// Filename: RollDice.cpp // This source file is used in assignment 16 on Pseudorandomness // This program demonstrates how to use the RandGen and Dice // classes. #include #include #include using namespace std; // First we define the classes (namely RandGen and Dice) that will be // used in this program. class RandGen { public: RandGen(); // set seed for all instances int RandInt(int max = INT_MAX); // returns int in [0..max) int RandInt(int low, int max); // returns int in [low..max] double RandReal(); // returns double in [0..1) double RandReal(double low, double max); // range [low..max] static void SetSeed(int seed); // static (per class) seed set private: static int ourInitialized; // for 'per-class' initialization // This makes sure init is called only once }; class Dice { public: Dice(); // default constructor assumes a 6-sided die. Dice(int sides); // constructor for any size dice int Roll(); // return the random roll of the die int getNumSides() const; // how many sides this die has int getNumRolls() const; // # times this die rolled private: int myRollCount; // # times die rolled int mySides; // # sides on die }; //--------------------------------------------------------------------- // main begins here //--------------------------------------------------------------------- int main() { Dice cube; // make a six-sided die cout << "Rolls of a " << cube.getNumSides() << "-sided die:" << endl; cout << cube.Roll() << endl; cout << cube.Roll() << endl; cout << "Rolled " << cube.getNumRolls() << " times." << endl; return 0; } //--------------------------------------------------------------------- // RandGen class functions begin here //--------------------------------------------------------------------- int RandGen::ourInitialized = 0; void RandGen::SetSeed(int seed) { // postcondition: system srand() used to initialize seed // once per program (This is a static function) if (0 == ourInitialized) { ourInitialized = 1; // only call srand once srand(seed); // randomize given a seed } } RandGen::RandGen() { // postcondition: system srand() used to initialize seed // once per program if (0 == ourInitialized) { ourInitialized = 1; // only call srand once srand(unsigned(time(0))); // randomize using time as seed } } int RandGen::RandInt(int max) { // precondition: max > 0 // postcondition: returns int in [0..max) return int(RandReal() * max); } // This function returns a number between low and max int RandGen::RandInt(int low, int max) { // precondition: low <= max // postcondition: returns int in [low..max] return low + RandInt(max-low+1); } double RandGen::RandReal() { // postcondition: returns double in [0..1) return rand() / (double(RAND_MAX) + 1); } // This function takes a low and high and returns a random // number within this range. double RandGen::RandReal(double low, double high) { double range = fabs(high-low); double thelow = low < high ? low : high; return thelow + RandReal()*range; } //--------------------------------------------------------------------- // Dice class functions begin here //--------------------------------------------------------------------- Dice::Dice()//Default is to assume a six sided die. // postcondition: all private fields initialized { myRollCount = 0; mySides = 6; } Dice::Dice(int sides) // postcondition: all private fields initialized { myRollCount = 0; mySides = sides; } int Dice::Roll() // postcondition: number of rolls updated // random 'die' roll returned { RandGen gen; // random number generator myRollCount= myRollCount + 1; // update # of times die rolled return gen.RandInt(1,mySides); // in range [1..mySides] } int Dice::getNumSides() const // postcondition: return # of sides of die { return mySides; } int Dice::getNumRolls() const // postcondition: return # of times die has been rolled { return myRollCount; }