in reply to Re^3: Rolling For Initiative
in thread Rolling For Initiative
#! perl -slw use strict; use List::Util qw[ sum ]; our $SHIPS ||= 10; our $REPS ||= 1e5; sub pick { my( $weights, $total ) = @_; my $rand = rand $total; ( $rand -= $weights->[ $_ ] ) < 0 and return $_ for 0 .. $#$weights; } sub pickAll{ my @weights = @_; my $total = sum @weights; my @order; for( 0 .. $#_ ) { my $pick = pick( \@weights, $total ); push @order, $pick; $total -= $weights[ $pick ]; $weights[ $pick ] = 0; } return @order; } my @weights = map rand( 16 ), 1 .. $SHIPS; my $total = sum @weights; $weights[$_] /= $total for 0 .. $SHIPS-1; print "$_ : $weights[ $_ ]" for 0 .. $#weights; print "\n"; my @results; for (1 .. $SHIPS) { push @results, [0 x $SHIPS]; # $results[ship][pick location] } for (1 .. $REPS) { my @realization = pickAll( @weights ); for (0 .. $SHIPS-1) { ++$results[$realization[$_]][$_]; } } for (@results) { for (@{$_}) { $_ /= $REPS; } } print sprintf "%.4f " x $SHIPS, @{$_} for @results; C:\test>WeightedPick.pl -SHIPS=10 -REPS=100000 0 : 0.156588763610903 1 : 0.0946606629807576 2 : 0.0327748134913928 3 : 0.100654289094377 4 : 0.162546174460996 5 : 0.135885704628311 6 : 0.135469229097757 7 : 0.0780801081629204 8 : 0.0401747990052874 9 : 0.0631654554672976 0.1574 0.1495 0.1394 0.1308 0.1174 0.1041 0.0857 0.0629 0.0386 0.0143 0.0938 0.0970 0.1014 0.1043 0.1110 0.1138 0.1147 0.1123 0.0974 0.0543 0.0330 0.0373 0.0398 0.0467 0.0533 0.0651 0.0830 0.1115 0.1781 0.3523 0.0993 0.1032 0.1067 0.1089 0.1115 0.1134 0.1129 0.1085 0.0882 0.0474 0.1632 0.1523 0.1434 0.1296 0.1176 0.1005 0.0845 0.0602 0.0359 0.0129 0.1350 0.1332 0.1295 0.1261 0.1177 0.1107 0.0981 0.0784 0.0507 0.0205 0.1364 0.1330 0.1297 0.1257 0.1176 0.1098 0.0952 0.0792 0.0517 0.0216 0.0782 0.0822 0.0864 0.0927 0.1012 0.1078 0.1191 0.1279 0.1230 0.0815 0.0408 0.0451 0.0507 0.0552 0.0635 0.0740 0.0922 0.1232 0.1863 0.2690 0.0629 0.0672 0.0732 0.0800 0.0892 0.1007 0.1147 0.1360 0.1500 0.1262
|
|---|