# AnyDice function to reroll one die if any die rolls X

I’m by no stretch of the imagination any sort of programming type, but I’ve been trying to use AnyDice to rank all the possible ways the die rolls can be modified in the board game HeroQuest. The basic mechanics of the use a roll and count die pool with opposed rolls using a base die that could be represented as {3:3, 2:2, 1} with three being used to attack, two being used for hero defense, and one being used for monster defense. Though the dice themselves are symboled dice using skulls, white shields and black shields respectively.

Using variables and custom dice I was able to cover most of the modifiers (that I could think of) which could be applied to the rolls. For example, a popular fan modification is to add colored dice with alternate distributions and doubled icons on some faces. To make these I just added three to the icon’s value to represent doubles and made new dice/variables for the alternate distribution (example: {6, 3:2, 5, 2, 1})

By some miracle of mess ups I managed to somehow get a function which when combined with the variables is able to produce all of the basic rolls as well as rolls where all the dice can be rerolled. But it cannot reroll a single die from the pool if X was rolled. I’ve spent days trying to figure this out (actually longer as this is something I have tried multiple times) and it keeps seeming like I’m almost there but whenever I run the function and then do actual math to compare (or run a control die in the program) the results do not match. With my extremely limited understanding of how AnyDice works it seems like my current function should have worked but if that was the case I wouldn’t be looking for help.

Here are a few of the variables and the functions that I’ve gotten (will only post variables for purple dice as they have doubles and serve as one of the worst testers):

 PURPLE: {6, 3:2, 5, 2, 1}
SK: 3
WS: 2
BS: 1
NA: -3 (used if no rerolls allowed)
BRPR: {6:7, 3:14, 5:7, 4:7, 1}


BRPR is a consolidated purple die rerolling black shields for control purposes or global rerolls.

There is also a COLOR, ACTION, and REROLL variable just above the output section and below the functions where I edit which dice I want to emulate and which die roll to test for.

Functions copied from AnyDice:

 function: roll DICE:s for ICON:n no
reroll
{SUCCESSES: DICE = ICON
DOUBLE: DICE = ICON + 3
if SUCCESSES > 0 {result: SUCCESSES
+ DOUBLE*2} if DOUBLE >0 {result:
DOUBLE*2}

else {result:0}}

function: roll DICE:s for ICON:n
reroll SINGLE
{SUCCESSES: DICE = ICON
DOUBLE: DICE = ICON + 3
if DICE != SINGLE|SINGLE+3
{result: SUCCESSES + DOUBLE*2}
result: SUCCESSES + DOUBLE*2 +
[roll 1dDICE for ICON no reroll]}

COLOR: PURPLE
ACTION: SK
REROLL: BS
\End edits here\

loop MAX over {1..4} {
output [roll MAX d COLOR for ACTION
reroll REROLL] named "[MAX]d Test"}

loop DICE over {1..4} {
output DICEd{1:2,2,0:3} named
"[DICE]d No reroll Control"}

output [roll 1dBRPR for ACTION no
reroll] named "Single Reroll
Control"


The results as I’m understanding should be checking for the reroll first and if it is negative it counts successes and doubles, then if there is a reroll rolling a single die and adding those successes to the successes already rolled. Instead I’m getting the same results as if there are no rerolls allowed. Can some please explain what I’m doing wrong here? Please explain it as if you’re talking to a five year old child as they’re probably more proficient at this than I am.

Link to the function with full variables if necessary: https://anydice.com/program/2ea73

There are two problems here:

function: roll DICE:s for ICON:n reroll SINGLE {
SUCCESSES: DICE = ICON
DOUBLE: DICE = ICON + 3
if DICE != SINGLE | SINGLE + 3 {
result: SUCCESSES + DOUBLE*2
}
result: SUCCESSES + DOUBLE*2 + [roll 1dDICE for ICON no reroll]
}


