Page 1 of 1

Random Dice (Two RNG examples + distribution tests)

Posted: Thu Jun 11, 2009 4:07 am
by Rescator
Here are two ways to "throw" 5 random dice.

Oh and if anyone knows how to do mod in asm (safely) I'd love to hear it.
It's not that the LCG_Dice() procedure below with the mixed asm and PureBasic is slow, but I can't help but feel that asm could make it even faster.

Enjoy folks, Public Domain (as my posts always are, unless stated otherwise)

Code: Select all

DisableDebugger
Procedure.i RandomSource()
 !RDTSC ;Read the CPU Time Stamp Counter
 ProcedureReturn ;Return the EAX register content, (32bit)
EndProcedure ;we're not using the upper half (EDX) as that hardly changes at all.

Procedure.l LCG_Dice(*seed.Long)
 Protected bit.l,random.l,bias.l,i.l
 random=*seed\l

 !mov eax,dword[p.v_random]
 !mov ecx,1664525
 !mul ecx
 !add eax,7
 !mov dword[p.v_random],eax

 bit=(random%6)
 If bit<0
  bit+6
 EndIf
 bit+1
 *seed\l=random
 ProcedureReturn bit
EndProcedure

Define seed.l,r.l,d1.l,d2.l,d3.l,d4.l,d5.l,d6.l
seed=RandomSource()

d1=0
d2=0
d3=0
d4=0
d5=0
d6=0
For i=1 To 60000000
 r=LCG_Dice(@seed)
 Select r
  Case 1
   d1+1
  Case 2
   d2+1
  Case 3
   d3+1
  Case 4
   d4+1
  Case 5
   d5+1
  Case 6
   d6+1
 EndSelect
Next

EnableDebugger
Debug d1
Debug d2
Debug d3
Debug d4
Debug d5
Debug d6

Debug ""
DisableDebugger

RandomSeed(seed)
d1=0
d2=0
d3=0
d4=0
d5=0
d6=0
For i=1 To 60000000
 r=Random(5)+1
 Select r
  Case 1
   d1+1
  Case 2
   d2+1
  Case 3
   d3+1
  Case 4
   d4+1
  Case 5
   d5+1
  Case 6
   d6+1
 EndSelect
Next

EnableDebugger
Debug d1
Debug d2
Debug d3
Debug d4
Debug d5
Debug d6

Re: Random Dice

Posted: Thu Jun 11, 2009 11:20 am
by PB
> Here are two ways to "throw" 5 random dice

Code: Select all

For dice=1 To 5
  Debug Random(5)+1
Next
What point am I missing :?:

Posted: Thu Jun 11, 2009 11:29 am
by Fred
Why do it easy when you can make it complex ? :)

Posted: Fri Jun 12, 2009 3:39 pm
by Rescator
@PB. Half it seems, Random() is used in the second half of the source.
In the first half a different random generator is used.

Yes, Random() and LCG_Dice() would be used as simply as you stated, but it was necessary to do distribution stats so people could see that the LCG RNG matches (at least) the distribution spread of Random()


@Fred. If you say so. I don't have access to the source of Random() so if you think the LCG_Dice() procedure is more complex I just gotta take your word for it. The speed seems similar though ;)

Speeds tests I added seems to show that Random() is about 1.85 (85%) faster than LCG_Dice() hence why I asked for asm tips to do the rest (i.e. mod) in asm as well. I'm pretty sure the speed of LCG_Dice() would then match Random()


What's so wrong with having two RNG's anyway? All experts say that mixing two RNG's (like maybe xor'ing their output) matches or beats even the best RNG's out there provided their engine are different obviously.

Posted: Fri Jun 12, 2009 4:42 pm
by Fred
There is nothing wrong. But in trick'n'trips, you post something big which can be done in 1 line with build-in command, so we can wonder why ;).

Posted: Fri Jun 12, 2009 4:51 pm
by Rescator
Ah! Gotcha. Updated the title to reflect that better then. :)

Re: Random Dice (Two RNG examples + distribution tests)

Posted: Sat Nov 14, 2015 6:55 am
by collectordave
Rolling Dice check this out for a graphical way of doing it.

http://www.codeinbasic.com/index.php?topic=248.0