Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- # Chainmail post melee morale probabilities for 6 LF vs 6 LF
- sub nFactorial { # Factorial n!
- my $n=shift;
- my $product = 1;
- while($n>0) {
- $product *= $n--;
- }
- $product;
- }
- sub nCr { # Combinations of n out of r
- my ($n,$r) = @_;
- int nFactorial($n) / int nFactorial($r) * int nFactorial($n-$r);
- }
- # Probability of 6 LF scoring n kills against 6 LF, n in 0..6
- sub prob {
- my ($n) = @_;
- nCr(6,$n) * (1/6)**$n * (5/6)**(6-$n);
- }
- foreach $lA (1..6) {
- foreach $lB (1..6) {
- foreach $m (1..6) { # Morale die
- # Step 1: Compute fewer casualties
- $dA = 6 - $lA; # A's casualties
- $dB = 6 - $lB; # B's casualties
- $p = (prob($dA) * prob($dB))/6; # Probability of this outcome
- if( $dA < $dB ) {
- $r1A = $m * ($dB - $dA);
- $r1B = 0;
- } elsif( $dB < $dA ) {
- $r1B = $m * ($dA - $dB);
- $r1A = 0;
- } else { # $dA == $dB
- $r1A = 0;
- $r1B = 0;
- }
- # Step 2: Compute greater survivors
- if( $lA > $lB ) {
- $r2A = $lA - $lB;
- $r2B = 0;
- } elsif( $lB > $lA ) {
- $r2B = $lB - $lA;
- $r2A = 0;
- } else { # $lA == $lB
- $r2A = 0;
- $r2B = 0;
- }
- # Step 3: Surviving figures
- $r3A = 4*$lA;
- $r3B = 4*$lB;
- # Step 4: Morale scores
- $sA = $r1A + $r2A + $r3A;
- $sB = $r1B + $r2B + $r3B;
- # Difference
- $d = abs($sA - $sB);
- # Double difference because no. figures per side < 20
- $d *= 2;
- $prob{$d} += $p;
- }
- }
- }
- foreach $d (sort {$a <=> $b} (keys %prob)) {
- #print $d, " ", $prob{$d}, "\n";
- if( $d >= 0 && $d <= 19 ) {
- $meleecontinues += $prob{$d};
- } elsif($d >= 20 && $d <= 39) {
- $backhalfgoodorder += $prob{$d};
- } elsif($d >= 40 && $d <= 59) {
- $backonegoodorder += $prob{$d};
- } elsif($d >= 60 && $d <= 79) {
- $retreatonemove += $prob{$d};
- } elsif($d >= 80 && $d <= 99) {
- $routoneandhalfmove += $prob{$d};
- } else { # $d >= 100
- $surrender += $prob{$d};
- }
- $total += $prob{$d};
- }
- # 13 special cases where we do not need to check post melee morale
- # Probability A wipes out B
- for $dA (0..5) { $p0Bs += prob($dA) * prob(6); }
- # Probability B wipes out A
- for $dB (0..5) { $p0As += prob($dB) * prob(6); }
- # Probability A & B wipe out each other
- $p0 = prob(6) * prob(6);
- # Add these special cases to the total probability mass
- $total += $p0 + $p0As + $p0Bs;
- print "Outcome: Probability\n";
- print "=======================================================\n";
- print "A and B wipe out each other: ", $p0, "\n";
- print "A wipes out B: ", $p0Bs, "\n";
- print "B wipes out A: ", $p0As, "\n";
- print "Melee continues (0-19): ", $meleecontinues, "\n";
- print "Back 1/2 move, good order (20-39): ", $backhalfgoodorder, "\n";
- print "Back 1 move, good order (40-59): ", $backonegoodorder, "\n";
- print "Retreat 1 move (60-79): ", $retreatonemove, "\n";
- print "Rout 1 1/2 move (80-99): ", $routoneandhalfmove, "\n";
- print "Surrender (100+): ", $surrender, "\n";
- print "Total: ", $total, "\n";
Advertisement
Add Comment
Please, Sign In to add comment