My old dice rolling routine, shared for Staxtix, to help showcase the core idea behind my new and improved utility which I'm working up:
_TITLE "Steve's Simple Dice Roller"
QuickRoll 10, 2, 10, 0, 0, 0, 0
PrintResults
QuickRoll 2, 5, 6, 1, 0, 3, 0
PrintResults
INPUT "Dice to Roll =>"; d$
old$ = d$
RollDice d$
PrintResults
SUB QuickRoll
(S
, D
, N
, DM
, TM
, KH
, KL
)
Results(0, 0) = TM
Rolls
(i
- 1) = INT(RND * N
) + 1 + DM
'PRINT Rolls(i - 1), 'UNREMARK THIS LINE TO SEE UNSORTED NUMBERS
'PRINT 'AND THIS LINE TO SEE UNSORTED NUMBERS
'The dice sorting routine, optimized to use _MEM and a comb sort algorithm. It's more than fast enough for our needs here I think. ;)
IF D
> 1 THEN 'No need to try and sort only 1 dice.
gap = 10 * gap \ 13
i = 0
swapped = 0
o = m.OFFSET + i * 4
o1 = m.OFFSET + (i + gap) * 4
swapped = -1
i = i + 1
'FOR i = 1 TO d: PRINT Rolls(i - 1),: NEXT: PRINT 'UNREMARK THIS LINE TO SEE THE SORTED NUMBERS, BEFORE WE DISCARD LOW OR HIGH
IF KH
THEN 'drop the undesired low rolls IF KL
THEN 'drop the undesired high rolls Results(j, i) = Rolls(i - 1)
total = 0
total = total + Results(j, i)
total = total + Results(0, 0) 'Results 0,0 holds our total modifier
Results(j, 0) = total 'And store the total in the 0 element of the array
'First strip spaces if any
d$
= UCASE$(text$
) 'Then make it UCASE for ease of parsing
'Parse the text for the proper number and size dice to roll
l
= INSTR(d$
, "D") 'l is the location of the D which tells us how many dice to roll and what size MID$(d$
, l
) = "@" 'Replace the D with something else so we don't accept it as a scientific notation value l1
= INSTR(l
+ 1, d$
, "+") 'l1 is the location of the dice modifier (+/-), which is optional
l2
= INSTR(d$
, "S") 'l2 is the location of S, which is the number of sets of dice we want to roll
l3
= INSTR(d$
, "T") 'l3 is the location of the total modifier, if any IF l1
> l3
AND l3
<> 0 THEN l1
= 0 'In case we have a T-100 and not a +/- to the dice rolls first
l4
= INSTR(d$
, "KH") 'l4 tells us how many of the high rolls to keep IF l4
= 0 THEN l4
= -INSTR(d$
, "KL") 'or how many of the low rolls to keep
Results(0, 0) = tm
Rolls
(i
- 1) = INT(RND * n
) + 1 + dm
'PRINT Rolls(i - 1), 'UNREMARK THIS LINE TO SEE UNSORTED NUMBERS
'PRINT 'AND THIS LINE TO SEE UNSORTED NUMBERS
'The dice sorting routine, optimized to use _MEM and a comb sort algorithm. It's more than fast enough for our needs here I think. ;)
IF d
> 1 THEN 'No need to try and sort just one dice
gap = 10 * gap \ 13
i = 0
swapped = 0
o = m.OFFSET + i * 4
o1 = m.OFFSET + (i + gap) * 4
swapped = -1
i = i + 1
'FOR i = 1 TO d: PRINT Rolls(i - 1),: NEXT: PRINT 'UNREMARK THIS LINE TO SEE THE SORTED NUMBERS, BEFORE WE DISCARD LOW OR HIGH
IF kh
THEN 'drop the undesired low rolls IF kl
THEN 'drop the undesired high rolls Results(j, i) = Rolls(i - 1)
total = 0
total = total + Results(j, i)
total = total + Results(0, 0) 'Results 0,0 holds our total modifier
Results(j, 0) = total 'And store the total in the 0 element of the array
PRINT " = "; Results
(s
, 0)
So there's a ton of dice rolling routines out there already you say... You ask, "What makes this one different?"
Well, I'm glad you asked! (Or that I imagined you'd ask...)
This routine lets us send it a STRING, and it parses that single string and sends us back the results that we wanted.
String format is: #S#D#+#T#
Sounds complicated at first, but it's not.
#S is the numbers of sets of dice we want rolled.
#D# is the number of dice in the set, and the size of the dice.
+# is the modifier for each dice
T# is the total modifier.
So some working examples -- run the program and type these in and see the way it works.
3d4
3d6
3d10
3d4+10
3d4-10
3d4+10T100
3d4-10T-100
Now those will get you single runs of the wanted rolls. Also give these a fast try
5s3d10
10s2d4+1T10
To break down the last valid command there (10s2d4+1T10), what it's telling the program to do is:
Roll 10 SETS
Of 2
D4 (a four sided dice)
add 1 to each dice roll
and then add 10 to the total
so the numbers we generate will be 1-4+1, or 2-5. For 2 dice, which gives us a range of 4-10. And then we add 10, so our range is now 14-20.
And we do this for 10 sets which fall into that end range of 14-20...
Notice this has two main processing routines for us:
QuickDice, which is an easy way to plug into an existing QB64 program and pass simple parameters to it for, and then it generates our formula for processing (for folks who aren't interested in learning the rolling syntax).
RollDice, which takes the proper syntax as illustrated above, and then sends us the results so we can use them in our programs however we see fit.
Results from the diceroll are returned via a 2 dimensional array called, fitting enough, Results(set, roll)
So if we send it "3S2d6" -- the command to roll 3 sets of 2D6, what we get back is a 2 dimensional array, Results(3,2), which looks like:
Results(1,1) = 1
Results(1,2) = 3
Results(2,1) = 2
Results(2,2) = 5
Results(3,1) = 3
Results(3,2) = 1
The first 2 results are the first set (1,3), the next are the second set (2,5), and the last is the third set (3,1).
If all we care about is the TOTAL of the rolls, it's pre-added in the second index.
Results(1,0) = 4
Results(2,0) = 7
Results(3,0) = 4
Send it a string formula, get back an array of results...
It's actually a very powerful little routine, which can be used in all sorts of ways. The main purpose of Steve's Ole Dice Roller (the work in progress) is to add more functionality and a simple UI so people who aren't used to these type dice rolls will have an easier way to interact with the roller. ;)