It's free to join Gamasutra!|Have a question? Want to know who runs this site? Here you go.|Targeting the game development market with your product or service? Get info on advertising here.||For altering your contact information or changing email subscription preferences.
Registered members can log in here.Back to the home page.

Search articles, jobs, buyers guide, and more.

By Guy W. Lecky-Thompson
Gamasutra
September 17, 1999

Letters to the Editor:
Write a letter
View all letters


Features

 

Contents

Introduction

Predictably Random Numbers

Name Generation Techniques

Generating Random Terrain

Plot Sequencing

Code Listings

Listing 1

Listing 2

Listing 3

Listing 4

Listing 5

Name Generation Techniques

In order to see how the PseudoRandomizer class may be employed to give characteristics to a particular game element, we shall now turn our attention to naming each of the stars in the universe. There are a myriad of techniques for doing this, but one of the most popular is known as the Markovian List (see also A.K. Dewdney, The Tinkertoy Computer, W.H. Freeman: 1990). In essence, this involves examining the frequency of repeated elements in a given number of sequences, and using this as a basis for generating new sequences. The sequences in the case of names are built up of letters.

Before creating actual names, we need to build up a table in which the frequency of adjacent letters in a list of sample names can be stored. This table must be 26 by 26 in order to store all the letters in the alphabet. We can then examine each word in a given list, and determine the frequency of adjacent letters in each word. The cumulative frequencies are stored in the table. For example, if the word is:

‘Nicole’

Then the adjacent letter couples are:

‘ni’ ‘ic’ ‘co’ ‘ol’ ‘le’

So, for this word, we would add one to the value stored in the column referenced by ‘n’ and ‘i’, and one to the value stored in the column (i,c), and so on for each couple. Applying the same technique to every word in the list results in a table which represents the frequencies of all letter couples.

Listing 4 shows the core algorithm for generating such a table. The table used in this listing is actually 28 by 28 in size, so that we can identify those letters which may end or begin a name.

It should be noted that this technique is not constrained by language; that is, any language will work equally well, and for those languages that are based on the Roman Alphabet (accents excluded), the algorithm can be applied as is, with no further modifications.

Once the table has been built, it can then be used to build new words at random. The first step is to determine the length of the desired word. Next, we must ascertain the first letter. This is done by adding up all the frequencies of those letters which can appear at the beginning of a word (that is, the frequencies of the letter couples in the first row of the table). Then, we choose a number at random between 1 and the sum of all the frequencies. The final step in choosing the letter is to start at the first column, and check to see if the chosen value falls between 1 and the stored value. If not, each column is examined in turn, by adding the value stored there and checking to see if this exceeds the random value. Once we find a column in which this is the case, we have found our starting letter.

The above algorithm yields a letter that can be preceded by a space character. The exact same technique can be applied on the following letter, but this time we use the row referenced by the letter that was chosen to begin the word. Then, for each letter that we require in the word, the same steps can be taken in turn until we have filled each available position. The code in Listing 5 shows the algorithm for doing this.

So, in order to generate a name for each of our stars, all we need to do is seed the PseudoRandomizer based on the unique position of the star (based on the grid reference), and let it produce a stream of random numbers which will provide the basis for choosing each letter in the word. Since we are guaranteed the same sequence of numbers for every seed value, all we need store is the frequency table. In addition, since the frequency table is derived from a list of real world words, each name will also "sound" natural.

Using this technique applied to the text of this article, I generated the frequency table in Figure 1. Applying the name generation algorithm produced the sequence of twenty names in Figure 2. At this point it is worth calculating where the storage "break even" point is.