(I've changed this code to use more conventional formatting.)

First, DICE != SINGLE | SINGLE + 3 does the following:

• Compares each of the dice rolls to SINGLE.
• Implicitly sums the result, which is the number of dice that rolled SINGLE.
• Performs a logical OR with SINGLE + 3. Since SINGLE + 3 is nonzero, the condition always evaluates to a result of 1 (true). Thus the conditional is always taken and the last line of the function will never be used.

What you want here is rather SUCCESSES + DOUBLE = #DICE, which will determine whether all of the dice were already successes or double successes.

Second, [roll 1dDICE for ICON no reroll] doesn't do what you want either. Since DICE has type sequence, 1dDICE will select a random element from the original roll of the pool rather than rerolling the die. You would need to take the die itself as an additional parameter of type die.

• I’m confident I understand why the Dice != SINGLE!SINGLE+3 as you explain it; however (if I’m reading your message correctly) if I dropped the |SINGLE+3 out it would work like it should on the single icon face and not the double (since it was removed with |SINGLE +3)? Commented Apr 3, 2023 at 1:41
• But now what I’m not confident about is how the second part of your message SUCCESSES + DOUBLE = #DICE solves it (not being smart elec asking so I can understand). With that line I don’t see how the program will compare/look for any of the reroll icons (in this example it’s rerolling on 1 or 4 but the dice could also come up 2 or 5) Commented Apr 3, 2023 at 1:42
• SUCCESSES + DOUBLE is the number of dice that rolled either a success or a double. If this is equal to the total number of dice, then there is nothing to reroll. Commented Apr 3, 2023 at 2:00
• I may be missing something simple here so please forgive me if I am, but wouldn’t a 3, 3, 2, 6 roll also trigger the reroll that way? Or would I need to then add an additional line to test for that. Wait, you’ve given me another thought. Would it work (probably overly complicated again) if I just changed the reroll to checking for one or the other and added a second if statement for the second reroll possibility? There are four possible results on any given face: success, double success, nothing, reroll. So checking for each individually? Commented Apr 3, 2023 at 2:49
• In the case of 3, 3, 2, 6 you have SUCCESSES = 2 and DOUBLE = 1 for a total of 3. But #DICE = 4 so the conditional is not taken and the reroll happens. Commented Apr 3, 2023 at 4:14

I believe I have the formula fixed now. There is a small to very small difference between the results this produces vs what I came up with using basic math but I’m assuming that is either a rounding or truncating error.

I’ll post the link as well as the actual function here, if anyone sees anything incorrect or even something “right” but which could be better please let me know.

Edit: I hope this is easier to read than the previous one I posted. Since I’m not a programmer I’m not too sure what the typical formats used would be. From looking at it what stood out to me was mostly just starting new lines and making sure the “}” where lines by themselves (to be easier to see I’m assuming).

Edit your roll here\
COLOR: PURPLE
ACTION: SK
REROLLING: BS
\End edits here\

function: roll DICE:s for ICON:n {
SUCCESSES: DICE = ICON
DOUBLE: DICE = ICON + 3
if (SUCCESSES + DOUBLE) > 0 {
result: SUCCESSES + DOUBLE*2
}
else {
result:0
}
}

function: roll DICE:s for ICON:n reroll SINGLE {
SUCCESSES: DICE = ICON
DOUBLE: DICE = ICON + 3
REROLL: DICE = SINGLE
DBLROLL: DICE = SINGLE +3
if (SUCCESSES + DOUBLE > 0) & (REROLL + DBLROLL) =0 {
result: SUCCESSES + DOUBLE*2
}
if (SUCCESSES + DOUBLE = 0) & (REROLL + DBLROLL) >0 {
result: [roll 1dCOLOR for ACTION]
}
if (SUCCESSES + DOUBLE > 0) & (REROLL + DBLROLL) >0 {
result: SUCCESSES + DOUBLE*2 + [roll 1dCOLOR for ACTION]
}
result: 0}

loop MAX over {1..4} {
output [roll MAX d COLOR for ACTION reroll REROLLING] named "[MAX]d Test"
}


The first function is only used during the reroll sequence itself. The function should be only rerolling a single die, and it should only trigger if a die result is equal to either the REROLL or DBLROLL values (1/Black Shields as I have it set now).

On the function’s page I have a list of variables which can be swapped for COLOR, ACTION, and REROLLING to facilitate most of the mods I could think of. For Rerolling all dice I had to use the rerolling die variables and set the REROLLING variable to NA (-3 so the DBLROLL value is 0 which no dice have).

As I said there were small differences between the produced results and what I got with math. But that could just be on my math skills, single dice give exactly the same results while two dice are off by roughly 0.2%. For three dice I only checked a couple of the easier possibilities such as six to four successes but they were all within 0.1% of what the math was producing. Beyond that I started to lose count of the possibilities and didn’t trust my values anymore. (~96 reroll triggering rolls in three dice so there are ~700 total possible roll results).