How to account for known quantities in a cumulative distribution of dice rolls

63 Views Asked by At

So, a friend of mine wants me to write them a program to calculate certain probabilities for their tabletop RPG. The mechanic is essentially, a player has a pool of $10$-sided dice, which they roll, and any result $5$ or above is a success, any result less than $5$ is a failure, and there is a a set number of total successful rolls they need to succeed overall. This feels fairly straightforward, here's the function I'm using to calculate that: $$ \sum_{i=c}^{p}\binom{p}{i}5^i\cdot(10-5)^{(p-i)} $$ where $p$ is the number of dice, $c$ is the "challenge", the number of required successful rolls to succeed overall, $5$ is the number of ways a roll can suceed, and $(10-5)$ is the number of ways it can fail. However this is insufficient because there are also special rules and mechanics dependent on rolling either $10$ or $1$ that I need to account for. My solution so far is just to handle them manually, i.e. sum over (for $5$ dice):

1 1 1 1 1 ? ?  ?  ?  ?  10
1 1 1 1 ? ? ?  ?  ?  10 10
1 1 1 ? ? ? ?  ?  10 10 10
1 1 ? ? ? ? ?  10 10 10 10
1 ? ? ? ? ? 10 10 10 10 10

where ? is an unknown quantity which is now essentially an 8-sided die, which conveniently still carries the same probability. So, my question: I have both of these components, but I'm having a very difficult time wrapping my brain around how to modify the distribution function above to take into account the known quantity of $10$s and $1$s (which are successes and failures respectively). Does it modify the probability? Does it multiply the result by a constant to the power of $i$? Or something else? Thanks!

2

There are 2 best solutions below

1
On BEST ANSWER

"One-hot" representation

If you are starting from scratch, probably the easiest solution is to consider the die as a multivariate distribution where a single die produces either a 0 or 1 on each axis. In this case, you would have a 3-vector (botch, success, crit) with the following outcomes:

  • 10% botch: (1, 0, 0)
  • 40% failure: (0, 0, 0)
  • 40% success: (0, 1, 0)
  • 10% crit: (0, 0, 1)
    • Or (0, 1, 1) depending on whether you prefer to count it as a success at the outset or at the final evaluation.

Then you can find the total number of botches, successes, and crits by taking successive sum distributions of 1 + 1 dice, 2 + 1 dice, 3 + 1 dice, etc.

Multinomials

Another option is to use the multinomial distribution directly to get the number of botches, failures, successes, and crits. This is probably the most popular approach in practice, being used by Troll and AnyDice.

Binomial decomposition of multinomials

However, your original approach does have merit---it is possible to decompose the multinomial coefficient into a product of binomial coefficients. In fact, this leads to efficient dynamic programming algorithms for dice pools, though perhaps overkill for this particular problem. If you're curious, you can read my paper on the subject.

@inproceedings{liu2022icepool,
    title={Icepool: Efficient Computation of Dice Pool Probabilities},
    author={Albert Julius Liu},
    booktitle={18th AAAI Conference on Artificial Intelligence and Interactive Digital Entertainment},
    series={AIIDE},
    year={2022}
}

More to the point, this sounds like the mechanic used in Vampire: The Masquerade 5th Edition. You can try these approaches applied to V5 in your browser using this JupyterLite notebook, which uses my own Icepool Python library.

0
On

Okay, well... I don't fully know how to explain this, but here's what I worked out. So, with $$ f(p,c)= \sum_{i=c}^{p}\binom{p}{i}\cdot 4^i\cdot 4^{(p-i)} $$ as the function that calculates all successes for a dice pool of size $p$ above a required number of successes $c$, with $4$ instead of $5$ as handling all ones and tens seperately essentially turns the remaining unknown dice into 8-sided die, the overall function I arrived at was: $$ total(p,c)=\sum_{tens=0}^{p}\sum_{ones=0}^{p-tens}\binom{p}{tens}\cdot \binom{p-tens}{ones}\cdot f(p-tens-ones,clamp(c,tens)) $$ $$\text{where}$$ $$ clamp(c,tens)=\begin{cases} 0 & \text{if $c-tens<0$} \\ c-tens & \text{otherwise} \end{cases} $$ So, for each combination of tens, ones, and unknowns, $$ \sum_{tens=0}^{p}\sum_{ones=0}^{p-tens} $$ we take the amount of ways we could have arrived at a given amount of tens, times the amount of ways we could have arrived at a given amount of ones, $$ \binom{p}{tens}\cdot \binom{p-tens}{ones} $$ times the amount of ways the remaining dice ($pool-tens-ones$) can give us successful outcomes, accounting for the fact that each ten we know about counts as one of the required successful outcomes, therefore reducing the amount required. $$ f(pool-tens-ones,clamp(c,tens)) $$ and the function $clamp$ exists purely because I don't know how else to represent the fact that $c-tens$ can't go below zero mathematically. So... Yeah, I think this about does it. I'm hesitant to mark it as an answer, as I arrived here largely by trial-and-error, and I don't have a formal proof this is correct, I merely tested it by writing a separate program to brute-force through all the possibilities and ran it until it's exponential complexity outgrew my patience and/or the limits of a 64-bit float, which ended up being $p=9$.

(To calculate probabilities, $(total(p,c)\div 10^p)*100$)