You seem to be asking for something like the built-in [explode DIE]
function in AnyDice, except for rerolling the die (once only) if the original roll is below a certain limit.
If you take a look at the AnyDice function library (in the left-hand-side menu) and click the explode
entry, it actually has a convenient "Do it yourself" section that shows how to reimplement the built-in explode
function yourself. The trick for making the syntax nice and clean is to use two functions: a wrapper function that takes in the unrolled die as a parameter and calls a helper function for every possible outcome of the roll (i.e. passing the same die to the helper function, which expects a number).
We can use the same trick here:
function: reroll DIE:d if under LIMIT:n {
result: [reroll DIE as DIE if under LIMIT]
}
function: reroll ROLL:n as DIE:d if under LIMIT:n {
if ROLL < LIMIT { result: DIE }
else { result: ROLL }
}
loop SIDES over {4,6,8,12,20} {
output [reroll dSIDES if under 3] named "d[SIDES] with GWF"
}
Here, [reroll DIE if under LIMIT]
is the wrapper function, which simply calls the inner function [reroll ROLL as DIE if under LIMIT]
for every possible roll of the die. The inner function then just checks if the roll is below the limit, and if so, returns the "re-rolled" die instead of the original roll.
Of course, you could also just call the inner function directly, as in:
loop SIDES over {4,6,8,12,20} {
output [reroll dSIDES as dSIDES if under 3] named "d[SIDES] with GWF"
}
and get the same results. But sometimes it's nice to avoid repeating a parameter like that. In fact, if we're only interested in modeling rerolls due to Great Weapon Fighting, we might as well leave the constant LIMIT
parameter out, too, and simplify our wrapper function into just:
function: gwf DIE:d {
result: [reroll DIE as DIE if under 3]
}
Bonus: The output of the function(s) given above is itself a die (i.e. a probability distribution over the integers), and thus can be assigned into a custom die that "automatically rerolls itself". You can then roll as many of these custom dice as you want, or even mix them with other dice.
For example, to get the results of rolling 2dX with Great Weapon Fighting, you could do:
loop SIDES over {4,6,8,12,20} {
GWF: [gwf dSIDES]
output 2dGWF named "2d[SIDES] with GWF"
}
or, alternatively, just:
loop SIDES over {4,6,8,12,20} {
output 2d[gwf dSIDES] named "2d[SIDES] with GWF"
}