Just use sequence comparison.
The documentation could explain this better, but it turns out (with an assumption about your intention) this is really trivial to do with Anydice's built in comparisons. In the documentation about sequences:
Compared to a sequence
The sequences are compared number by number, from left to right, resulting in either a 1 or a 0.
Experimentation shows this means it actually iterates through the sequences, comparing the Nth value of the first to the Nth value of the other. If we have two sequences, A and B, then A > B
iterates through the sequence:
returns 1 if the Nth value of A is greater than the Nth value of B
returns 0 if the Nth value of A is less than the Nth value of B
goes on to the N+1th value if they are equal
It also returns 1 if B runs out of elements before A or 0 if A runs out of elements before or at the same time as B.
So if you compare the sequences:
{6,4,3,2} > {6,4,2,1}
: 1
{6,4,3,2} > {6,4,3,3}
: 0
{6,4,3,2} > {6,4,3}
: 1
{6,4,3} > {6,4,3,1}
: 0
{6,6,5} > {6,5,5,1}
: 1
You can do this sort of comparison with dice if you cast them to sequences using a function before you compare them.
function: compare ATTACK:s to DEFENCE:s {
result: ATTACK > DEFENCE
}
output [compare 4d6 to 3d6]
When the function compare ATTACK to DEFENCE
is invoked, the ATTACK:s
and DEFENCE:s
in the declaration convert whatever arguments are provided into a sequence. When a dice pool is converted into a sequence, it becomes a sequence representing the results of rolling that dice pool, sorted from high to low (and the function is invoked once for every possible result of the roll and the results statistics'd together).
This program takes dice pools and does a bit of sequence comparison to tell you which one wins under these circumstances. This does assume that your rule is that 6,6,5
beats 6,5,5
, i.e. that dice cancel each other out on a 1:1 basis; if you intended differently, this becomes much more complex to describe and Anydice starts to not be very efficient.
But I want to count the number of draws!
Unfortunately, sequence comparison won't let you do that. But if you write your own loop iterator manually, it will run less efficiently than anydice's built in comparison (so you are limited to smaller dice pools before anydice gives up on the program) but you can get this information:
function: compare ATTACK:s to DEFENCE:s {
loop N over {1..[lowest of #ATTACK and #DEFENCE]} {
if N@ATTACK > N@DEFENCE { result: N }
if N@ATTACK < N@DEFENCE { result: -N }
}
if #ATTACK > #DEFENCE {result: #DEFENCE +1}
if #ATTACK < #DEFENCE {result: -#ATTACK -1}
result: 0
}
Basically, we loop over the length of the shortest array doing the element by element comparison, and when we get a victory or fail we return N for success (or -N for fail). This means we reached the Nth element of the array before we got a result and therefore N-1 pairs of dice were cancelled. Then there's the extra bit of logic on the end which works out who wins if all the dice it was able to compare were draws (and ensures that the result is consistent with the above, so subtract 1 from the absolute value to work out how many dice pairs were cancelled).
This program implements the above code. In my testing it can do up to 5d6 vs 5d6 before it starts taking too long for anydice to execute (as you expect dice pools in the 1-4 range, hopefully that's still useful for you).