# Anydice: Counting Successes on dice and rerolling any (+ bonus dice) below the target of 6 on d6's

I'm trying to model the roll and reroll probabilities of skill checks in Coriolis RPG.

Here the skill rolls use a pool of d6, and you count how many 6 you rolled. You can optionally reroll any dice that were not 6s the first time you rolled. Sometimes you can add bonus d6 dice to the reroll pool.

I've been trying to model this in AnyDice, but I'm struggling to make it work! Especially around the reroll that need to be the number of dice less as many 6's from the initial roll.

N:5
output [count {6} in N d6]


then for the reroll element i tried this

N:5
output [count {6} in N d6] + [count {6} in (N - [count {6} in N d6]) d6]


But for sure that's not working, as the output from this alone a count up to 1

[count {6} in (N - [count {6} in N d6]) d6]


Any help greatly appreciated!

• Welcome to RPG.SE! Take the tour if you haven't already and see the help center or ask us here in the comments (use @ to ping someone) if you need more guidance. Good Luck and Happy Gaming! Sep 11, 2022 at 18:28

I'm going to give you two different approaches, because they highlight two different and very powerful techniques in AnyDice.

## Treating it like a dice pool

In order to work with dice pools, especially when caring about more than one property of the rolled dice (as a collective) or caring about it more than once, we need to cast it to a sequence. To do so, we make a function which takes our roll as a sequence. We can apply logic as if working with a single roll, and at runtime AnyDice will iterate over every possible roll and spit out the distribution.

