Difference between revisions of "Programming:Random Number Generator"

From CPCWiki - THE Amstrad CPC encyclopedia!
Jump to: navigation, search
(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:
== 8-bit Random Number Generator ==
+
== BASIC ==
  
This is a very simple generator. It's function is x[i + 1] = (5 * x[i] + 1) mod 256. The only advantage is the small size and it's simplicity.
+
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 Random Number Generator - lookup table based ==
+
=== 8-bit random number generator (lookup table based) ===
  
To use this routine you need to define 1 Byte of RAM for the ''RandomPtr''.
+
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,.skip
+
         jr      nc,skip
 
         inc    h
 
         inc    h
 
.skip:  ld      a,(hl)
 
.skip:  ld      a,(hl)
Line 60: Line 79:
 
</pre>
 
</pre>
  
== 16-bit Random Number Generator ==
+
=== 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

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