I've never been very good at probability anyalisis, but I do enjoy a good game of Risk. I wanted to figure out the probabilities of the attacker losing no pieces, one piece, or two pieces under given rolls. I tried to work out how to do this using online tutorials, and quickly discovered that most web-based probability sources are aimed as continuing references for people who are already deep inside the field.

Anyway, there aren't that many combinations, so the problem is solvable using brute-force alone. Not my best code here, but it seems to be giving correct answers (or correct-looking answers, anyway :)

The output is divided into sections. The top of the section gives the number of attacker dice vs. the number of defender dice. In the following lines, the first column gives the defender's roll. The next three columns give the attacker's chance of losing none, losing one, or losing two (respectively) against that roll. The last line of the section gives the attacker's overall chance of losing none, losing one, or losing two.

I was interested to note that in the most common situation (3 attackers vs 2 defenders), the chances are almost even between the three possibilities, with the attacker being slightly favored to lose none. Also, the 1v1 roll slightly favors the defender.

#!/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 ); }

"There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.


In reply to Dice Roll Probabilities in Risk by hardburn

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.