//****************************************************************** // Game program // This program simulates the children's game Rock, Paper, and // Scissors. Each game consists of inputs from two players, // coming from fileA and fileB. A winner is determined for each // individual game and for the games overall //****************************************************************** #include #include // For file I/O using namespace std; enum PlayType {ROCK, PAPER, SCISSORS}; PlayType ConversionVal( char ); void GetPlays( ifstream&, ifstream&, PlayType&, PlayType&, bool& ); void PrintBigWinner( int, int ); void ProcessPlays( int, PlayType, PlayType, int&, int& ); void RecordAWin( char, int, int& ); int main() { PlayType playForA; // Player A's play PlayType playForB; // Player B's play int winsForA = 0; // Number of games A wins int winsForB = 0; // Number of games B wins int gameNumber = 0; // Number of games played bool legal; // True if play is legal ifstream fileA; // Player A's plays ifstream fileB; // Player B's plays // Open the input files fileA.open("filea.dat"); fileB.open("fileb.dat"); if ( !fileA || !fileB ) { cout << "** Can't open input file(s) **" << endl; return 1; } // Play a series of games and keep track of who wins GetPlays(fileA, fileB, playForA, playForB, legal); while (fileA && fileB) { gameNumber++; if (legal) ProcessPlays(gameNumber, playForA, playForB, winsForA, winsForB); else cout << "Game number " << gameNumber << " contained an illegal play." << endl; GetPlays(fileA, fileB, playForA, playForB, legal); } // Print overall winner PrintBigWinner(winsForA, winsForB); return 0; } //****************************************************************** void GetPlays( /* inout */ ifstream& fileA, // Plays for A /* inout */ ifstream& fileB, // Plays for B /* out */ PlayType& playForA, // A's play /* out */ PlayType& playForB, // B's play /* out */ bool& legal ) // True if plays // are legal // Reads the players' plays from the data files, converts the plays // from char form to PlayType form, and reports whether the plays // are legal. If end-of-file is encountered on either file, the // outgoing parameters are undefined. // Precondition: // fileA and fileB have been successfully opened // Postcondition: // IF input from either file failed due to end-of-file // playForA, playForB, and legal are undefined // ELSE // Player A's play has been read from fileA and Player B's // play has been read from fileB // && IF both plays are legal // legal == TRUE // && playForA == PlayType equivalent of Player A's play // char // && playForB == PlayType equivalent of Player B's play // char // ELSE // legal == FALSE // && playForA and playForB are undefined { char charForA; // Player A's input char charForB; // Player B's input fileA >> charForA; // Skip whitespace, including newline fileB >> charForB; if ( !fileA || !fileB) return; legal = (charForA=='R' || charForA=='P' || charForA=='S') && (charForB=='R' || charForB=='P' || charForB=='S'); if (legal) { playForA = ConversionVal(charForA); playForB = ConversionVal(charForB); } } //****************************************************************** PlayType ConversionVal( /* in */ char someChar ) // Play character // Converts a character into an associated PlayType value // Precondition: // someChar == 'R' or 'P' or 'S' // Postcondition: // Function value == ROCK, if someChar == 'R' // == PAPER, if someChar == 'P' // == SCISSORS, if someChar == 'S' { switch (someChar) { case 'R': return ROCK; // No break needed after case 'P': return PAPER; // return statement case 'S': return SCISSORS; } } //****************************************************************** void ProcessPlays( /* in */ int gameNumber, // Game number /* in */ PlayType playForA, // A's play /* in */ PlayType playForB, // B's play /* inout */ int& winsForA, // A's wins /* inout */ int& winsForB ) // B's wins // Determines whether there is a winning play or a tie. If there // is a winner, the number of wins of the winning player is // incremented. In all cases, a message is written // Precondition: // All arguments are assigned // Postcondition: // IF Player A won // winsForA == winsForA@entry + 1 // ELSE IF Player B won // winsForB == winsForB@entry + 1 // && A message, including gameNumber, has been written specifying // either a tie or a winner { if (playForA == playForB) cout << "Game number " << gameNumber << " is a tie." << endl; else if (playForA == PAPER && playForB == ROCK || playForA == SCISSORS && playForB == PAPER || playForA == ROCK && playForB == SCISSORS) RecordAWin('A', gameNumber, winsForA); // Player A wins else RecordAWin('B', gameNumber, winsForB); // Player B wins } //****************************************************************** void RecordAWin( /* in */ char player, // Winning player /* in */ int gameNumber, // Game number /* inout */ int& numOfWins ) // Win count // Outputs a message telling which player has won the current game // and updates that player's total // Precondition: // player == 'A' or 'B' // && gameNumber and numOfWins are assigned // Postcondition: // A winning message, including player and gameNumber, has // been written // && numOfWins == numOfWins@entry + 1 { cout << "Player " << player << " has won game number " << gameNumber << '.' << endl; numOfWins++; } //****************************************************************** void PrintBigWinner( /* in */ int winsForA, // A's win count /* in */ int winsForB ) // B's win count // Prints number of wins for each player and the // overall winner (or tie) // Precondition: // winsForA and winsForB are assigned // Postcondition: // The values of winsForA and winsForB have been output // && A message indicating the overall winner (or a tie) has been // output { cout << endl; cout << "Player A has won " << winsForA << " games." << endl; cout << "Player B has won " << winsForB << " games." << endl; if (winsForA > winsForB) cout << "Player A has won the most games." << endl; else if (winsForB > winsForA) cout << "Player B has won the most games." << endl; else cout << "Players A and B have tied." << endl; }