# How can I model the probabilities for this mechanic involving cancelling out dice pools in AnyDice?

So I'm struggling with the probabilities for a dice mechanic.

You create a d6 pool of Edge dice and Snag dice and roll all of them.

Each Snag die cancels an Edge die of a lower value.

After cancelling out, you pick the single highest Edge die left.

If no Edge dice are left, you pick the single lowest Snag die.

If there's no die left, consider the result a 1.

Example 01: I roll 3 Edge dice {3, 5, 5} and 2 Snag dice {5, 6}. Result: 5

Example 02: I roll 2 Edge dice {3,4} and 4 Snag dice {2, 3, 5, 5}. Result: 2

Example 03: I roll 1 Edge die {3} and 1 Snag die {5}. Result: 1

Would you guys help me model it on AnyDice?

• Do the edge dice always cancel in ascending order? So E{1,2,3} and S{4,4} cannot yield 1 or 2 (which is valid based on your rules above where it just cancels any die of lower value) Jul 8, 2019 at 16:34
• Welcome to RPG.SE! Take the tour if you haven't already, and check out the help center for more guidance. I assume this is a homebrew mechanic unassociated with any existing RPG? (I ask because if it were associated with a particular RPG, tagging it with that system could help attract experts in that system to the question.) Jul 8, 2019 at 21:41
• Hi! Yes,it is a homebrew! Should I clarify it with an edit? Jul 9, 2019 at 13:18

## Anydice program

I've written the following anydice function which I think implements your desired mechanic, as described. I have assumed that, when cancelling, the highest snag die cancels the highest edge die that it can, and then so on descending from there.

function: edgesnag EDGE:s SNAG:s {
loop X over {1..#EDGE} {
if X@EDGE >= X@SNAG { result: X@EDGE }
}
if #EDGE < #SNAG { result: #SNAG@SNAG }
result: 1
}


This function expects to be invoked with two dice pools, e.g. [edgesnag 2d6 3d6].

So the way this works is that we cast the die pools to sequences, to fix them for inspection, and then we'll loop over those sequences to compare the dice. Remember that by default therefore anydice sorts the pool in descending order (so a roll like 3, 5, 3 becomes {5,3,3}). We thus consider the dice in the two sequences in pairs.

If the first die in the EDGE sequence is greater than or equal to the first die in the SNAG sequence, we are already certain that this edge die will not be cancelled by any snag dice, so it will remain at the end and is therefore the result. Otherwise, the snag die cancels the edge die, and we loop on to the next pair, comparing them in the same way.

If we run out of snag dice to cancel edge dice without finding a keeper, we'll take the edge die we're currently considering as the highest remaining result (the value of a nonexistent element in a sequence is 0, so the check will favour the edge die). Otherwise, the loop will continue until we run out of edge dice.

If we run out of edge dice, and there were more snag dice than edge dice, snag dice must remain and so the result will be the smallest snag die. Otherwise, it must be the case that no dice remain, and the result is 1.

It is necessary for us to optimise the algorithmic implementation of your mechanic in this way because otherwise, anydice will choke pretty quickly on relatively small dice pools. Even as it is, it can just about handle [edgesnag 5d6 5d6]; beyond this, the possible sequence permutations are too large and it chokes. (Some greater anydice expert might be able to further optimise it past this limitation but this is as far as I go.)

## Observations

• My original idea was for snag dice to cancel lower or equal edge die, but I felt it punished players too much. I might be wrong, though. I assume removing the equal sign at the third line wouldbe enough to test it, am I right? Also, maybe if all dice are cancelled, roll 1d6 and keep that as a result? Your observations made me realize this mechanic is probably broken. I tried to mend it, but... function: edgesnag EDGE:s SNAG:s { loop X over {1..#EDGE} { if X@EDGE > X@SNAG { result: X@EDGE } } if #EDGE < #SNAG { result: #SNAG@SNAG } result: 1d6 } Jul 9, 2019 at 13:31
• The proposed change still has a bit of an issue where occasionally more snag dice are better (compare [snagedge 2d6 1d6] and [snagedge 2d6 2d6] for example). But yes, changing the comparison to a straight > rather than >= represents snag dice cancelling equally or lesser edge die. Jul 9, 2019 at 14:16