Probability of more "hits" comparing the result of two uneven dice pools

64 Views Asked by At

I'm designing a board game and trying to evaluate roll probabilities, but I'm in over my head. What I'm looking to determine is:

I roll two different sized pools of six-sided dice, sort them high-to-low, compare the highest vs. highest of each, 2nd highest vs. the 2nd highest of each, and so on. The pool scores a "hit" for each that is greater. If one pool has more dice, each extra die "hits."

Th probability I would love is f(x,y,n) where:

  1. x is always >= y
  2. x is the number of dice in one pool
  3. y is the number of dice in the other hits
  4. The function yields the probability that x scores n hits more than y (negative numbers meaning y scored more hits than x.)

But just f(x,y) where x is always >=y resulting in "probability that pool of x dice has more hits than pool of y dice" would also be helpful if it's easier.

I'm also trying to evaluate an alternative where extra dice don't "hit", more dice just means you have a better chance of hitting against however many dice y does have, but I figure I know enough about probability to modify the formula for that given the above?

Some help would be so appreciated!

1

There are 1 best solutions below

0
On

It's possible to compute the solution without an exponential-time enumeration of all possible dice rolls. We can do this by iterating through the numbers on the dice (i.e. 6, 5, 4, 3, 2, and 1), and computing the distribution of how many dice in each pool rolled that number. Then we can put a state transition function on top of that based on the rules of the game. Here's a fuller (though unfortunately still crude) explanation of the algorithm.

I implemented this approach as part of my hdroller Python library. Here's a JupyterLite notebook that calculates these RISK-like probabilities. An excerpt:

class EvalRiskDiff(hdroller.EvalPool):
    def next_state(self, state, outcome, a, b):
        if state is None:
            net_score, advantage = 0, 0
        else:
            net_score, advantage = state
        # Advantage is the number of unpaired dice that rolled a previous (higher) number.
        # If positive, it favors side A, otherwise it favors side B.
        # We pair them off with newly-rolled dice of the disadvantaged side.
        if advantage > 0:
            net_score += min(b, advantage)
        elif advantage < 0:
            net_score -= min(a, -advantage)
        advantage += a - b
        return net_score, advantage
    
    def final_outcome(self, final_state, *_):
        # Take only the score.
        return final_state[0]
    
    def direction(self, *_):
        # See outcomes in descending order.
        return -1

Probably a more bespoke algorithm can compute the result even faster, but this can easily handle a dozen dice on each side.

I'm also trying to evaluate an alternative where extra dice don't "hit", more dice just means you have a better chance of hitting against however many dice y does have

I recommend not having extra dice "hit". Even a single extra die is already a pretty big advantage without this additional bonus. Indeed, the most common case in RISK itself of 3 attackers versus 2 defenders does not give the attacker a free hit. In addition to this, the defender is given a hit on ties. Even with these factors favoring the defender, the attacker still has a slight advantage overall due to their extra die.