// Purpose. Memento design pattern lab // // Problem. The GuessGame class expects multiple "clients" to "connect" to it // with a call to join(). Each client has a different random number chosen // for it by GuessGame. In order to uniquely identify itself to the GuessGame // server, each client passes a string identifier when it calls join() and // when it calls evaluateGuess(). GuessGame remembers each string identifier // in an internal table in the join() method, and then searches that table in // the evaluateGuess() method. If we put the information that is peculiar to // each client into a "black box" object (a Memento), and make the client the // "caretaker" of that object; then the implementation of the server (Guess- // Game) is greatly simplified. // // Assignment. // o Declare a class Memento // o Make class GuessGame a "friend" of class Memento // o Class Memento will have a single private int data member and a private // constructor that accepts an int and initializes the data member // o GuessGame::join() doesn't need to accept a string identifier. But, it // does need to: select a random number, "wrap" that number in a Memento // object, and return a pointer to that object. // o GuessGame::evaluateGuess() will now accept a Memento object instead of // a string identifier. It doesn't need to search its table of string // identifiers, and then access its table of random numbers. Instead, it // simply references the Memento's private int data member. // o All the private data members of class GuessGame can now be retired. // o Add a Memento* member to struct Game // o The call to guessServer.join() no longer requires a string argument, // and, the Memento* returned from join() needs to be remembered. // o The call to guessServer.evaluateGuess() now requires a Memento* argument // instead of a string argument. // o Be sure to clean-up the Memento* pointers when you are done #include #include #include #include class GuessGame { private: int numbers[10]; char names[10][20]; int total; public: GuessGame() { time_t t; srand((unsigned) time(&t)); total = 0; } void join( char* name ) { strcpy( names[total], name ); numbers[total++] = rand() % 30 + 1; } int evaluateGuess( char* name, int guess ) { int i; for (i=0; i < total; i++) if ( ! strcmp( names[i], name )) break; if (guess == numbers[i]) return 0; return ((guess > numbers[i]) ? 1 : -1); } }; struct Game { char name[20]; int min, max, done; Game() { min = 1; max = 30; done = 0; } }; void main( void ) { GuessGame guessServer; const int MAX = 3; Game games[MAX]; int gamesComplete = 0; int guess, ret; for (int i=0; i < MAX; i++) { cout << "Enter name: " ; cin >> games[i].name; guessServer.join( games[i].name ); } while (gamesComplete != MAX) { for (int j=0; j < MAX; j++) { if (games[j].done) continue; cout << games[j].name <<" ("<> guess; ret = guessServer.evaluateGuess( games[j].name, guess ); if (ret == 0) { cout << " lights!! sirens!! balloons!!" << endl; games[j].done = 1; gamesComplete++; } else if (ret < 0) { cout << " too low" << endl; games[j].min = guess; } else { cout << " too high" << endl; games[j].max = guess; } } } } // Enter name: Tom // Enter name: Dick // Enter name: Harry // Tom (1-30): 10 // too low // Dick (1-30): 15 // too high // Harry (1-30): 20 // too high // Tom (10-30): 22 // too high // Dick (1-15): 8 // lights!! sirens!! balloons!! // Harry (1-20): 10 // too low // Tom (10-22): 16 // too high // Harry (10-20): 15 // too low // Tom (10-16): 13 // too high // Harry (15-20): 17 // too low // Tom (10-13): 11 // lights!! sirens!! balloons!! // Harry (17-20): 18 // lights!! sirens!! balloons!!