Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)
You are not logged in.
I generate a random map with a random number generator. I start srand on the title screen, then after that, I generate a ton of random numbers. Those random numbers are always the same!
Offline
Could you share a code snippet?
Is it possible that you set the random seed in the same loop you generate the random numbers in?
Offline
I set srand(); on the very first line of main().
Offline
If you set it to the same value always, the numbers that will generate rand() will always be the same.
You need to add something like a loop to wait for the user to press and read from register DIV, for example. That's a sort of reasonable unpredictable value, so it can be used as random seed. But only if you wait for the user input!
Offline
I am also wondering about how to get a random number. I searched for DIV on the wiki, but nothing came up.
Offline
I think it is pretty well explained in this blogpost:
http://imrannazar.com/GameBoy-Emulation … pt:-Timers
and partly in the Gameboy CPU manual (http://marc.rawer.de/Gameboy/Docs/GBCPUman.pdf) at page 38.
You have a timer on the gameboy that is incremented 16384 times per second (that's the DIV register you mention). If you extract a value from that register (0xFF04) at random intervals, you basically get a random number. In other words, despite that that counter is not random, your time intervals are and thus you get pseudorandom numbers.
Hope it helps. :-)
Offline
But how would I pull its number out? I'm using C.
I don't know what to call it? 0xFF04? DIV_REG? What?
Offline
I am not really sure when using C; so far I have only programmed Gameboys using assembly, so it is a bit of guess. Sorry for that.
Here goes. In C, you can refer to a memory location using a pointer. The value of that pointer is then equal to the memory address. So to create a pointer to the DIV register, you type:
unsigned char *ptr_div_reg = 0xFF04; // set pointer to memory address
To get the value residing at the memory address of the pointer, you use the dereference operator "*", like so:
unsigned char random_number = *(ptr_div_reg); // get value at memory address
Finally, to get a random number within a certain range from that you could use a modulus. To get a random number between 0 and 5, inclusive (i.e. a dice roll), you could use:
unsigned char dice_roll = random_number % 6;
Offline
If you read from that register twice without enough time in between, you will probably read the same value, so be careful when using it. If you use it once or twice per frame, in different part of the code, you'll be fine. If you want to use it a lot, you'll need other system.
Offline
Indeed, good point. The alternative is to use the DIV register as a seed for a pseudorandom number generator. The only thing is that I'm not sure how computationally expensive the various RNG algorithms are given the GB platform.
Offline
The ideal thing is to wait for user input or something, then read the value and use it as seed. For example, if your game has a title screen, you could read its value after the user closes the screen, or something like that. DIV starts always at the same value, you can't even use it as a seed if srand is called always at the same time in your boot sequence.
Offline
Having trouble again. Trying to get a random number between 10 and 30. Can't do it. I tried this:
poweruptimerlimit = randomthing % 30; poweruptimerlimit=poweruptimerlimit+10
but it won't work. How would I do this?
Offline
Well, `randomthing % 30` will return a number from 0 through 29, and then you're adding 10 to that, so that will give you a range of 10 through 39.
If you want 10 through 30 (including 30), you want: (randomthing % 21) + 10
If you want 10 until 30 (excluding 30), you want: (randomthing % 20) + 10
Last edited by DonaldHays (2017-02-23 12:03:58)
Offline
More trouble.
So (randomthing % 2)+1 should give me a number between 1 and 3, right? But it's always giving me 2 and never 1 nor 3. What's going on?
Offline
(randomthing % 2)+1 should give you either 1 or 2.
If you try to read randomthing only, what kind of value do you obtain? Only odd values?
Offline
This reminds me of an earlier post http://gbdev.gg8.se/forums/viewtopic.php?id=288
I dont know what you did differently that caused it not to produce random negative numbers.
Last edited by MrElephant (2017-03-28 20:18:14)
Offline