_ a b c d e f g h i j k l m n o p q r s t u v w x y z _
_ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
a 410 2 29 101 8 117 17 62 154 17 3 1 102 60 41 8 21 3 146 22 87 30 35 13 22 0 1 0
b 192 37 2 0 0 0 0 0 1 6 0 0 0 40 0 10 1 0 5 0 0 4 0 2 0 0 0 0
c 187 116 0 7 0 64 0 0 0 89 0 0 6 0 81 12 0 0 3 10 6 20 0 0 3 0 0 0
d 89 20 0 1 4 38 0 1 1 32 0 1 6 0 61 19 0 0 19 0 0 21 0 1 0 1 0 0
e 148 0 80 51 81 49 31 64 111 38 10 21 99 96 111 2 26 0 201 164 159 57 120 24 0 23 10 0
f 139 7 0 0 3 31 15 0 0 15 0 0 4 0 16 2 0 0 3 1 0 4 0 0 0 0 0 0
g 152 17 0 0 2 14 0 1 0 26 0 0 24 0 18 3 0 0 11 0 0 7 0 0 0 0 0 0
h 66 0 0 66 1 1 0 12 0 1 0 0 0 0 2 1 7 0 0 25 651 0 0 49 0 0 0 0
i 356 27 15 28 44 15 48 37 116 0 0 4 66 55 102 21 5 0 93 91 176 18 22 61 5 5 0 0
j 3 1 10 0 3 0 0 0 0 0 0 0 2 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0
k 16 9 0 8 0 0 0 0 0 3 0 0 0 0 1 0 0 0 3 1 0 0 0 0 0 0 0 0
l 98 130 30 13 1 58 2 1 0 55 0 0 40 0 10 27 113 0 6 3 7 57 0 1 0 2 0 0
m 110 114 0 0 0 50 0 0 18 53 0 0 2 2 1 45 1 0 22 2 0 49 0 0 0 0 0 0
n 123 171 0 0 1 206 0 5 17 262 0 7 0 2 8 104 0 0 14 0 0 75 0 2 0 0 0 0
o 310 2 11 60 69 1 72 27 57 90 2 1 34 44 49 34 49 0 49 25 45 0 2 35 0 3 7 0
p 156 30 0 0 0 13 0 0 0 7 0 0 2 51 0 11 17 0 1 17 0 9 0 0 5 8 0 0
q 4 0 0 0 0 48 0 0 0 23 0 0 0 0 0 0 0 0 0 9 0 0 0 0 0 0 0 0
r 120 130 6 20 8 260 28 19 2 27 0 0 1 0 2 137 29 0 14 0 32 54 0 1 0 1 0 0
s 278 60 1 1 5 81 0 1 1 63 0 1 9 4 34 42 21 0 73 22 23 62 0 2 0 10 0 0
t 814 149 0 49 0 76 5 1 3 133 0 0 11 0 86 30 4 0 24 123 36 19 0 0 6 3 0 0
u 107 9 17 17 8 17 8 13 8 0 3 0 44 17 39 75 15 84 8 41 39 0 0 0 0 0 0 0
v 37 30 0 0 1 38 0 0 0 85 0 0 2 0 5 17 0 0 3 0 0 0 0 0 0 0 0 0
w 228 5 0 0 0 2 0 0 0 0 0 0 0 0 0 28 0 0 1 1 17 0 0 0 0 0 0 0
x 2 5 0 0 0 40 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
y 6 29 3 1 0 6 1 0 1 0 0 1 10 1 0 3 0 0 4 6 13 0 0 0 0 0 0 0
z 6 1 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 _
0 105 1 13 266 1028 197 99 118 0 0 14 96 69 384 173 12 6 205 452 309 2 0 25 4 159 0 0

Figure 1. Frequency table generated using the Pseudorandomizer technique.

 

amiteq
sive
ntim
talaca thinct
wolyin
five
ceeriqu
fran
onddef
itha
vathmp
winca
frri
averon
peminci
crelame
frotim
foonl
domict
Figure 2. A series of 20 names generated by the name generation algorithm.

The table will occupy (28x28)x2 bytes of memory, if we assume each value to be a 16-bit floating point number. This means that (code excluded) we are using 1,568 bytes of storage space. This could equally well hold the actual names of the stars, in which case we could store 261 names instead (assuming each is 6 characters long).

So, if we need only to store 261 names for our universe, then it is more efficient simply to store them directly. Using our universe model, this would mean that the universe dimensions would be 161 by 161 units (since only 1 percent can be occupied, and we only have space for 261 stars), or about 0.2 percent of the algorithmic capacity, based on a maximum universe dimension of 65,535 x 65,535.

 

 

 

 

 

 


 

Generating Random Terrain


join | contact us | advertise | write | my profile
news | features | companies | jobs | resumes | education | product guide | projects | store



Copyright © 2003 CMP Media LLC

privacy policy
| terms of service