AnyDice – Complicated Stat Distribution

ability-scoresanydicestatistics

I'm trying to model average stat distributions for characters based on what a friend sent me:

Balanced Stat Roll

Roll 4d6 drop lowest five times. Count them together and deduct the total from 72. The last number is the sixth ability score, provided it's greater than 3 and less than 19, otherwise re roll the set.

Essentially, I want to take the total of 5 "4d6 drop lowest" rolls, and produce the sixth roll by subtracting that from 72. I've been able to get that far using the below code, modified from the looped function https://anydice.com/articles/4d6-drop-lowest/, resulting in the below:

ABIL: 5 d [highest 3 of 4d6]
loop P over {1..5} {
 output P @ ABIL named "Ability [P]"
}

output 72 - {1..5}@ABIL named "Ability 6"

However the output for "Ability 6" clearly isn't bound to the normal 3-18 distribution I want, which invalidates all of the outputs by extension as the whole group has to be tossed out if the 6th total is less than 3 or greater than 18.

I've tried a number of ways to create a function that binds the output of everything to whether the calculation of the 6th ability is within that range, but I keep running into issues as I'm not well versed in AnyDice at all. Trying to include the loop in the function results in errors with the output part of the loop no matter how I try to reformat it, and I'm not exactly sure how else to proceed. Any help would be appreciated.

Here's a link to the code above in AnyDice for visualization, you can see that "Ability 6" generates a probability range of -18 to 57. https://anydice.com/program/348c7

Best Answer

You can return an empty die d{} from a function to reject results. They will be removed from the probability space, which is equivalent to rerolling such results without limit, or conditioning against such results.

While we're at it, we can do an explicit sort of the five rolled scores and the synthetic sixth to get an overall ranking.

function: balanced RANK:n from FIVE:s {
 SIXTH: 72 - FIVE
 if SIXTH < 3 | SIXTH > 18 {
  result: d{}
 }
 result: RANK @ [sort {FIVE, SIXTH}]
}

loop RANK over {1..6} {
 output [balanced RANK from 5d[highest 3 of 4d6]]
}

Link.

Side note: This script keeps cases where the last score is a 3, as per the second half of your question. However, as written in your linked image, a 3 on the last score is also rejected. I'm unsure if this was intentional; if it was, just adjust SIXTH < 3 to SIXTH < 4.

Related Topic