Thanks go to Uhfgood in #gamedevelopers for finding the article Using rand(). I thought I already knew about the problems with using rand(). This article was great at clarifying the actual problems people have with using rand() as well as faults with “good” solutions people use. It also documents a simpler way to use rand() that actually produces better results! It turns out that rand() is better than many programmers thought.
For those of you who don’t know, the classic way people are taught to use rand() to get a random number between 0 and maxRange is as follows:
int picked = rand() % maxRange;
The problem with the above is that the value you get in picked will not be as random as it could be. Something about lower order bits repeating too often. So usually the “better” way to solve the problem is through some slightly more complicated code:
int picked = lowerBound + rand() / ( RAND_MAX / ( maxRange - lowerBound ) + 1 );
The article explains that this example also has problems!
So what do you do? Stop fighting rand()! I wasn’t happy with the example given as I don’t understand why simple variables have to be used with simple examples since they only make it more confusing. The following is my own code:
int highest = 100;
int randDivisor = RAND_MAX / highest;
pickedValue = rand() / randDivisor;
while ( pickedValue >= highest );
It may seem like you would waste too many cycles waiting for pickedValue to be within the range you desire, but it really doesn’t take long at all. It is more pseudorandom than the other examples and needs less complex code, too!
The document also explains the problem with the usual code to seed the random number generator:
The problem seems to come from the fact that changes from one time to another aren’t usually enough to change the first randomly generated number. The article explains a way to use time() in a portable manner by hashing the bytes of its return value.
The entire article is a good read, and I believe any game programmer will find it useful.