#include "munga.h" #pragma hdrstop #include "random.h" int RandomGenerator::Numbers[250]; int RandomGenerator::Index = -1; RandomGenerator Random; // //########################################################################### //########################################################################### // void RandomGenerator::Init() { int i, msb, mask; // //-------------------------------------------------------------------- // After making sure the table is built only once, initialize the // Borland C++ random numbers with the low word of the current time in // milliseconds, and initialize the index pointer //-------------------------------------------------------------------- // char *seed_spec = getenv("RANDOM"); unsigned seed; if (seed_spec) { seed = (unsigned)atol(seed_spec); } else { seed = (unsigned)time(NULL); } #if defined(TEST_CLASS) cout << "Random Seed = " << seed << endl; #endif srand(seed); Index = 0; // //------------------------------------------------------------------ // Load the random number buffer, then go thru and set the sign bit // randomly, increasing the range of random numbers from 0..32767 to // 0..65535 //------------------------------------------------------------------ // for (i=0; i<250; i++) { Numbers[i] = rand(); } // //-------------------------------------------------------------------- // In order to preserve a good random number mix for the XOR function, // mask and set the bits of 16 words in a descending manner as in // 1xx..., 01xx..., 001xx..., 0001xx..., ... //-------------------------------------------------------------------- // mask = RAND_MAX >> 1; msb = mask + 1; int rand_size; for (rand_size=0; !(msb&(1<>= 1; msb >>= 1; i += 11; } } // //########################################################################### //########################################################################### // int RandomGenerator::GetRandomInt() { int indent, result; // //------------------------------------------------------------------ // The random number generated will be the result of an XOR with the // element 103 positions further (wrapping around) in the table //------------------------------------------------------------------ // indent = (Index>=147)?Index-147:Index+103; result = Numbers[Index]^Numbers[indent]; // //------------------------------------------------------------------------ // Replace the current random number with the new one generated, increment // the buffer index pointer, and return the number //------------------------------------------------------------------------ // Numbers[Index] = result; if (++Index == ELEMENTS(Numbers)) Index=0; return result; } // //########################################################################### //########################################################################### // RandomGenerator::operator Scalar() { Scalar result; result = GetRandomInt(); result /= (float)(RAND_MAX + 1); return result; } // //########################################################################### //########################################################################### // int RandomGenerator::operator ()(int range) { int result, max; max = RAND_MAX - ((RAND_MAX + 1)%range); do { result = GetRandomInt(); } while (result>max); return result%range; } // //########################################################################### //########################################################################### // Die::Die(int n) { dieSides = (n>1)?n:2; highestRandom = RAND_MAX - ((RAND_MAX+1)%dieSides); } // //########################################################################### //########################################################################### // Die::operator int() { int result; // //------------------------------------------------------------------------ // In order to not skew the probabilities to the low numbers, make sure // that the random # used is not greater than the limit determined for the // number of sides. //------------------------------------------------------------------------ // do { result = Random.GetInt(); } while (result>highestRandom); // //------------------------------------------------------------------- // Once the base random number is determined, do modulus division and // increment by 1 to map into the die range. //------------------------------------------------------------------- // return result % dieSides + 1; } #if defined(TEST_CLASS) #include "random.tcp" #endif