// generates random number
int get_random(int lo, int hi)
{
return (rand() % (hi-lo+1)) + lo ;
}
but this does not randomize anything... I tested my beginning of my game several times and it occured to me that i played it the same over and over again so i looked why and i saw that everytime i played the game the randomizer gave the same numbers in order everytime so i could predict the outcome of it. Why is this? is there something wrong with the code? is there better code for this?
There is probably a better solution than this, but alas this is the solution I used and it did/does work.
I created the following function:
void InitRandomNumberGen()
{
int x;
struct timeval cTime;
gettimeofday(&cTime, 0);
int seed = cTime.tv_sec % 256;
for (x=0; x < seed; x++)
rand();
}
Call this function 1 time near the start of your program. It will get the system times and modulo it to get a number between 0 and 255. Then it calls the random number generator that many times. This will ensure the first random number actually used in your program is not the same random number allways returned first by the rand() function.
As you probably figured out, the random number generator allways produces the same random numbers. Doesn't sound very random but that's the way it usually works. I think normally a seed function that uses the system time (such as the one I mention above) is included in the random number function. I was suprised the one in the PSP lib did not plant a seed based on system time for you. But if you do it yourself as described above, you will get the results you are looking for.
->Garak. That will give 256 different start points, which is better, but not as good as calling
srand(time(NULL));
which gives RAND_MAX+1 starting points.
Jim
Thats even hotter, Garak ;) (Mt19937 = Mersenne twister)
It gives "better" random numbers, and it's faster (should be - didn't test on PSP - but my PS2 version is).
If i am correct the function Raphael gave me was the best one right?
So it gives a number between? i mean i only have to get a 1 or a 2 randomized. like a boolean value :)
/**
* Function to return a new psuedo random number.
*
* @param ctx - Pointer to a pre-initialised context.
* @return A pseudo random number (between 0 and MAX_INT).
*/
u32 sceKernelUtilsMt19937UInt(SceKernelUtilsMt19937Context *ctx);
So the function returns a complete random value inside the u32 valuespace.
So you could just use your get_random function and replace the rand() with the mersenne twister function and it would work perfectly. Just make the context global and initialise it at the start of your program.
Or in your special case, you'd just append
SceKernelUtilsMt19937Context ctx;
int RandomInit(void) {
sceKernelUtilsMt19937Init(&ctx, time(NULL));
return 0;
}
// generates random number
int get_random(int lo, int hi)
{
u32 rand_val = sceKernelUtilsMt19937UInt(&ctx);
rand_val = 1 + rand_val % 2;
return (int)rand_val;
}
however rand_val is always empty :S i have sprintf the randval with %i to an char array and displayed it on screen but it was always empty. So according to that it didn't work.
however i use it in my program and for my blocks the randomness works, however when i output the get_random to a char array and display it also the ones that work on my blocks don't show anything. How can this be?
you are right that it only gives the number between 1 en 2 but the returned value or the rand_val inside the function(see above) doesn't seem to hold any information i can use or store in an integer, what am i seeing wrong?
You need to be a little more specific with the way you're drawing text & what sBuffer is.
Please post the code that calls the get_random() function and we can help you figure out whats wrong, because the get_random() function looks correct to me.
Hrmm, well I guess the get_random function is correct but if you are going to use it like it is defined you may want to replace the 1 and 2 with lo and hi. Like this
// generates random number
int get_random(int lo, int hi)
{
return (rand() % (hi-lo+1)) + lo ;
}
but this does not randomize anything... I tested my beginning of my game several times and it occured to me that i played it the same over and over again so i looked why and i saw that everytime i played the game the randomizer gave the same numbers in order everytime so i could predict the outcome of it. Why is this? is there something wrong with the code? is there better code for this?
any comments are welcome.
seems you haven't initialized the generator
you have to use srand() somewhere to initialize it.
Is there a floating point random number generator in the psp sdk? (you know like on windows, where it returns between 0 and 1 and you just scale it into range yourself)
Every 624 calls to mtrand, it has to go off and update the RNG's state, which is 624 32bit integers. The code for doing a single mtrandom number is normally just a handful of xors, shifts and ands.
The C99 standard recommends this implementation for rand()
static unsigned long int next = 1;
int rand(void) // RAND_MAX assumed to be 32767
{
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}
which is just one mul, one shift, one add and one and. Many C runtimes use this exact algorithm.
So what you'll find is mtrand performance will be 'lumpy' compared with rand. Do you really need mtrand? You'd traditionally want that only if you were doing specific statistical analysis.
Jim
Last edited by Jim on Sat Aug 12, 2006 11:24 am, edited 1 time in total.
Jim wrote:Every 624 calls to mtrand, it has to go off and update the rng's state, which is 624 32bit integers. The code for doing a single mtrandom number is normally just a handful of xors, shifts and ands.
The C99 standard recommends this implementation for rand()
static unsigned long int next = 1;
int rand(void) // RAND_MAX assumed to be 32767
{
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}
which is just one mul, one shift and one and. Many C runtimes use this exactly algorithm.
So what you'll find is mtrand performance will be 'lumpy' compared with rand. Do you really need mtrand? You'd traditionally want that only if you were doing specific statistical analysys.
Jim
Reasonable. I doubt that this implementation has a near-equal distribution over the int range (won't prove that mathematically though here :P). So if you use it for something where every random number should have same probability, it's bad (dice anyone?).