[RPG] How to get the highest two die rolls from a mixed pool in AnyDice


Let's say the rulebook says this:

Roll one 4-sided die, two 6-sided dice, and one 10-sided die. Add the highest two rolls together.

In a different environment, I might write something like this:

int[] results = {1d4, 1d6, 1d6, 1d10}
return {results[1], results[2]}

How can I write that in AnyDice?

So far, this is the best I've come up with, but it doesn't do what I'm expecting:

X: [sort {1d4, 1d6, 1d6, 1d10}]
output 1@X + 2@X

Best Answer

As usual with AnyDice, the solution is "write a function." Here's a simple example:

function: highest N:n of A:s B:s C:s {
    result: {1..N}@[sort {A, B, C}]
output [highest 2 of 3d4 2d6 1d8]

Of course, this technique can be easily extended to more than three types of dice simply by adding more parameters to the function. The trick here is that passing a die into a function that expects a number or a sequence will "freeze" the die roll, invoking the function for every possible outcome of the roll in parallel, and summing up the results (weighted by their respective probabilities). Thus, inside the function, you can just manipulate the sequences of individual dice as you want.

Note that converting dice into sequences like this is a "brute force" solution, since it ends up invoking the function separately for every possible outcome of every roll. For large amounts of dice, it can run very slowly or even time out.

In particular, if you only want the single highest roll in the pool, the solution I presented in this earlier answer is a lot more efficient: by discarding all but the highest die of each type before calling the function, the number of combinations that AnyDice must iterate over becomes a lot smaller.