Is there a way to calculate/simulate rolling 3d20 and spit the middle one (that is easily done with middle function), or if its value is the same as the high or the low one, spit that one too?

Here it is in more detail: I want to use 3d20 and always take the middle value. If two values are the same that is a critical result. Then if the third value is higher than the equal values it is a negative critical and if the third value is lower than the equal values it is a positive critical.

Here are a few samples, I'm not sure how it could return the criticals, but one idea is the following:

  • 1, 10, 20 returns 10.
  • 1, 10, 10 (a high critical) could return 20+10.
  • 5, 5, 10 (a low critical) could return 0-5.
  • \$\begingroup\$ I wanted to calculate the odds of a critical where the critical is defined as the same value appearing 2 times. If the third value is smaller it is a high crit, and of the third value is larger it is a low crit. I'm not sure that is possible to calculate without many functions... :/ \$\endgroup\$ Commented Oct 15, 2020 at 21:01
  • 2
    \$\begingroup\$ What's the result if all 3 dice tie? \$\endgroup\$
    – Carcer
    Commented Oct 15, 2020 at 21:13

3 Answers 3


Anydice is unfortunately a bit tricky in that it only allows us to return a single number from a function, so we have to use these workarounds if you want to get more information out of a single roll. But that's entirely doable, in this case, since the introspection you want to do isn't very complicated.

Here's a program which implements your mechanic:

function: critical POOL:s {
  if 1@POOL = 3@POOL { result: 2@POOL }
  if 1@POOL = 2@POOL { result: 20 + 2@POOL }
  if 2@POOL = 3@POOL { result: 2@POOL - 20 }
  result: 2@POOL

output [critical 3d20]

We invoke the function critical with a 3d20 roll, which is cast to a sequence in descending order. Stepping through the function:

  1. If the highest die and the lowest die are equal, we must have a triple, which I assume cancels out and we just take the value of the middle die.
  2. If the highest die equals the middle die, we have a positive critical and we add 20 to the result to indicate that.
  3. If the middle die equals the lowest die, we have a negative critical and we subtract 20 from the result to indicate that.
  4. Otherwise, we just take the value of the middle die.

The resulting output shows the probability curve you'd expect for taking the middle die of a 3d20 roll, but with a couple of wings either side that represent the critical rolls. Note that there is zero probability of getting a result of 0 or 21, because it's impossible to get a negative crit if the middle die is a 20 and impossible to get a positive crit if the middle die was a 1.

Anydice graph of expected results.

  • \$\begingroup\$ Thanks, that is what I was looking for! \$\endgroup\$ Commented Oct 15, 2020 at 21:51


output 2@3d20

should provide the second result from the top. If two (or all three) results are equal, that also 'spits out' that same result.


Just answering: How to make Anydice see if two values are the same among 3 dice and keep them?

Because the explanation after that makes no sense to me.

This outputs the middle number if it matches either the highest or the lowest of 3 dice and 0 if it doesn’t.

function: matches DICE:s {
  result: (1@DICE=2@DICE)*2@DICE + (1@DICE!=2@DICE)*(2@DICE=3@DICE)*2@DICE 

output [matches 3d20]
  • \$\begingroup\$ That is actually quite close to what I had in mind... \$\endgroup\$ Commented Oct 15, 2020 at 21:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .