加权轮次
作者:Eric Hodges
规范
来自 http://www.perlmonks.org/?node_id=731443
这是一个策略游戏的一部分。战斗中有多艘船只,您必须确定它们采取行动的顺序。
每艘船都有一个主动性值。
在回合开始时,每艘船都会获得与其主动性值相等的票数。选票是随机抽取的。当一艘船的选票第一次被抽中时,它就会轮到它行动。它剩下的选票就作废了。
工作示例
3 艘船 <A B C>,主动性值为 (1,2,4)。
我们将选票放入一个数组中:<A B B C C C C>
我们随机抽取一张选票:C。轮到 C 行动了。
我们再抽一张选票:C。什么也不做。
我们再抽一张选票:C。什么也不做。
我们再抽一张选票:B。轮到 B 行动了。
我们再抽一张选票:B。什么也不做。
我们再抽一张选票:A。轮到 A 行动了。
我们抽取最后一张选票:C。什么也不做。
所以最终的顺序是:<C B A>
这不一定是执行该算法的最有效方式。
需要注意的有用事项
要生成一个从 1 到 N 的随机数,请使用
(1..N).pick要生成一个从 0 到 N-1 的随机数,请使用
(0..^N).pick
use v6;
our $SHIPS = 4;
our $REPS = 30;
my @weights = (1..16).pick($SHIPS, :replace);
for @weights.kv -> $k, $v { say "$k: $v" }
my $total = [+] @weights;
say "Total Weights $total";
sub pick(@weights, $total) {
my $rand = (0..^$total).pick;
for @weights.kv -> $i, $w {
$rand -= $w;
return $i if $rand < 0;
}
}
sub pickAll(@weights is copy, $total is copy) {
my @order;
for @weights {
my $pick = pick(@weights, $total);
@order.push($pick);
$total -= @weights[$pick];
@weights[$pick] = 0;
}
return @order;
}
say ~pickAll(@weights,$total) for 1 .. $REPS;
Perl 6 示例