/* * File: random.cpp * ---------------- * This file implements the random.h interface. */ #include #include #include #include "random.h" #include "private/randompatch.h" using namespace std; /* Private function prototype */ static void initRandomSeed(); /* * Implementation notes: randomInteger * ----------------------------------- * The code for randomInteger produces the number in four steps: * * 1. Generate a random real number d in the range [0 .. 1). * 2. Scale the number to the range [0 .. N) where N is the number of values. * 3. Translate the number so that the range starts at the appropriate value. * 4. Convert the result to the next lower integer. * * The implementation is complicated by the fact that both the expression * * RAND_MAX + 1 * * and the expression for the number of values * * high - low + 1 * * can overflow the integer range. These calculations must therefore be * performed using doubles instead of ints. */ int randomInteger(int low, int high) { initRandomSeed(); double d = rand() / (double(RAND_MAX) + 1); double s = d * (double(high) - low + 1); return int(floor(low + s)); } /* * Implementation notes: randomReal * -------------------------------- * The code for randomReal is similar to that for randomInteger, * without the final conversion step. */ double randomReal(double low, double high) { initRandomSeed(); double d = rand() / (double(RAND_MAX) + 1); double s = d * (high - low); return low + s; } /* * Implementation notes: randomChance * ---------------------------------- * The code for randomChance calls randomReal(0, 1) and then checks * whether the result is less than the requested probability. */ bool randomChance(double p) { initRandomSeed(); return randomReal(0, 1) < p; } /* * Implementation notes: setRandomSeed * ----------------------------------- * The setRandomSeed function simply forwards its argument to srand. * The call to initRandomSeed is required to set the initialized flag. */ void setRandomSeed(int seed) { initRandomSeed(); srand(seed); } /* * Implementation notes: initRandomSeed * ------------------------------------ * The initRandomSeed function declares a static variable that keeps track * of whether the seed has been initialized. The first time initRandomSeed * is called, initialized is false, so the seed is set to the current time. */ static void initRandomSeed() { static bool initialized = false; if (!initialized) { srand(int(time(NULL))); initialized = true; } }