Page 1 of 1

[TI ASM] Random Numbers

Posted: Wed 14 Jun, 2006 2:02 am
by thegamefreak0134
I feel really stupid for having to post about this, but I can't find a simple solution. I need to be able to generate random numbers for a program. For this particular one, they need to be from 1 to <7 to 10>. How is random number generation done in asm? Is there a romcall I can use to use the built-in rand function? I'm sorry about asking, but my current docs are rather limiting and on dial-up it's much faster to simply ask.

-thegamefreak

Posted: Wed 14 Jun, 2006 2:31 am
by Jim e
This is from ION. Modified though because at the cost of 7 bytes we could potentially save thousands of clocks while still maintaining relocatability.

Code: Select all

;Fast random
;input:
;b = max random size
;out:
;a = random_vaule that is ( b > a >= 0 )

random:
	push hl
	push de
	ld hl,(randData)
	ld a,r
	ld d,a
	ld e,(hl)
	add hl,de
	add a,l
	xor h
	ld (randData),hl
	ld h,a
	ld l,0
	ld e,b          ;Hmmmm...
	ld d,l          ;Is it faster to have a put in to hl or a put into de?
	ld b,8          ;Statistically that is.
randomLoop:
	add hl,hl
	jr nc,skipmultrand
	add	hl,de
skipmultrand:
	djnz randomLoop
	ld a,h
	pop de
	pop hl
	ret
What this basically does is it takes a seed given in randData, and the timing register R, and a value from the memory and it creates a random value. Then multiplies so you can have it in a range.

Posted: Wed 14 Jun, 2006 10:47 am
by tr1p1ea
Nice stuff. I also like the random routine from Venus ... as well as the rest of that shell :).

What will you be using this for thegamefreak0134? A certain jewel themed game? :).

Posted: Wed 14 Jun, 2006 2:32 pm
by Liazon
Jim e wrote: What this basically does is it takes a seed given in randData, and the timing register R, and a value from the memory and it creates a random value. Then multiplies so you can have it in a range.
So that's what R is for. I always thought it was weird that a processor would have a register that worked kinda funky compared to a regular register.

Posted: Wed 14 Jun, 2006 3:35 pm
by benryves
R is the built-in dynamic memory refresh register, for use with dynamic memory (it's a hardware thing). 7 bits of it increment after every instruction fetch (well, near enough), making it a useful random number generator seed.

Posted: Wed 14 Jun, 2006 5:12 pm
by Liazon
how come you just can't directly take the seed for a random #?

Posted: Wed 14 Jun, 2006 5:31 pm
by Jim e
Because you need to provide the seed, so it can't be consider random.

If you actually use this routine quite a bit, you'll see its not very random at all. Patterns may show after a while. However if you only need it to intialize some things than its suitable.

There are other things that can be used to help increase randomness. For example gb would use the title screen + user input to set the seed.

Posted: Wed 14 Jun, 2006 6:06 pm
by NanoWar
What is gb?

Posted: Wed 14 Jun, 2006 8:36 pm
by Kalimero
ionRandom isn't very good because the quality of its output is unpredictable. It uses the R register and the memory contents. The R register isn't really random, sometimes it is, sometimes it isn't and that depends on how you've organised your code. The same goes for the memory contents. There isn't a whole lot of randomness in there. So, ionRandom may work quite well sometimes and sometimes it may not. It's a lot better to use a simple formula of which you can be sure it always works no matter what the state of the calc is.

For example the simple formula "seed=9*seed+5 mod 32" produces the following sequence: 0 5 18 7 4 9 22 11 8 13 26 15 12 17 30 19 16 21 2 23 20 25 6 27 24 29 10 31 28 1 14 3 (0 5 18 7...). This is just an example of how simple formulas (linear congruential pseudo random number generators) can shuffle numbers. Don't use it. Practically it's a bad generator because its period is way too short.

The routine tr1p1ea refers to is http://baze.au.com/misc/z80bits.html#4.2. That's still a bad generator but it's sufficient for calc games (except maybe poker games).

If you really want a good generator you can look into combining multiple LCRNGs (the OS combines 3 I believe). Or maybe somebody can port the Mersenne Twister generator (http://www-personal.engin.umich.edu/~wa ... ister.html) [8^P.

Posted: Thu 15 Jun, 2006 3:30 am
by Dwedit
There is only one true source of randomness: The user, or specifically, how long the user holds down the keys. Since you can poll the keyboard at such high rates and get microsecond level information on how long a key was held down, even a short key tap can produce quite different results each time.

Posted: Thu 15 Jun, 2006 10:32 pm
by thegamefreak0134
I do intend to use it for the "jewel themed game", yes. I haven't actually done an asm program requiring randomness yet.

I will go ahead and use this routine for now and see how well it works out. Considering that I need it for smaller numbers and such, it should be fine. Not to mention that I have the luxary of being able to call it every "frame" and thus get random jewel generation based on how long the player takes to make a move. Thanks a bunch!

-thegamefreak

Posted: Thu 15 Jun, 2006 10:52 pm
by CompWiz
I just noticed that someone just released a Multiply with Carry random number generator at ticalc.org. According to them, it is great for finding very random numbers. I don't know much about it, and it is in basic, so take a look at it if you want. However, the one you are planning to use looks good enough for what you want to do. :)