The Star Wars Risk Dice Calculator Program
==========================================
Copyright Stuff

Copyright Richard Hamilton 2013
You may use this program for any purpose and change it in any way you like. You may not, however, explicitly claim it as your own work.
This program is (theoretically) available on my website at swrd/infiniplix.ca. The roll ditribution tables are also available there.
Risk is copyright 2006 Hasbro, Pawtucket, RI 02862. I don't know what the part after Hasbro means either.
The game is copyright Lucasfilm Ltd. in 2006. Also presumably Star Wars itself, but it doesn't seem to say that anywhere on the box.
Star Wars Risk Battles

The purpose of this program is to calculate the probabilities of different battle outcomes in the game "Risk: The Game of Galactic Domination  Star Wars: Original Trilogy Edition". As that is rather a lot to say, it is commonly called "Star Wars Risk".
Battles in Risk (and thus in Star Wars Risk) take place between two teams of armies (i.e. units). You can have as many armies as you want at once, but you can only use a few at a time. The rest are used as reinforcements.
All battles are between two teams:
1. The defender, who currently occupies the planet (i.e. territory in normal Risk)
2. The attacket, who wants to capture the planet
The defender may use at most 2 units to defend with. The attacker may use at most 3 units. It is almost always best to use as many units as possible, although there are a few rare cases when the attacker may want to use fewer. Therefore, the permitted battle combinations are:
> 1 attacker vs. 1 defender
> 2 attackers vs. 1 defender
> 3 attackers vs. 1 defender
> 1 attacker vs. 2 defenders
> 2 attackers vs. 2 defenders
> 3 attackers vs. 2 defenders
In a battle, each player rolls one dice for each unit in the battle and sorts them from largest to smallest. The largest dice are them compared. If the attacker rolled higher than the defender, the defender loses 1 unit. Otherwise, if the attacker rolled lower than or equal to the defender, the attacker loses one unit. If both the attacker and the defender rolled 2 more or dice, the secondhighest for each team are compared similarly.
One of the things that makes Star Wars Risk different from basic Risk is that, in addition to units, teams may also have spaceships in the battle. The spaceships do not fight; they modify dice rolls. There are 3 types of ships:
1. fighters
2. bombers
3. capital ships (this seems to be a catchall term that includes all major ships, such as destroyers, battleships, notexactlyaircraft carriers, etc.)
For each fighter, you may reroll one die that shows a 1. You also rerolling it until it shows something else (even if it takes all day). If you have 2 fighters, you can also reroll a second die that shows a 1. However, this does not happen often (1/36 ~= 3% with 2 units, 15/216 ~= 7% with 3), so it is probably a bad investment. The 3rd fighter is useful only if you roll three 1s (a 1/216 chance with 3 units), and so is definately not worth having.
For each bomber, you add 1 to one of your rolls. The first bomber increases your highest roll. The second bomber increases your second highest roll. The third bomber increases your thirdhighest roll. However, as that roll is not used in combat, it is generally a waste (you would use it while attacking the Death Star, but that is beyond the scope of this program).
For each capital ship , you replace 1 6sided die with and 8sided die. This allows you to roll higher numbers. This means that, if you are attacking with three untis, a third capital ship is actually useful.
If you have more of a single type of spaceship that you have units, the extras are just wasted. If you have ships of multiple types, apply all the benefits.
Special Cases:
> If you have a fighter and a bomber and roll a 1, the +1 from the bomber should be applied after you reroll the die. You do not lose your reroll just because the die got increased to an effective 2.
> If you have a fighter and a cpital ship and roll a 1 on an 8sided die, it is still an 8sided die when you reroll it.
> If you have a fighter and a capital ship and roll 2 1s, one of which is on an 6sided die and one of which is on an 8sided die, always reroll the 8sided die. This will give a higher average result.
Program Goal

This program calculates the mathematical probabilities of different battle outcomes for any given number of units and spaceships on each team.
There are two main outputs:
1. Roll frequency tables for 1, 2, and 3 dice
2. Probabilitites for each teams losses for 1, 2, and 3 attackers and 1 or 2 defenders
Coding Conventions

I use 4 naming conventions for identifies based on their usage:
Symbol  Meaning
+
lowercase_with_underscores  variable
UPEERCASE_WITH_UNDERSCORES  constant, #include guards
lowerCamelCase  function
UpperCamelCase  scope (struct, class, namespace)

Files are named in UpperCamelCase.
I use a system of variable name prefixes inspired by (but not actually based on) Hungarian Notation for my programs. All indicators are collected together on the front of the variable name and followed by an underscore. Two indicators that appears in this program (that I noticed):
Symbol  Meaning  Notes
++
m  member variable 
a  1D array  add another 'a' for each dimension
 
Tabs have size 8. Ideally tabs would not be used at all, but they are much nicer to work with than spaces.
Documentation is limited to 64 characters (I find 80 characters to wide to read confortably). However, the code usually goes as far right as needed. I have a wide screen and find code easier to read without line breaks.
Algorithm

PART A: Calculate the dice roll distributions
Every possible dice roll combination for a single team is considered and combined into frequency arrays. The array has one dimension for each die and the rolls are used as indexes. For example, rolling 4 and 2 with 2 dice would increase the value at position [4][2] of a 2D array. The indexes are sorted in descending order, so rolling 2 and 4 would also increase the same position.
If a die must be rerolled because of a fighter, the probability is divided up evenly among the values it can be rerolled as. For a 6sided die, this means that each non1 value gets an extra 1/5 of a roll. For an 8sided die, the extra is 1/7.
However, the probabilities are stored as integers, so fractions cannot be represented. To solve this, we begin by assigning each roll a larger weight so that their is room to reduce it as needed. For example, if an 8sided die and 2 6sided dice are rolled, the origial weight is 5 * 5 * 7 = 175. That way, even if all dice are rerolled, the final rolls still have a weight of (excactly) 1.
The frequencies end up in big Ndimensional arrays representing complicated ratio. We then divide each table by its greatest common factor (GCF) to put the ratio into simplest terms.
We print out the reduced tables as the dice distributions.
PART B: Calculate losses probabilities