AnyDice handles exploding dice in a peculiar fashion that's poorly-suited for roll-and-count dice pools. I have cobbled together a somewhat inelegant solution, but it appears to work correctly.
Here's the link to the program.
Instead of using dice in the usual manner, I've created several functions that, given parameters of a die, return its output, i.e. the number of successes it has produced.
function: roll ROLL:n threshold T {
if ROLL >=T {result: 1}
result: 0
}
function: rollexploding ROLL:n threshold T{
if ROLL =6 {result: 1+[rollexploding 1d6 threshold T]}
result: [roll ROLL threshold T]
}
function: rerollfailures ROLL:n threshold T{
if ROLL < T {result: [roll 1d6 threshold T]}
result: [roll ROLL threshold T]
}
function: rerollthenexplode ROLL: n threshold T {
if ROLL < T {result: [rollexploding 1d6 threshold T]}
result: [rollexploding ROLL threshold T]
}
Then I made a wrapper function that would figure out which of these functions to call, and handle requests for multiple dice being rolled:
function: wrapper DICE:n threshold T explode E reroll R{
RES:0
loop N over {1..DICE} {
if E & R {RES: RES+[rerollthenexplode 1d6 threshold T]}
else {if E {RES:RES+[rollexploding 1d6 threshold T]}
else {if R {RES:RES+[rerollfailures 1d6 threshold T]}
else {RES:RES+[roll 1d6 threshold T]}
}
}
}
result:RES
}
Finally, I made a bunch of functions that simplify input by providing pre-determined combinations of parameters. I'll provide only 3 of them here:
function: b DICE:n{
result:[wrapper DICE threshold 4 explode 0 reroll 0]
}
function: be DICE:n{
result:[wrapper DICE threshold 4 explode 1 reroll 0]
}
function: gr DICE:n{
result:[wrapper DICE threshold 3 explode 0 reroll 1]
}
To use it, type things like output [b 4]
To input the result of a function into another function, simply call the second function with the first function as a parameter.
For example, your complete AnyDice program could look like this:
function: hitme NN:n {
result: [count {5, 6} in NN d6]
}
function: woundme HH:n {
result: [count {1, 2, 3, 4, 5} in HH d6]
}
output [woundme [hitme 5]]
Best Answer
Cut your
lossesaccuracyWhen working with many kinds of modeling there is a tradeoff between accuracy and speed. Anydice cuts us off on our speed, so we need to lose some accuracy. Anydice already truncates to exploding twice anyway and seeing as exploding twice on a d10 will only happen in 1 in a hundred throws the error should be fairly small.
For simplicity — rather than implementing a custom explode function — we can simply create the truncated exploded dice like this:1
Which I'd call close enough:
Anydice will then model up to 8k3, at least fairly close. It will slant slightly lower, and obviously loses out on the extreme highs (which are pretty much 0 anyway).
You can consider the effect for this for pools were anydice is willing to calculate with explodes, say for 5k3:
Carcer points out you can do the same thing by changeing anydice's explode depth:
but I'll stick to the custom die method partly to show it off and because it appears to be slightly faster, but onfortunatly not enough to be give an actual benefit to us here.