Random Numbers
Why they aren’t and shouldn’t be

Many people don’t really realize that a computer is not capable of generating truly random numbers without outside input.  Other people think that computers can do anything and generating random numbers is pretty low on the list if you are omnipotent. 

Both sets of people are sort of right and wrong.  You can get truly random numbers from a computer, but not in the traditional sense of just having the computer generate them.  And the random numbers that computers generate usually aren’t random at all.  It’s very important to game programmers to understand the differences, and use the one they really need. 

First let’s cover generating random number using a random number generator. 

The random number functions of most, if not all, compilers have a function for seeding it.  Based on what this seed is the random number function will return a sequence of numbers that appears random at first, and actually have a fairly even, yet "random" distribution.  But if you give the same seed number twice in a row, you will get the same sequence of "random" numbers.  Here’s an example: 

(This program was written and tested under Microsoft Visual C++ v4.2 (MSVC4.2), your results may vary, but be similar). 

#include "stdlib.h"
#include "stdio.h"

void main()
{
    srand(1);
    for(int i=0; i<10; i++)
    {
        printf("%d\t",rand());
    }
    printf("\n");
}

If you compile and run this program under MSVC4.2 you’ll get the following results: 

41      18467   6334    26500   19169   15724   11478   29358   26962   24464 

Not just once, but every time you run it.  This is because the srand() function is seeding the random number generator with a constant.  If you change the 1 to a 2, you get the following results: 

45      29216   24198   17795   29484   19650   14590   26431   10705   18316 

Now a lot of people may run away screaming at the fact that they can’t get random numbers.  But a number is usually random enough if the user can’t predict what the next value will be.  Taken the above 2 lists, and given any number in the list, what is the likely hood of someone figuring out what the next number will be.  It is possible for a mathematician to do this, but usually in games they don’t actually get the results of the random numbers, they just see it’s effect. 

If you want a sequence of random numbers that is different every time, then use a different seed every time.  The most obvious and easy to use seed for this kind of activity is the clock.  If you use the internal clock as the seed for your random numbers, it’s usually random enough.  Take this example: 

#include "stdlib.h"
#include "stdio.h"
#include "clock.h"

void main()
{
    srand(time());
    for(int i=0; i<10; i++)
    {
        printf("%d\t",rand());
    }
    printf("\n");
}

I ran this program three times with the following results: 

14565   16390   5546    8855    9584    26233   13138   5847    24653   29008 
14568   27138   23411   150     19898   30160   16251   2919    8396    22860 
14686   20865   11161   14462   30775   7682    29995   28609   12989   30906 

Notice that the results are fairly unpredictable.  However, notice that the first number is very close.  This is because the more "random" numbers you generate, the further from the seed they get.  It’s always a good idea to generate a 100 or so numbers and just toss them.  The numbers you get after that will be much more "random". 

As a game programmer you can use this predictability to your advantage.  There was an old game called Rescue on Fractalus.  I don’t know what algorithm they used for this.  But, they had several hundred levels.  Each level was unique.  But they were so big that there was no way they could have been pre-generated and stored on the disk (this was back in 140KB floppy days).  So the levels were "randomly" generated.  But even though they were "random" every time you went to the same level, the map was exactly the same.  This allowed them to have several hundred if not thousand unique levels, but each time you visited a level it stayed the same. 

However, as a game programmer this can be detrimental as well.  You don’t want to use random numbers for your creature AI and have the users get to the point where they can say, "Now the big green guy is going to go left, then right, then fire."  Unless you planned it that way of course.  Remember Pac-Man?  Remember how you could learn patterns to run through the levels?  That was because Pac-Man used the same random seed for it’s ghost AI every time.  The levels were different because the ghosts moved faster, and that changed how the random numbers were used.  But at some point it peaked out, and if you knew that pattern then you could play for as long as you wanted.  I know, I did. 

But there are some games that you truly want to be completely and totally random, like gambling games that actually involve money (there are laws that govern that sort of thing you know). 

So now we’ll discuss making things truly random. 

There are a lot of things that happen in a computer that happen at random.  And I mean truly at random as opposed to what we were discussing above.  If you need truly random numbers for an application, you can get them.  But not in very large quantities. 

One of the easiest ways of getting a few random numbers is ask the user to type their name, and any other textual information.  Then time the amount of time between keystrokes and use this as the number.  It’s best to use a high speed timer for this, the standard PC timer is only accurate to 1/18th of second.  You can reprogram that, but that’s beyond the scope of this article. 

Another way to do it, is have the user use the mouse or joystick to control something on screen and keep track of how they move it.  For example; if you want a slot machine simulation, make the user pull the handle of the slot machine with the mouse.  Have them put the mouse over the handle, hold down the button and drag it down.  If you keep track of all the X and Y positions of the mouse during this journey, you can be fairly certain that those numbers won’t be the same twice.  However, don’t use the numbers as you get them, because they will be in a consistent downward direction with very little change on the X axis.  But if you use that number as a seed, for the random number generator, and then take the Nth number generated, you’ll have a fairly good random number. 

I did say to take only one number, because if you just use that for the seed, then use the standard random number generator, it will still be a sequence.  This may be good enough, but not in all cases.  Given that it’s a game in question, then the users input is the most random event you can possibly get.  And if you use that knowledge to encourage them to be even more random (without telling them of course), then you can probably generate as many truly random numbers as you want. 



Home

Last revised:  January 17, 1998