/** * 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() */