One really handy thing about Microsoft Office is that it's fairly ubiquitous, and it comes with its own programming language. I don't have to package anything up. I can just share the code with you and have you insert it into a Word module. I don't know how much experience you have with Word macros. A quick search should help, but I can also walk you through the steps of putting this into Word. It's a fast-and-dirty code job. I couldn't be bothered with designing my own sort, so I Googled one and tacked it on there. It works for what is needed here. Just copy this code and put it into your VBA Editor. Run the macro named "DrabTest".
You may want to start off with a small number of iterations just to get an idea of how long each process will take. The more iterations you have, the closer your average damage will be to the real mean.
For your convenience and confidence, the code outputs into Word the die results so that you can confirm that the code is doing what it should. At the very end is the average damage over all iterations.
And I welcome any other coders to review my work. As I said, it's fast and dirty, so it's a little embarrassing.
Option Explicit
Public Sub Drab_Test()
Dim strAtt() As String
Dim strDef() As String
Dim docNew As Document
Dim intAttCount As Integer
Dim intDefCount As Integer
Dim intIterations As Single
Dim intRange As Integer
Dim intHit As Integer
Dim intHitCount As Integer
Dim i As Integer
Dim j As Integer
Dim k As Integer
'If you don't want to be asked each time, replace the InputBox with hard numbers
intIterations = InputBox("How many iterations do you wish to run?")
intAttCount = InputBox("How many attacks?")
intDefCount = InputBox("How many defenses?")
intRange = InputBox("What is the range?")
intHitCount = 0
ReDim strAtt(1 To intAttCount)
ReDim strDef(1 To intDefCount)
'Initialize arrays
For i = 1 To UBound(strAtt)
strAtt(i) = ""
Next i
For i = 1 To UBound(strDef)
strDef(i) = ""
Next i
Set docNew = Documents.Add
docNew.Range.InsertAfter "Number of iterations: " + CStr(intIterations) + vbCr + vbCr
For i = 1 To intIterations
intHit = 0
docNew.Range.InsertAfter "Att rolls:"
For j = 1 To UBound(strAtt)
strAtt(j) = Int(Rnd() * 6 + 1)
Next j
strAtt = BubbleSrt(strAtt, True)
For j = 1 To UBound(strAtt)
docNew.Range.InsertAfter " " + strAtt(j)
Next j
docNew.Range.InsertAfter " Def rolls:"
For j = 1 To UBound(strDef)
strDef(j) = Int(Rnd() * 6 + 1)
Next j
strDef = BubbleSrt(strDef, True)
For j = 1 To UBound(strDef)
docNew.Range.InsertAfter " " + strDef(j)
Next j
docNew.Range.InsertAfter vbCr
'Drop att out of range
For j = 1 To UBound(strAtt)
If CInt(strAtt(j)) < intRange Then strAtt(j) = ""
Next j
'Compare def to att
For j = 1 To UBound(strDef)
For k = 1 To UBound(strAtt)
If strDef(j) <> "" And strAtt(k) <> "" Then
If CInt(strDef(j)) >= CInt(strAtt(k)) Then
strDef(j) = ""
strAtt(k) = ""
End If
End If
Next k
Next j
docNew.Range.InsertAfter "Unblocked att:"
For j = 1 To UBound(strAtt)
docNew.Range.InsertAfter " " + strAtt(j)
If strAtt(j) <> "" Then intHit = intHit + 1
Next j
docNew.Range.InsertAfter " Unused def:"
For j = 1 To UBound(strDef)
docNew.Range.InsertAfter " " + strDef(j)
Next j
docNew.Range.InsertAfter vbCr
docNew.Range.InsertAfter "# Hits: " + CStr(intHit) + vbCr + "==========" + vbCr
intHitCount = intHitCount + intHit
Next i
docNew.Range.InsertAfter vbCr + "Average hit: " + CStr(intHitCount / intIterations)
End Sub
Public Function BubbleSrt(ArrayIn, Ascending As Boolean)
Dim SrtTemp As Variant
Dim i As Long
Dim j As Long
If Ascending = True Then
For i = LBound(ArrayIn) To UBound(ArrayIn)
For j = i + 1 To UBound(ArrayIn)
If ArrayIn(i) > ArrayIn(j) Then
SrtTemp = ArrayIn(j)
ArrayIn(j) = ArrayIn(i)
ArrayIn(i) = SrtTemp
End If
Next j
Next i
Else
For i = LBound(ArrayIn) To UBound(ArrayIn)
For j = i + 1 To UBound(ArrayIn)
If ArrayIn(i) < ArrayIn(j) Then
SrtTemp = ArrayIn(j)
ArrayIn(j) = ArrayIn(i)
ArrayIn(i) = SrtTemp
End If
Next j
Next i
End If
BubbleSrt = ArrayIn
End Function