#!/usr/bin/perl use strict; use warnings; # # Everything here is very brute-force and hackish # sub probability_to_beat { my @defender_roll = sort { $b <=> $a } @{ +shift }; my @attackers = @_; my $lose_none = 0; my $lose_one = 0; my $lose_two = 0; foreach my $attacker_roll (@attackers) { my @attacker_roll = sort { $b <=> $a } @$attacker_roll; if(defined($defender_roll[1]) && defined($attacker_roll[1])) { if( ($defender_roll[0] >= $attacker_roll[0]) && ($defender_roll[1] >= $attacker_roll[1]) ) { $lose_two++ } elsif( ( ($defender_roll[0] >= $attacker_roll[0]) && ($defender_roll[1] < $attacker_roll[1]) ) || ( ($defender_roll[0] < $attacker_roll[0]) && ($defender_roll[1] >= $attacker_roll[1]) ) ) { $lose_one++; } else { $lose_none++; } } else { if($defender_roll[0] >= $attacker_roll[0]) { $lose_one++; } else { $lose_none++; } } } return ( $lose_none, $lose_one, $lose_two, ); } sub one_die { return [map {[ $_ ]} 1 .. 6]; } sub two_die { return [map { my $first = $_; map {[ $first, $_ ]} 1 .. 6 } 1 .. 6]; } sub three_die { return [map { my $first = $_; map { my $second = $_; map {[ $first, $second, $_ ]} 1 .. 6 } 1 .. 6 } 1.. 6]; } sub run { my @attackers = @{ +shift }; my @defenders = @{ +shift }; my $num_attackers = scalar @{ $attackers[0] }; my $num_defenders = scalar @{ $defenders[0] }; my $total_lose_none = 0; my $total_lose_one = 0; my $total_lose_two = 0; foreach my $defender_roll (@defenders) { my ($lose_none, $lose_one, $lose_two) = probability_to_beat( $defender_roll, @attackers ); my $total = $lose_none + $lose_one + $lose_two; print join( ', ' => @$defender_roll) . "\t" . sprintf("%2.2f%%, %2.2f%%, %2.2f%%", ($lose_none / $total) * 100, ($lose_one / $total) * 100, ($lose_two / $total) * 100, ) . "\n"; $total_lose_none += $lose_none; $total_lose_one += $lose_one; $total_lose_two += $lose_two; } my $total = $total_lose_none + $total_lose_one + $total_lose_two; print "Totals:\t" . sprintf("%2.2f%%, %2.2f%%, %2.2f%%", ($total_lose_none / $total) * 100, ($total_lose_one / $total) * 100, ($total_lose_two / $total) * 100, ) . "\n"; } { print "3 v 2\n"; run( three_die, two_die ); print "\n3 v 1\n"; run( three_die, one_die ); print "\n2 v 2\n"; run( two_die, two_die ); print "\n2 v 1\n"; run( two_die, one_die ); print "\n1 v 2\n"; run( one_die, two_die ); print "\n1 v 1\n"; run( one_die, one_die ); }