/**
* Generate reproducible sequences of random numbers.
* This is designed to produce a random number from the same
* seed. This will make sequences of reproduceable random
* numbers.
*
* Useful for things like garbling of text and stuff so the garble
* always looks the same...
*/
int seed = 100;
varargs int random(int max, mixed lseed);
#define Q 51924
#define R 10855
#define MULT 41358
#define MOD 21474836647
#define MAX_VALUE (MOD-1)
/* Throw away this many random numbers on startup */
#define STARTUP_RANDS 16
/**
* Set the seed for the generator.
* @param new_seed the seed to use.
*/
void set_seed(int new_seed) {
int i;
if (seed <= 0)
seed = random(200);
else
seed = new_seed;
/* Throw away some initial values */
for (i=0;i<STARTUP_RANDS;i++)
random(200);
} /* set_seed() */
/**
* Generate a random number. If lseed is an int, it is used as the seed.
* If lseed is a one-element array of ints, lseed[0] is used as the seed
* and the new seed is passed back. Otherwise, the previously set seed
* is used.
* @param max the maximum value for the number.
* @param lseed the seed to use, either an int or a one-element array
* of int.
* @return a number from 0..max-1 (inclusive)
*/
varargs int random(int max, mixed lseed) {
int k, residue, curseed, mode;
if (undefinedp(lseed)) {
curseed = seed;
} else if (intp(lseed)) {
curseed = lseed;
mode = 1;
} else if (arrayp(lseed) && (sizeof(lseed) == 1) && (intp(lseed[0]))) {
curseed = lseed[0];
mode = 2;
} else {
curseed = seed;
}
k = curseed / Q;
residue = MULT * (curseed - Q*R) - R*k;
if (residue < 0)
residue += MOD;
if (mode == 0) {
seed = residue;
} else if (mode == 2) {
lseed[0] = residue;
}
return residue % max;
} /* random() */
/**
* Returns the currently specified seed.
* @return the current seed
*/
int query_seed() {
return seed;
} /* query_seed() */