#6334 - MojoJojo - Fri May 23, 2003 12:44 pm
Just strated playing with GBADev and emulators, (I'll get the hardware when I next get paid ;), and I was wondering how to seed a random number generator. Normally, you'd use the time, but there doesn't seem to be one lying around on the GBA. If you're doing an interactive program, you could use the time to the first keypress, but I'm just doing graphics testing stuff at the moment, and was wondering if there was any thing you can use as a starting seed?
#6339 - phr0zn - Fri May 23, 2003 2:23 pm
Alright. this has been discussed a thousand times before so poke around. but here is an example of how I do it:
Code: |
#define VCOUNT *(volatile u16*)0x4000006
//random max
#define RAND_MAX 32767
volatile s32 RAND_RandomData;
void SeedRandom(void);
s32 RAND(s32 Value);
int main()
{
u16 random_num;
SeedRandom();
random_num = RAND(4);
}
void SeedRandom(void)
{
RAND_RandomData = VCOUNT;
}
s32 RAND(s32 Value)
{
RAND_RandomData *= 20077;
RAND_RandomData += 12345;
return ((((RAND_RandomData >> 16) & RAND_MAX) * Value) >> 15);
}
|
Thats pretty much that. I believe it was used in a TRON demo coded a while ago by somebody. I think thats where I got it. It works fairly well...
_________________
http://cerberus.promodtecnologies.com
#6342 - niltsair - Fri May 23, 2003 3:09 pm
And a way to greatly improve the above, is to wait a keypress before seeding your number. Like after a start screen.
Another smart way i've seen on this forum, if you can't do the above for some reason, you seed the number after certain events in the game, and store it in the gamepak ram. Thus, when you restart your game, you just go fetch that number to reseed.
#6348 - MojoJojo - Fri May 23, 2003 5:21 pm
Ah, sorry, this has been discussed before, thanks for your reply.
0x4000006 is the vertical sync isn't it? Using the gamepaq is a good idea too.
#6377 - Jason Wilkins - Fri May 23, 2003 9:43 pm
It seems to me that seeding at the same point at the beginning of the program would always give you the same number. User input really seems like the best way to seed a random number generator. Anything else seems too deterministic.
Too bad there isn't a bit of radioactive element and a geiger counter in the GBA, that would be truely random ^_^
_________________
http://devkitadv.sourceforge.net
#6378 - niltsair - Fri May 23, 2003 9:48 pm
True, there need to be some User input. Hence the start screen. The second method also worked because it's base on the fact that in order to be at a certain point, the user had to have pressed keys, just remove the obligation of having a start screen. But will also mean the 1st game will always be the same, unless you insert yourself the random seed on the rom before flashing it.
#6384 - sgeos - Fri May 23, 2003 10:20 pm
niltsair wrote: |
But will also mean the 1st game will always be the same, unless you insert yourself the random seed on the rom before flashing it. |
Thats not a very random seed, now is it? After it's flashed, the first screen will always be the same. I'll admit that I usually just seed the RNG with something because I'm too lazy to set up the timers. Often I use:
seed = 0xFDB97531;
-Brendan
#6386 - niltsair - Fri May 23, 2003 10:33 pm
True, but i was thinking about it in a consumer way, where the gamer will always play with the same cart.
I usually go for the : Let's wait untill the player pressed start with an Intro Screen method, using a timer value too.
#19034 - rlaxogns - Sat Apr 10, 2004 2:15 pm
Hello all...I'm a newbie in GBA programming....
I need a true random number generator...The code provided only
generates the same numbers all the time....
Can someone post example code for real random number generator, please?
I would really appreciate it ... Thank you....
phr0zn wrote: |
Alright. this has been discussed a thousand times before so poke around. but here is an example of how I do it:
Code: |
#define VCOUNT *(volatile u16*)0x4000006
//random max
#define RAND_MAX 32767
volatile s32 RAND_RandomData;
void SeedRandom(void);
s32 RAND(s32 Value);
int main()
{
u16 random_num;
SeedRandom();
random_num = RAND(4);
}
void SeedRandom(void)
{
RAND_RandomData = VCOUNT;
}
s32 RAND(s32 Value)
{
RAND_RandomData *= 20077;
RAND_RandomData += 12345;
return ((((RAND_RandomData >> 16) & RAND_MAX) * Value) >> 15);
}
|
Thats pretty much that. I believe it was used in a TRON demo coded a while ago by somebody. I think thats where I got it. It works fairly well... |
_________________
-THK-
#19037 - Lupin - Sat Apr 10, 2004 3:19 pm
When you show the start screen, use a timer to find out a random time value when the user hits a button. That will definately give you a "true" random value.
_________________
Team Pokeme
My blog and PM ASM tutorials
#19038 - yaustar - Sat Apr 10, 2004 3:20 pm
technically, there is no 'true' random generator in any program.. you can make it seem more random and varied at best.
_________________
[Blog] [Portfolio]
#19056 - sgeos - Sat Apr 10, 2004 8:36 pm
Jason Wilkins wrote: |
It seems to me that seeding at the same point at the beginning of the program would always give you the same number. User input really seems like the best way to seed a random number generator. Anything else seems too deterministic. |
The board game 1830 has no random component. Every game turns out very different, and things are very hard if not impossible to predict.
If you seed your rng with 0x13579BDF at the start of every new game, and use the SRAM method mentioned above, I suspect that the game would turn out to be very hard if not impossible to predict. =)
You could also use code like this:
Code: |
seed = fetch_seed_from_sram();
if (seed == 0)
seed = 0x13579BDF;
|
-Brendan