function: count T:n in A:s with reroll {
result: [count T in A] + [count T in (#A-[count T in A])d6]
}
output [count 6 in Nd6 with reroll]


## Treating it as independent dice

Now, in mathematical terms the dice aren't really a pool. Each dice is rerolled independently of the results on other dice. Dependance would be if you could roll a die if a different die rolled a 5, or some other such rule.

We can then construct a die which encapsulates a d6, but rerolling non 6s (once). In concept, we want a die which has one side which has a 6, and 5 which are a d6 roll. Now due to how AnyDice converts dice to sequences and sequences back into dice this is slightly trickier (in short, it doesn't handle fractional faces). The construction actually looks like:

d{1d6:5, 6:6}


Which is in essence a 36 sided dice which has the same net distribution as d6 rerolled once on non-6. Conceptually, if you split its faces in 6 sets, one is all sixes, and five of them has the 1-6 series of a normal d6 roll.

You can then just ask AnyDice to count the number of 6s in a roll of N such dice.

output [count 6 in Nd{1d6:5, 6:6}]


These two methods give the same results. The former might be easier to generalize, especially if you have more complex pool/rerolling rules, but the latter will perform better (which can matter for large pools).

• Tip: With the "independent" dice method you can still let AnyDice reroll one die for you and save the result as a custom die that you can roll N times. And if you want to optimize it even further for uses like this, where you really only have two outcomes (success and failure) and you can reroll failures once, you can first let AnyDice give you a custom die with just those two sides and then reroll it (and then roll the rerolled success die N times). Sep 11, 2022 at 18:43
• Ahh, the 1d6 inside the dice span generates the full 1-6 range, it doesn't roll once. That explains why my "solution" didn't give sane output. Nice!
– From
Sep 11, 2022 at 19:45
• Thanks! I updated the function to deal with the bonus dice, my only issue now is it can't calculare over above N=7 as it takes >5 sec to calculate! B:1 N:7 function: count T:n in A:s with reroll { result: [count T in A] + [count T in (#A-[count T in A] + B)d6] } output [count 6 in Nd6 with reroll]  How can I edit the 2nd approach to deal with bonus 1, 2 or 3 bonus dice (extra D6 added to the pool of dice being rerolled that were not already a 6)?
– Andy
Sep 11, 2022 at 20:53
• @Andy Unless there's some complexity I'm missing, bonus dice could just be treated as an additional d6 which isn't rerolled so you can handle them as: output [count 6 in Nd{1d6:5, 6:6}]+[count 6 in Bd6] Sep 11, 2022 at 20:58
• @From: Yes, 1d6:5 here is equivalent to {1..6}:5, i.e. the numbers from 1 to 6 repeated 5 times. Also, 2d6 inside a sequence definition is equivalent to {2..12}, which may not be what you expect. Alas, AnyDice doesn't actually let you put dice inside sequences, and its behavior if you try is kind of counterintuitive and rarely useful. Except maybe for just this particular case, although I'd still argue that Nd{{1..6}:5, 6:6} is a clearer way to write the same thing. Sep 12, 2022 at 15:35

### Paradox: Math is simpler than Anydice!

This application is another, beautiful use case of the Binomial distribution: you actually do not need anydice.

The probability of getting $$\t\$$ successes in a Nd6 roll is given by $$P(t,N)= \sum_{i=0}^t \mathcal{B}(N,i,1/6)\cdot\mathcal{B}(N-i,t-i,1/6)$$

where $$\\mathcal{B}(N,t,s)\$$ is the Binomial distribution of parameters $$\N,s\$$. The mathematical explanation is given further in the text.

### To infinity and beyond!

Someone_Evil's anydice program works fine, but the problem with anydice programs is that it can not run them for a large value for $$\N\$$: in this case just for a 7d6 roll the site stop working. Instead, using direct formulas you can simulate rolls with an high amount of dice, in the case you are interested into the distribution analysis, or in the case you can add bonus dice to the reroll. The figure below refers to a roll 100d6. ### Mathematical explanation

Given $$\N\$$ independent trials with the same change of success $$\s\$$, the probability to get $$\t\$$ success is given by $$\mathcal{B}(N,t,s) = \begin{pmatrix}N\\t\end{pmatrix}s^t(1-s)^{N-t}$$ where $$\\begin{pmatrix}N\\t\end{pmatrix}\$$ is the binomial coefficient.

Let's compute the probability $$\P(2,6)\$$ of getting exactly two 6s on a 5d6 roll under the proposed rules: this is given by $$P(2,5)= P(0,5)\cdot P(2,5) + P(1,5)\cdot P(1,4) + P(2,5)\cdot P(0,3)$$ where

• the first term computes the probability of getting zero 6s on the first roll and two 6s on re-rolling all the dice,
• the second term computes the probability of getting just one 6 on the first roll and another one in the re-rolling of the remaining 5 dice,
• the last term accounts for getting two 6s on the first roll and none on re-rolling the remaining 4 dice.

Each probability above can be computed by the Binomial distribution: hence $$P(2,5)= \mathcal{B}(5,0,1/6)\cdot\mathcal{B}(5,2,1/6) + \mathcal{B}(4,1,1/6)\cdot(3,1,1/6)+\mathcal{B}(5,2,1/6)\cdot\mathcal{B}(3,0,1/6)$$ or, more compactely, $$P(2,5)= \sum_{i=0}^2 \mathcal{B}(5,i,1/6)\cdot\mathcal{B}(5-i,2-i,1/6)$$ and $$\P(2,5)=0.35531228235766055 \sim 35.53\%\$$, accordingly to SomeoneEvil's answer.

It can be easily generalized to the case of getting $$\t\$$ success in a Nd6 roll: $$P(t,N)= \sum_{i=0}^t \mathcal{B}(N,i,1/6)\cdot\mathcal{B}(N-i,t-i,1/6)$$ The following python code produces the results for $$\N=5, t\in\{0,1,2,3,4,5\}\$$:

from scipy.stats import binom
# Number for dice
n = 5
# Probability of success
p = 1/6

print("Succ\tProbability")
for i in range(n + 1):
P = 0;
for j in range(i+1):
P = P + binom.pmf(j, n, p)*binom.pmf(i-j, n-j, p)
print(str(i) + "\t" + str(P))

• AnyDice can compute large binomial distributions just fine, though; you just have to be slightly smart about how to write the code so that it doesn't waste time enumerating too many equivalent rolls. :) Sep 12, 2022 at 15:42
• @IlmariKaronen Yep, I recognize that Anydice is quite powerful, but SE's program halts for small N: one has to have a strong anydice-fu as you to overcome problems like these. I am aware that I usually answer to questions about Anydice with pure mathematical solutions, because I find that even if Anydice is very powerful it makes one lose the deeper insight that a math analysis can provide.. Sep 12, 2022 at 16:55