I'm doing a dice program using a freerunning timer that automatically and fairly counts from 0-6^x (where x is number of die)
Now one die is easy (I'm a BASIC programmer but want to do it in C18)
So
A single die is roll+1
Two dice are D1=int(roll/6)+1 and D2=(roll mod 6)+1
Any ideas on 3 or more dice? And avoiding floating point...
Does the MCU you're using have a hardware divide instruction or are you useing a maths library?
The x86 does and puts the quotent and remainder in to different registers. Using a high level language like C will probably end up producing two divide instructions, one to get the remainder and another for the quotent which is a wate of clock cycles. I'd recommend doing the division part in assembler, that way you can use one instruction to get both the quotent and remainder.
Does the MCU you're using have a hardware divide instruction or are you useing a maths library?
The x86 does and puts the quotent and remainder in to different registers. Using a high level language like C will probably end up producing two divide instructions, one to get the remainder and another for the quotent which is a wate of clock cycles. I'd recommend doing the division part in assembler, that way you can use one instruction to get both the quotent and remainder.
What use is the remainder? For D4 the calculation goes, int(roll/216), result/6 and keep remainder. Two divides required anyway. D2 is the only one that could benefit from the remainder but the additional code wouldn't be worth it.
I don't see why more than one divider per iteration is required.
Roll is the variable with the the value generated by the timer.
Divide, is the divide instruction, it accepts two variables, the first value is divided by the second value. After the instruction is executed the quotent is stored in the first variable and the remainder is stored in the second.
e.g.
x = 105
y = 10
Divide x, y
Print x, y
The output will be:
10 5
Assuming the PIC has a similar instruction, here's how you'd use it. Roll is the random number which is set before the code runs.
Do
Remainder = 6
Divide Roll, Remainder
Print Remainder
Loop until Roll = 0
Well the formula should work well as an unsigned int function (now I'll have to learn C18 functions)
Code:
for Roll = 0 to 6^4-1
D1 = int(Roll/1 mod 6)+1
D2 = int(Roll/6 mod 6)+1
D3 = int(Roll/36 mod 6)+1
D4 = int(Roll/216 mod 6)+1
print Roll, D1, D2, D3, D4
next
It's a real gem, it was one of your older posts that pointed it out to me.
It occurred to me to let it free run till you press a button, presto instant random number.
I could do the software in Swordfish easy, but it's more a challenge to do it in C18.
Eventually I'll make a Risk game battle dice (5 dice) roller on the Junebug as one of the tutorials.
You can of course use the compiler's runtime library to do the division if the PIC does not have a hardware divider, but if it is just for 2 dice why don't you use repeated substraction in a loop ? Stupid ,yes but very simple and performance is not a concern in this case, anyway the number of iterations would be 0 to 5 so who cares ? This will give you both the result of the division and the remainder... easy to do even in assembly.
Petr