Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
random.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : Command & Conquer *
24 * *
25 * $Archive:: /VSS_Sync/wwlib/random.cpp $*
26 * *
27 * $Author:: Vss_sync $*
28 * *
29 * $Modtime:: 8/29/01 10:24p $*
30 * *
31 * $Revision:: 2 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * RandomClass::RandomClass -- Constructor for the random number class. *
36 * RandomClass::operator() -- Fetches the next random number in the sequence. *
37 * RandomClass::operator() -- Ranged random number generator. *
38 * Random2Class::Random2Class -- Constructor for the random class. *
39 * Random2Class::operator -- Generates a random number between two values. *
40 * Random2Class::operator -- Randomizer function that returns value. *
41 * Random3Class::Random3Class -- Initializer for the random number generator. *
42 * Random3Class::operator -- Generates a random number between two values. *
43 * Random3Class::operator -- Random number generator function. *
44 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
45
46#include "always.h"
47#include "random.h"
48
49// Timing tests for random these random number generators in seconds for
50// 10000000 iterations. Testing done by Hector Yee, 6/20/01
51// using DIEHARD and multidimensional Monte-Carlo Integration
52/*
53Time for Random=0.156000
54Time for Random2=0.250000
55Time for Random3=1.281000
56Time for Random4=0.375000
57Time for Built in Rand()=0.813000
58Results from DIEHARD battery of tests
59A p-value of 0.0 or 1.0 means it fails. Anything inbetween is ok.
60R0 - FAILED almost all tests, didn't complete squeeze test
61R2 - Passed all tests, p-value 0.6
62R3 - Failed 11 of 253 tests, p-value 1.0
63R4 - Passed all tests, p-value 0.2588
64Rand() - FAILED almost all tests, didn't complete squeeze test
65Results from Montecarlo Integration 2-96 dimensions
66R0 - starts breaking in 24 dimensions
67R2 - Ok, but will repeat with short period. Huge spike at 300000 samples in 64 dimensions
68R3 - Strong bias from 2 dimensions up
69R4 - Ok
70Rand() - starts breaking in 24 dimensions
71*/
72
73
74/***********************************************************************************************
75 * RandomClass::RandomClass -- Constructor for the random number class. *
76 * *
77 * This constructor can take an integer as a parameter. This allows the class to be *
78 * constructed by assigning an integer to an existing object. The compiler creates a *
79 * temporary with the constructor and then performs a copy constructor operation. *
80 * *
81 * INPUT: seed -- The optional starting seed value to use. *
82 * *
83 * OUTPUT: none *
84 * *
85 * WARNINGS: none *
86 * *
87 * HISTORY: *
88 * 02/27/1996 JLB : Created. *
89 *=============================================================================================*/
91 Seed(seed)
92{
93}
94
95
96/***********************************************************************************************
97 * RandomClass::operator() -- Fetches the next random number in the sequence. *
98 * *
99 * This routine will fetch the next random number in the sequence. *
100 * *
101 * INPUT: none *
102 * *
103 * OUTPUT: Returns with the next random number. *
104 * *
105 * WARNINGS: This routine modifies the seed value so that subsequent calls will not return *
106 * the same value. Take note that this routine only returns 15 bits of *
107 * random number. *
108 * *
109 * HISTORY: *
110 * 02/27/1996 JLB : Created. *
111 *=============================================================================================*/
113{
114 /*
115 ** Transform the seed value into the next number in the sequence.
116 */
118
119 /*
120 ** Extract the 'random' bits from the seed and return that value as the
121 ** random number result.
122 */
123 return((Seed >> THROW_AWAY_BITS) & (~((~0) << SIGNIFICANT_BITS)));
124}
125
126
127/***********************************************************************************************
128 * RandomClass::operator() -- Ranged random number generator. *
129 * *
130 * This function will return with a random number within the range specified. This replaces *
131 * the functionality of IRandom() in the old library. *
132 * *
133 * INPUT: minval -- The minimum value to return from the function. *
134 * *
135 * maxval -- The maximum value to return from the function. *
136 * *
137 * OUTPUT: Returns with a random number that falls between the minval and maxval (inclusive). *
138 * *
139 * WARNINGS: The range specified must fall within the maximum bit significance of the *
140 * random number algorithm (15 bits), otherwise the value returned will be *
141 * decidedly non-random. *
142 * *
143 * HISTORY: *
144 * 02/27/1996 JLB : Created. *
145 *=============================================================================================*/
146int RandomClass::operator() (int minval, int maxval)
147{
148 return(Pick_Random_Number(*this, minval, maxval));
149}
150
151
152/***********************************************************************************************
153 * Random2Class::Random2Class -- Constructor for the random class. *
154 * *
155 * This will initialize the random class object with the seed value specified. *
156 * *
157 * INPUT: seed -- The seed value used to scramble the random number generator. *
158 * *
159 * OUTPUT: none *
160 * *
161 * WARNINGS: none *
162 * *
163 * HISTORY: *
164 * 05/14/1997 JLB : Created. *
165 *=============================================================================================*/
167 Index1(0),
168 Index2(103)
169{
170 Random3Class random(seed);
171
172 for (int index = 0; index < ARRAY_SIZE(Table); index++) {
173 Table[index] = random;
174 }
175}
176
177
178/***********************************************************************************************
179 * Random2Class::operator -- Randomizer function that returns value. *
180 * *
181 * This is the random number generator function. It will generate a random number and *
182 * return the value. *
183 * *
184 * INPUT: none *
185 * *
186 * OUTPUT: Returns with a random number. *
187 * *
188 * WARNINGS: none *
189 * *
190 * HISTORY: *
191 * 05/20/1997 JLB : Created. *
192 *=============================================================================================*/
194{
196 int val = Table[Index1];
197
198 Index1++;
199 Index2++;
200
201 if (Index1 >= ARRAY_SIZE(Table)) Index1 = 0;
202 if (Index2 >= ARRAY_SIZE(Table)) Index2 = 0;
203
204 return(val);
205}
206
207
208/***********************************************************************************************
209 * Random2Class::operator -- Generates a random number between two values. *
210 * *
211 * This routine will generate a random number between the two values specified. It uses *
212 * a method that will not bias the values in any way. *
213 * *
214 * INPUT: minval -- The minium return value (inclusive). *
215 * *
216 * maxval -- The maximum return value (inclusive). *
217 * *
218 * OUTPUT: Returns with a random number that falls between the two values (inclusive). *
219 * *
220 * WARNINGS: none *
221 * *
222 * HISTORY: *
223 * 05/20/1997 JLB : Created. *
224 *=============================================================================================*/
225int Random2Class::operator() (int minval, int maxval)
226{
227 return(Pick_Random_Number(*this, minval, maxval));
228}
229
230
231/*
232** This is the seed table for the Random3Class generator. These ensure
233** that the algorithm is not vulnerable to being primed with a weak seed
234** and thus prevents the algorithm from breaking down as a result.
235*/
236int Random3Class::Mix1[20] = {
237 0x0baa96887, 0x01e17d32c, 0x003bcdc3c, 0x00f33d1b2,
238 0x076a6491d, 0x0c570d85d, 0x0e382b1e3, 0x078db4362,
239 0x07439a9d4, 0x09cea8ac5, 0x089537c5c, 0x02588f55d,
240 0x0415b5e1d, 0x0216e3d95, 0x085c662e7, 0x05e8ab368,
241 0x03ea5cc8c, 0x0d26a0f74, 0x0f3a9222b, 0x048aad7e4
242};
243
244int Random3Class::Mix2[20] = {
245 0x04b0f3b58, 0x0e874f0c3, 0x06955c5a6, 0x055a7ca46,
246 0x04d9a9d86, 0x0fe28a195, 0x0b1ca7865, 0x06b235751,
247 0x09a997a61, 0x0aa6e95c8, 0x0aaa98ee1, 0x05af9154c,
248 0x0fc8e2263, 0x0390f5e8c, 0x058ffd802, 0x0ac0a5eba,
249 0x0ac4874f6, 0x0a9df0913, 0x086be4c74, 0x0ed2c123b
250};
251
252
253/***********************************************************************************************
254 * Random3Class::Random3Class -- Initializer for the random number generator. *
255 * *
256 * This initializes the random number generator with the seed values specified. Due to a *
257 * peculiarity of the random number design, the second seed value can be used to find the *
258 * Nth random number generated by this algorithm. The second seed is used as the Nth index *
259 * value. *
260 * *
261 * INPUT: seed1 -- The seed value to inialize the generator with. It is suggest that some *
262 * random value based on user input seed this value. *
263 * *
264 * seed2 -- The auxiliary seed value. This adds randomness and thus allows this *
265 * algorithm to use a 64 bit seed. This second seed also serves as an index *
266 * into the algorithm such that the value passed as 'seed2' is will prime *
267 * the generator to return that Nth random number when it is called. *
268 * *
269 * OUTPUT: none *
270 * *
271 * WARNINGS: As with all random number generators. Randomness is only as strong as the *
272 * initial seed value. *
273 * *
274 * HISTORY: *
275 * 05/20/1997 JLB : Created. *
276 *=============================================================================================*/
277Random3Class::Random3Class(unsigned seed1, unsigned seed2) :
278 Seed(seed1),
279 Index(seed2)
280{
281}
282
283
284/***********************************************************************************************
285 * Random3Class::operator -- Random number generator function. *
286 * *
287 * This routine generates a random number. The number returned is strongly random and is *
288 * nearly good enough for cryptography. *
289 * *
290 * INPUT: none *
291 * *
292 * OUTPUT: Returns with a 32bit random number. *
293 * *
294 * WARNINGS: none *
295 * *
296 * HISTORY: *
297 * 05/20/1997 JLB : Created. *
298 *=============================================================================================*/
300{
301 int loword = Seed;
302 int hiword = Index++;
303 for (int i = 0; i < 4; i++) {
304 int hihold = hiword;
305 int temp = hihold ^ Mix1[i];
306 int itmpl = temp & 0xffff;
307 int itmph = temp >> 16;
308 temp = itmpl * itmpl + ~(itmph * itmph);
309 temp = (temp >> 16) | (temp << 16);
310 hiword = loword ^ ((temp ^ Mix2[i]) + itmpl * itmph);
311 loword = hihold;
312 }
313 return(hiword);
314}
315
316
317/***********************************************************************************************
318 * Random3Class::operator -- Generates a random number between two values. *
319 * *
320 * This routine will generate a random number between the two values specified. It uses *
321 * a method that will not bias the values in any way. *
322 * *
323 * INPUT: minval -- The minium return value (inclusive). *
324 * *
325 * maxval -- The maximum return value (inclusive). *
326 * *
327 * OUTPUT: Returns with a random number that falls between the two values (inclusive). *
328 * *
329 * WARNINGS: none *
330 * *
331 * HISTORY: *
332 * 05/20/1997 JLB : Created. *
333 *=============================================================================================*/
334int Random3Class::operator() (int minval, int maxval)
335{
336 return(Pick_Random_Number(*this, minval, maxval));
337}
338
339// Random4
340// Hector Yee 6/11/01
341
342/* Period parameters */
343#define N 624
344#define M 397
345#define MATRIX_A 0x9908b0df /* constant vector a */
346#define UPPER_MASK 0x80000000 /* most significant w-r bits */
347#define LOWER_MASK 0x7fffffff /* least significant r bits */
348
349/* Tempering parameters */
350#define TEMPERING_MASK_B 0x9d2c5680
351#define TEMPERING_MASK_C 0xefc60000
352#define TEMPERING_SHIFT_U(y) (y >> 11)
353#define TEMPERING_SHIFT_S(y) (y << 7)
354#define TEMPERING_SHIFT_T(y) (y << 15)
355#define TEMPERING_SHIFT_L(y) (y >> 18)
356
358{
359 /* setting initial seeds to mt[N] using */
360 /* the generator Line 25 of Table 1 in */
361 /* [KNUTH 1981, The Art of Computer Programming */
362 /* Vol. 2 (2nd Ed.), pp102] */
363 if (!seed) seed=4375;
364
365 mt[0]= seed & 0xffffffff;
366 for (mti=1; mti<N; mti++)
367 mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;
368 // mti is N+1 after this
369}
370
372{
373 unsigned int y;
374 static unsigned int mag01[2]={0x0, MATRIX_A};
375 /* mag01[x] = x * MATRIX_A for x=0,1 */
376
377 if (mti >= N) { /* generate N words at one time */
378 int kk;
379
380 for (kk=0;kk<N-M;kk++) {
381 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
382 mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
383 }
384 for (;kk<N-1;kk++) {
385 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
386 mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
387 }
388 y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
389 mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
390
391 mti = 0;
392 }
393
394 y = mt[mti++];
395 y ^= TEMPERING_SHIFT_U(y);
398 y ^= TEMPERING_SHIFT_L(y);
399
400 int *x=(int *)&y;
401
402 return *x;
403}
404
405int Random4Class::operator() (int minval, int maxval)
406{
407 return(Pick_Random_Number(*this, minval, maxval));
408}
409
411{
412 int x=(*this)();
413 unsigned int *y=(unsigned int *) &x;
414
415 return (*y)*2.3283064370807973754314699618685e-10f;
416}
int Pick_Random_Number(T &generator, int minval, int maxval)
Definition RANDOM.H:217
#define ARRAY_SIZE(a)
Random2Class(unsigned seed=0)
Definition random.cpp:166
int operator()(void)
Definition random.cpp:193
int Table[250]
Definition RANDOM.H:114
int operator()(void)
Definition random.cpp:299
static int Mix2[20]
Definition RANDOM.H:244
Random3Class(unsigned seed1=0, unsigned seed2=0)
Definition random.cpp:277
static int Mix1[20]
Definition RANDOM.H:236
Random4Class(unsigned int seed=4357)
Definition random.cpp:357
unsigned int mt[624]
Definition RANDOM.H:189
float Get_Float()
Definition random.cpp:410
int operator()(void)
Definition random.cpp:371
RandomClass(unsigned seed=0)
Definition random.cpp:90
@ MULT_CONSTANT
Definition RANDOM.H:74
@ ADD_CONSTANT
Definition RANDOM.H:75
@ THROW_AWAY_BITS
Definition RANDOM.H:76
int operator()(void)
Definition random.cpp:112
unsigned long Seed
Definition RANDOM.H:67
@ SIGNIFICANT_BITS
Definition RANDOM.H:63
#define N
Definition random.cpp:343
#define TEMPERING_SHIFT_T(y)
Definition random.cpp:354
#define TEMPERING_SHIFT_L(y)
Definition random.cpp:355
#define TEMPERING_SHIFT_U(y)
Definition random.cpp:352
#define MATRIX_A
Definition random.cpp:345
#define UPPER_MASK
Definition random.cpp:346
#define LOWER_MASK
Definition random.cpp:347
#define M
Definition random.cpp:344
#define TEMPERING_MASK_B
Definition random.cpp:350
#define TEMPERING_SHIFT_S(y)
Definition random.cpp:353
#define TEMPERING_MASK_C
Definition random.cpp:351