Difference between revisions of "Programming:Random Number Generator"
(Added RNG with lookup table) |
(→8-bit random number generator using Refresh Register (R)) |
||
(5 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
− | == | + | == BASIC == |
− | This is a very simple generator. | + | The BASIC command <tt>RANDOMIZE TIME</tt> can be used to generate random numbers, using the value of the <tt>TIME</tt> variable as a seed. The <tt>TIME</tt> variable is incremented every 1/300th of a second, so it is highly unlikely that the same set of numbers will be generated each time the BASIC program is run. |
+ | |||
+ | However, after about five or six numbers are obtained using the <tt>RND</tt> command, the randomness of the numbers decreases dramatically. The listing below demonstrates this problem: | ||
+ | |||
+ | <pre>10 MODE 2 | ||
+ | 20 FOR a=1 TO 23 | ||
+ | 30 RANDOMIZE TIME | ||
+ | 40 FOR b=1 TO 25 | ||
+ | 50 PRINT USING("## ");INT(RND*100); | ||
+ | 60 NEXT b | ||
+ | 70 PRINT | ||
+ | 80 NEXT a</pre> | ||
+ | |||
+ | This problem can be overcome by using the commands <tt>RANDOMIZE TIME:RANDOMIZE RND</tt> instead. This re-initialises the random number seed and greatly improves the randomness of the numbers that are obtained using the <tt>RND</tt> command. | ||
+ | |||
+ | == Machine code == | ||
+ | |||
+ | === 8-bit random number generator === | ||
+ | |||
+ | This is a very simple generator. Its function is x[i + 1] = (5 * x[i] + 1) mod 256. The only advantage is the small size and its simplicity. | ||
'''Input:''' ''none'' | '''Input:''' ''none'' | ||
Line 18: | Line 37: | ||
</pre> | </pre> | ||
− | == 8-bit | + | === 8-bit random number generator (lookup table based) === |
− | To use this routine you need to define 1 | + | To use this routine you need to define 1 byte of RAM for the ''RandomPtr''. |
'''Input:''' ''none'' | '''Input:''' ''none'' | ||
Line 35: | Line 54: | ||
add a,l | add a,l | ||
ld l,a | ld l,a | ||
− | jr nc, | + | jr nc,skip |
inc h | inc h | ||
.skip: ld a,(hl) | .skip: ld a,(hl) | ||
Line 60: | Line 79: | ||
</pre> | </pre> | ||
− | == 16-bit | + | === 8-bit random number generator using Refresh Register (R) === |
+ | |||
+ | Code courtesy from Singaja, this seems to produce a more random effect. | ||
+ | |||
+ | '''Input:''' ''none'' | ||
+ | |||
+ | '''Output:''' seed = ''a pseudo random number, period 256'' | ||
+ | |||
+ | <pre> | ||
+ | ;-----> Generate a random number | ||
+ | ; ouput a=answer 0<=a<=255 | ||
+ | ld hl,(seed_ion) | ||
+ | ld a,r | ||
+ | ld d,a | ||
+ | ld e,a | ||
+ | add hl,de | ||
+ | xor l | ||
+ | add a | ||
+ | xor h | ||
+ | ld l,a | ||
+ | ld (seed_ion),hl | ||
+ | ret | ||
+ | seed_ion: .dw 0x0 | ||
+ | </pre> | ||
+ | |||
+ | === 16-bit random number generator === | ||
This algorithm uses a similar method, but returns much better results. | This algorithm uses a similar method, but returns much better results. | ||
Line 86: | Line 130: | ||
ret | ret | ||
</pre> | </pre> | ||
+ | |||
+ | === 16-bit random number generator using the R register === | ||
+ | |||
+ | A pseudo random generator using the R register for the first byte of the random number. It then uses this number as a seed to feed the 8-bit random number generator to generate the other byte of the random value. | ||
+ | |||
+ | '''Input:''' ''none'' | ||
+ | |||
+ | '''Output:''' HL = ''a pseudo random number, period 65536'' | ||
+ | |||
+ | <pre> | ||
+ | Rand16 ld a,r | ||
+ | ld h,a | ||
+ | |||
+ | Rand8 ld b,a | ||
+ | add a,a | ||
+ | add a,a | ||
+ | add a,b | ||
+ | inc a | ||
+ | ld (Rand8 + 1),a | ||
+ | |||
+ | ld l,a ; HL now contains a random 16-bit number | ||
+ | ret | ||
+ | </pre> | ||
+ | |||
+ | [[Category:Programming]] |
Latest revision as of 16:11, 8 January 2016
Contents
BASIC
The BASIC command RANDOMIZE TIME can be used to generate random numbers, using the value of the TIME variable as a seed. The TIME variable is incremented every 1/300th of a second, so it is highly unlikely that the same set of numbers will be generated each time the BASIC program is run.
However, after about five or six numbers are obtained using the RND command, the randomness of the numbers decreases dramatically. The listing below demonstrates this problem:
10 MODE 2 20 FOR a=1 TO 23 30 RANDOMIZE TIME 40 FOR b=1 TO 25 50 PRINT USING("## ");INT(RND*100); 60 NEXT b 70 PRINT 80 NEXT a
This problem can be overcome by using the commands RANDOMIZE TIME:RANDOMIZE RND instead. This re-initialises the random number seed and greatly improves the randomness of the numbers that are obtained using the RND command.
Machine code
8-bit random number generator
This is a very simple generator. Its function is x[i + 1] = (5 * x[i] + 1) mod 256. The only advantage is the small size and its simplicity.
Input: none
Output: A = a pseudo random number, period 256
Rand8 ld a,Seed ; Seed is usually 0 ld b,a add a,a add a,a add a,b inc a ; another possibility is ADD A,7 ld (Rand8+1),a ret
8-bit random number generator (lookup table based)
To use this routine you need to define 1 byte of RAM for the RandomPtr.
Input: none
Output: A = a pseudo random number, period 256
RandomNumber: push hl ld a,(RandomPtr) inc a ld (RandomPtr),a ld hl,RandTable add a,l ld l,a jr nc,skip inc h .skip: ld a,(hl) pop hl ret RandTable: db &3B,&02,&B7,&6B,&08,&74,&1A,&5D,&21,&99,&95,&66,&D5,&59,&05,&42 db &F8,&03,&0F,&53,&7D,&8F,&57,&FB,&48,&26,&F2,&4A,&3D,&E4,&1D,&D9 db &9D,&DC,&2F,&F5,&92,&5C,&CC,&00,&73,&15,&BF,&B1,&BB,&EB,&9E,&2E db &32,&FC,&4B,&CD,&A7,&E6,&C2,&10,&11,&80,&52,&B2,&DA,&77,&4F,&EC db &13,&54,&64,&ED,&94,&8C,&C6,&9A,&19,&9F,&75,&FA,&AA,&8D,&FE,&91 db &01,&23,&07,&C1,&40,&18,&51,&76,&3C,&BD,&2A,&88,&2D,&F1,&8A,&72 db &F6,&98,&35,&97,&68,&93,&B3,&0C,&82,&4E,&CB,&39,&D8,&5F,&C7,&D4 db &CE,&AE,&6D,&A3,&7C,&6A,&B8,&A6,&6F,&5E,&E5,&1B,&F4,&B5,&3A,&14 db &78,&FD,&D0,&7A,&47,&2C,&A8,&1E,&EA,&2B,&9C,&86,&83,&E1,&7B,&71 db &F0,&FF,&D1,&C3,&DB,&0E,&46,&1C,&C9,&16,&61,&55,&AD,&36,&81,&F3 db &DF,&43,&C5,&B4,&AF,&79,&7F,&AC,&F9,&37,&E7,&0A,&22,&D3,&A0,&5A db &06,&17,&EF,&67,&60,&87,&20,&56,&45,&D7,&6E,&58,&A9,&B0,&62,&BA db &E3,&0D,&25,&09,&DE,&44,&49,&69,&9B,&65,&B9,&E0,&41,&A4,&6C,&CF db &A1,&31,&D6,&29,&A2,&3F,&E2,&96,&34,&EE,&DD,&C0,&CA,&63,&33,&5B db &70,&27,&F7,&1F,&BE,&12,&B6,&50,&BC,&4D,&28,&C8,&84,&30,&A5,&4C db &AB,&E9,&8E,&E8,&7E,&C4,&89,&8B,&0B,&24,&85,&3E,&38,&04,&D2,&90
8-bit random number generator using Refresh Register (R)
Code courtesy from Singaja, this seems to produce a more random effect.
Input: none
Output: seed = a pseudo random number, period 256
;-----> Generate a random number ; ouput a=answer 0<=a<=255 ld hl,(seed_ion) ld a,r ld d,a ld e,a add hl,de xor l add a xor h ld l,a ld (seed_ion),hl ret seed_ion: .dw 0x0
16-bit random number generator
This algorithm uses a similar method, but returns much better results.
Input: none
Output: A = a pseudo random number, period 65536
Rand16 ld de,Seed ; Seed is usually 0 ld a,d ld h,e ld l,253 or a sbc hl,de sbc a,0 sbc hl,de ld d,0 sbc a,d ld e,a sbc hl,de jr nc,Rand inc hl Rand ld (Rand16+1),hl ret
16-bit random number generator using the R register
A pseudo random generator using the R register for the first byte of the random number. It then uses this number as a seed to feed the 8-bit random number generator to generate the other byte of the random value.
Input: none
Output: HL = a pseudo random number, period 65536
Rand16 ld a,r ld h,a Rand8 ld b,a add a,a add a,a add a,b inc a ld (Rand8 + 1),a ld l,a ; HL now contains a random 16-bit number ret