| |
|
|
||||
![]() |
||||||
| |
|
|||||
|
Predictably Random Numbers The key to producing the effect of an infinite game universe is the ability to produce an endless variation in the principle game elements. This could be quite easily arranged, simply by generating a random number sequence using the current date and time of the host computer as the starting point (or seed). Thus, when continually played, events would unfold in a random manner, providing an infinite universe in which to play. This approach suffers from two drawbacks. The first is that no two games would ever be the same. Not just in terms of the game play itself, but also key features of the universe would change, such as the initial placement of objects (such as stars and planets), or sequences of events. The second drawback stems from the first - it would be impossible for two players to share their experiences, since they would inhabit two completely different game universes. They would not be able to swap tips, such as "if you go to the third planet from sun x, be aware that you will be attacked," nor strategies for survival, since one strategy that works in one universe would not work in the other. Therefore, we need to have a situation in which we can generate a sequence of random numbers repeatedly. The randomness gives us the power to create an infinite game universe, while the repeatability enables us to ensure that, at least in the beginning, two instances of the same universe will look the same. Such sequences of numbers are known as pseudo-random, simply because they can be repeated. The basic algorithm is as follows:
This may look daunting, but it is very simple to implement, as the code in Listing 1 shows. There are, however, a few points that should be noted. The first is that the sequence will repeat itself after Max iterations. The second is that the choice of Gen1 and Gen2 have a direct effect on the sequence of numbers, as does the seed. Gen1 and Gen2 must be much larger than Max for a satisfactory absence of pattern. In fact, the pattern breaking is done by Gen2; indeed, a simple multiplication followed by a division yields a sequence of numbers with a strong pattern, and Gen2 serves to remove that pattern to a certain extent. There is one final limitation. The largest number that can be generated using this system is 4,294,967,295. It follows from the algorithmic description above that the sequence will begin to repeat itself after the 4,294,967,295th iteration. This is a limitation of the data type used, a 32-bit unsigned integer. If greater numbers are required, it is necessary to move to a different representation. Creating the Universe: an Example With our pseudo-random number generator in place, we can now begin to build our universe. In the manner of all good game examples, this will be represented by a black backdrop upon which we will place a scattering of stars. In this example, we are just going to let the chips fall where they may, and not worry about whether the generated universe adheres to the physical laws of universe creation. We shall see later how to incorporate limitations into the generation of universe features. For now, however, we will simply apply our pseudo-random number generation algorithm. Listing 2 shows the implementation for the PseudoRandomizer class. The code in Listing 3 implements the Universe class. As can be seen, the dimensions of the required universe are used to provide values for Gen1 and Gen2, the two modifiers from the PseudoRandomizer class. In this way, we are sure that the sequence of numbers resulting from the given seed will not change from instance to instance. Use of the Universe class is very simple. The initialization code simply sets up the randomizer, and stores the dimensions of the universe. If we wish to know whether there is a star at a given point, we call the StarAt class member. This will then generate a unique "serial number" value for the given grid reference, and call the randomizer that number of times. The resulting value is then used to decide whether a star is present or not. If a star is present, a value that is greater than 99 percent of the total area will be indicated. Incidentally, the area of the universe is used to determine the maximum value returned by PseudoRandomizer. The discerning reader will have noticed by now that universes generated in this way cannot be truly random, as the dimensions must be given beforehand. In fact, due to the limitations of our randomizer routine, each universe may only be 65,535 by 65,535 units in size (the square root of the maximum possible generated random number). Thus, this system lacks Macro-Infinite Resolution. However, if we populate 1 percent of the total area with game elements (stars, in this example), there will be 42,948,362 of them, which is enough to give a reasonable illusion of infinity.
|
|
|