5
\$\begingroup\$

So after fumbling around in AnyDice for awhile, I’m struggling to find a solution. Here’s what I’m looking for:

  • What are the chances of rolling a specific number that matches a specific sequence in order in multiple dice?
  • For example, in Xd6, I’m trying to figure out what that chances of rolling a 5+, THEN a 4+ in the remaining dice (as long as I get a 5+ first), then a 3+ in the remaining dice (as long as I get the 5+ and 4+ previously).
  • Bonus cookies and many thanks to you if your function allows me to easily change the numbers I’m looking for (like if I’m trying to find a 4+, 2+,5+ in that order)

Basically, a player rolls Xd6 at the same time and tries to match their different specific number sets, like

  • 3+, 3+, 2+
  • exactly 1, 2, 3
  • 4+, 2, 6

For example, a player has 5d6 is trying to roll a 5 or higher, than a 4 or higher, than a 3 or higher. They first have to roll a 5, and then a 4 and then the 3. The 4 and 3 results don’t matter unless they rolled a 5 or higher first.

It’s very similar to Yahtzee (except one roll) with different number goals.

\$\endgroup\$
  • \$\begingroup\$ @Shemulator Does your answer have to be in AnyDice specifically, or will you accept any calculation of the probability? \$\endgroup\$ – BBeast Dec 5 '20 at 1:50
7
\$\begingroup\$

If I understand your question correctly, the mechanic you want to model is one where the player:

  1. has (or is given) a list of \$M\$ target numbers;
  2. rolls \$N \ge M\$ dice, all at once; and
  3. tries to match any \$M\$ of the rolled dice to the target list, so that each chosen die roll meets or exceeds the corresponding target number.

So, for example, if my target list was (5, 4, 3, 3) and I rolled (1, 3, 4, 5, 6) on 5d6, I could pick e.g. (6, 5, 4, 3) as my matching rolls and succeed, since each of the matching rolls meets or exceeds the corresponding target number.

If so, this AnyDice function should do what you want:

function: ROLL:s includes at least SEQ:s {
  loop I over {1..#SEQ} {
    if I@ROLL < I@SEQ { result: 0 }
  }
  result: 1
}

output [5d6 includes at least {5,4,3,3}]
  named "chance of finding 5+, 4+ and two 3+ rolls in 5d6"

Note that this function expects both of its input sequences to be sorted in descending order. This is how AnyDice sorts the results of dice rolls by default, so the first parameter should be fine, but sorting the second parameter (i.e. the sequence of minimum rolls to be found) is up to the user. If you give the function a sequence that is not correctly sorted, it will still run and produce more or less valid-looking results, but they will probably not be what you really expect to get. You have been warned!

(To make the code a bit more foolproof at the expense of performance, we could add the line SEQ: [sort SEQ] at the beginning of the function to automatically sort the input sequence.)

The reason it works is based on the observation that the player may always match their highest roll to the highest target number, their second-highest roll to the second-highest target number, and so on. If this will not result in a successful match, then neither will any other possible order of the rolled dice!

To convince yourself that this is the case, consider what happens if the player attempts this and finds that their \$K\$-th highest die does not meet the \$K\$-th highest target number. Clearly, none of the lower rolls can then meet that target number either — and, while one of the higher rolls could meet it, if the player chose to match their \$J\$-th highest roll (where \$J < K\$) with the \$K\$-th highest target, they'd then have to match the \$J\$-th highest target with one of the lower rolls, which will also fail.

Thus, all that the AnyDice code needs to do is to compare the sequence of rolled dice (sorted in descending order) with the target sequence (sorted the same way) and check that each roll meets or exceeds its corresponding target number. If any fail to do so, the function returns 0; otherwise it returns 1.


Ps. It's also possible to extend this function so that you can require some matches to be exact. The trick here is that we can first look for the exact matches and set aside any dice needed to satisfy those, and then check if the remaining dice can meet or exceed all of the "at least" targets.

For the first part, it would be convenient if AnyDice had a function for removing the elements of one sequence from another and returning the rest. Unfortunately it doesn't come with such a function built in, but we can write one:

function: remove SUBSEQ:s from SEQ:s {
  REST: {}
  J: 1
  loop I over {1..#SEQ} {
    if J <= #SUBSEQ & I@SEQ = J@SUBSEQ { J: J + 1 }
    else { REST: {REST, I@SEQ} }
  }
  result: REST
}

function: ROLL:s includes EXACT:s and at least TARGET:s {
  REST: [remove EXACT from ROLL]
  if #REST != #ROLL - #EXACT | #REST < #TARGET { result: 0 }
  loop I over {1..#TARGET} {
    if I@REST < I@TARGET { result: 0 }
  }
  result: 1
}

output [4d6 includes {} and at least {3,3,2}]
  named "chance of finding 3+, 3+, 2+ in 4d6"
output [4d6 includes {3,2,1} and at least {}]
  named "chance of finding 3, 2, 1 in 4d6"
output [4d6 includes {6,2} and at least {4}]
  named "chance of finding 6, 4+, 2 in 4d6"

(Note: Again, the functions assume that all input sequences are sorted in descending order, and will return incorrect results if they aren't. Also, the [remove SUBSEQ from SEQ] function above is a bit finicky: if it doesn't find some number that it's trying to remove, it gets stuck on that number and won't actually remove any smaller numbers in SUBSEQ from SEQ either. However, for our purposes that's OK, since we're failing the roll unless all the exact targets are found and removed anyway.)

\$\endgroup\$
  • 1
    \$\begingroup\$ @GOATNine: I'm mostly basing my interpretation on the OP's comments to their question above — particularly their reply affirming Mark Wells's interpretation that "the dice are all rolled together in no particular order, and the player must then find one die matching each requirement (without using the same die more than once)". If instead the dice had to be rolled sequentially and matched to the targets in the order that they're rolled in, that would indeed change the probabilities (generally making success a lot less likely). \$\endgroup\$ – Ilmari Karonen Dec 5 '20 at 15:35
  • \$\begingroup\$ @Ilmari Karonen: You definitely got it right. And thanks! This works beautifully! \$\endgroup\$ – Shemulator Dec 5 '20 at 19:29
  • \$\begingroup\$ @Shemulator, BTW, I added a version that can also handle exact (rather than just "at least") targets. I'm not sure if that's something you actually wanted, but since that was edited into your question, I figured I might as well do it. :) \$\endgroup\$ – Ilmari Karonen Dec 7 '20 at 11:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.