The usual solution to "How do I count dice rolls in some special way in AnyDice?" is to:
- write a function that takes a sequence parameter (i.e. one with
:s
appended to the parameter name), and
- give your rolled dice pool as the parameter to that function.
AnyDice will then automatically call the function for each possible (sorted) combination rolled on the dice and collect whatever the function results into a custom die, weighted by the probability of rolling each of the combinations. Inside the function the value of the paramater will be just a fixed sequence, and so you can inspect and manipulate it any way you'd normally manipulate a sequence, including using if
conditions based on it.
Here's a quick example that should do what you want:
function: evaluate ROLL:s {
if [count 6 in ROLL] >= 2 {
result: ROLL + [explode d6]
} else {
result: ROLL
}
}
output [evaluate 3d6]
What was wrong with your code, then?
The main problem was that, in your code, you had if [select 2 from X] = 6
outside a function, where X
is a dice pool (specifically 3d6
), not a sequence.
The select INDICES from SEQUENCE
function (which looks familiar) is meant to return a sequence, but it can only do that if both parameters given to it are actual sequences (or numbers, which AnyDice will happily convert into single-element sequences). As I noted in the answer linked above:
If [either parameter is] a pool of dice, the function will still technically work, but the results will get automatically summed back into a number before being collected into a die[.]
So, in your code, since X
is a die (or, rather, a pool of dice — AnyDice terminology is sometimes a bit confusing here), [select 2 from X]
will also be a die. And thus [select 2 from X] = 6
will also be a die — specifically, a die that rolls 1 if the second-highest roll in 3d6 is a 6, and 0 otherwise. And you can't pass a die to if
in AnyDice.
So how could you have fixed your code, then?
The simplest way (in the sense of making the fewest changes to your code) would've been to just wrap the if
statement in a function that takes X
as a sequence parameter, like this:
function: select INDICES:s from SEQUENCE:s {
RESULT: {}
loop INDEX over INDICES {
RESULT: {RESULT, INDEX@SEQUENCE}
}
result: RESULT
}
function: evaluate X:s {
if [select 2 from X] = 6 {
result: X + [explode d6]
} else {
result: X
}
}
output [evaluate 3d6]
(I also fixed a small bug in your code where you had [explode 6]
instead of [explode d6]
. With that change, this code gives the exact same output as my first example program above.)
Ps. There actually is a way to kind of make AnyDice support if
conditions based on dice, using a helper function like this:
function: if CONDITION:n then A else B {
if CONDITION { result: A } else { result: B }
}
However, if you try to rewrite your code using this trick, something like this:
output [if [select 2 from X] = 6 then X + [explode d6] else X]
or even like this:
output X + [if [select 2 from X] = 6 then [explode d6] else 0]
you'll find that these programs give subtly incorrect results: the average will in fact be correct, but the standard deviation and the shape of the distribution graph will be subtly off:

Experienced AnyDice users will, of course, quickly realize what the problem is: in the expressions above, each X
represents a separate independent 3d6 roll. So the actual dice rolling mechanic that ends up being modelled here isn't "roll 3d6, then add an exploding d6 if you rolled at least two sixes", but rather "roll 3d6, then roll 3d6 again and add an exploding d6 if you rolled at least two sixes on the first 3d6 roll".
Of course, wrapping the code above inside a function, so that X
becomes a sequence instead of a die, does make it work as intended:
function: evaluate X:s {
result: [if [select 2 from X] = 6 then X + [explode d6] else X]
}
output [evaluate 3d6]
Basically, any time you want to implement a mechanic in AnyDice where you roll some dice and use the result of the roll more than once, you do need to write a function and pass the roll into it as a sequence parameter. That's the only way in AnyDice to "freeze" the result of a dice roll into a fixed sequence (or number).