Wednesday, January 18, 2017

Programming Challenge 6.24 - Rock Paper Scissors Game

/* Rock Paper Scissors Game - This program lets you play the game Rock,
   Paper, Scissors against the computer. The program works as follows:
  
      * When the program begins, a random number in the range of 1 through
        3 is generated.
       
         * If the number is 1, then the computer has chosen rock.
         * If the number is 2, then the computer has chosen paper.
         * If the number is 3, then the computer has chosen scissors.

      * The user enters his or her choice of "rock", "paper", or "scissors"
        at the keyboard.

      * The computer's choice is displayed.

      * A winner is selected according to the following rules:

         * If one player chooses rock and the other player chooses scissors,
           then rock wins. (The rock smashes the scissors)
         * If one player chooses scissors and the other player chosses paper,
           then scissors wins. (Scissors cuts paper)
         * If one player chooses paper and the other player chooses rock, then
           paper wins.
         * If both players make the same choice, the game must be played again
           to determine the winner.

   This program is broken up into functions to perform each major task. */

#include "Utility.h"

/* Prototypes: Show intro, Show menu, Show Instructions, Show Quit message,
               Generate random number, Display CPU choice, Get player choice,
               Get winner, Winning choice, Display score */
string showIntro(string, string);
void showMenu();
void showInstructions();
int generateRndNumber(int);
void displayCPUChoice(int, string);
int getPlayerChoice(int, string);
int getWinner(int, int, string, string, int &, int &);
void winningChoice(int, int, int, string, string);
void displayScore(int, int, string, string);
void showQuitMessage(string, string, int, int);

int main()
{  
   /* Variables: Instructions, Begin, Again, Show score, Quit */
   const int INSTRUCTIONS = 1,
             BEGIN = 2,
             SHOW_SCORE = 3,
             QUIT = 4;
  
   /* Variable: Menu choice, Random number */
   int menuChoice = 0,
       rndNumber = 0,
       playerChoice = 0,
       winOrDraw = 0;

   /* Static Variables: Player's number of wins, CPU's number of wins */
   static int numWinsPlayer = 0,
              numWinsCpu = 0;

   /* Variables: Player name, CPU name */
   string playerName = " ",
          cpuName = "R-P-S Master";

   /* Call: showIntro */
   playerName = showIntro(playerName, cpuName);

   /* Display: Menu
      Call: showMenu, showInstructions, getRandomNumber, getPlayerChoice,
            displayCPUChoice, getWinner, displayScore, showQuitMessage
      Get: Menu choice
      Validate: Menu choice */
   do
   {
      showMenu();

      cin >> menuChoice;

      while (menuChoice < 1 || menuChoice > 4)
      {
         cout << "\n" << playerName << ", you chose a menu item that does\n"
              << "not exist. Your choice: ";
         cin >> menuChoice;
      }

      if (menuChoice != 4)
      {
         switch (menuChoice)
         {
            case 1:
               showInstructions();
            break;

            case 2:
               rndNumber = generateRndNumber(rndNumber);
               playerChoice = getPlayerChoice(playerChoice, playerName);
               displayCPUChoice(rndNumber, cpuName);
               winOrDraw = getWinner(playerChoice, rndNumber, playerName, cpuName,
                                     numWinsPlayer, numWinsCpu);

               while (winOrDraw == 3)
               {
                  rndNumber = generateRndNumber(rndNumber);
                  playerChoice = getPlayerChoice(playerChoice, playerName);
                  displayCPUChoice(rndNumber, cpuName);

                  if (playerChoice != rndNumber)
                  {
                     winOrDraw = getWinner(playerChoice, rndNumber, playerName,
                                           cpuName, numWinsPlayer, numWinsCpu);
                  }
               }
            break;

            case 3:
               displayScore(numWinsPlayer, numWinsCpu, playerName, cpuName);
            break;
         }
      }

      if (menuChoice == 4)
      {
         showQuitMessage(playerName, cpuName, numWinsPlayer, numWinsCpu);
      }

   } while (menuChoice != 4);
  
   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: showIntro

   This function displays an intro, gets and returns the
   player's name.
   ********************************************************** */

string showIntro(string playerName, string cpuName)
{
   cout << "\n\t\tROCK - PAPER - SCISSORS KINGDOM\n\n"
        << "As you wander through the kingdom, you discover a hut.\n"
        << "Above the door you can read the following inscription:\n\n"
        << "\t\t********************************\n"
        << "\t\t*  ROCK PAPER SCISSORS MASTER  *\n"
        << "\t\t********************************\n\n"
        << "When you knock, you hear a sonorous but friendly voice\n"
        << "voice asking:\n\n"
        << "Who is it who wishes to visit my modest home? ";
   cin >> playerName;

   cout << "\nWelcome " << playerName << "! Come in, come in!\n\n"
        << "While uttering these words the door magically opens.\n"
        << "Once inside, the first thing you see is the old man,\n"
        << "sitting in a comfortable chair next to a fireplace.\n"
        << "He sits there in silence and looks at you for a while,\n"
        << "then, with a broad smile, he introduces himself to you:\n\n"
        << "My name is Rock Paper Scissors Master or " << cpuName
        << "\nfor short. Would you like to challenge me to a game of:\n\n"
        << "\t\tROCK PAPER SCISSORS\n\n";

   /* Return: playerName */
   return playerName;
}

/* **********************************************************
   Definition: showMenu

   This function displays a menu.
   ********************************************************** */

void showMenu()
{
   /* Display: The menu */
   cout << "1.) Play Instructions\n"
           "2.) Play / Again\n"
           "3.) Show Score\n"
           "4.) Quit ...\n\n"
      << "Your choice: ";
}

/* **********************************************************
   Definition: showInstructions

   This function displays the playing instructions.
   ********************************************************** */

void showInstructions()
{
   /* Display: The game instructions */
   cout << "\n\t\tGame Instructions\n\n"
        << "So, declares the R-P-S Master, you wish to know the\n"
        << "rules for this game? They are utmost simple!\n\n"
        << " * Choose from:\n\n"
        << " * O ROCK\n"
        << " * []PAPER\n"
        << " * %< SCISSORS\n\n"
        << " * I choose first!\n"
        << " * You choose next!\n\n"
        << " * If I choose ROCK and you choose SCISSORS - I win\n"
        << " * If I choose SCISSORS and you choose PAPER - I win\n"
        << " * If I choose PAPER and you choose ROCK - I win\n\n"
        << "Good Luck!\n\n";
}

/* **********************************************************
   Definition: generateRndNumber

   This function simulates the PC's choice. It generates a
   random number in the range of 1 through 3 and returns it.
   ********************************************************** */

int generateRndNumber(int rndNumber)
{
   /* Constants: Random number min, Random number max */
   const int RANDOM_NUM_MIN = 1,
             RANDOM_NUM_MAX = 3;

   /* Seed: Random number generator */
   srand((unsigned int) time(NULL) * (unsigned int(3)));

   /* Generate random number in the range of 1 through 3 */
   rndNumber = (rand() % (RANDOM_NUM_MAX - RANDOM_NUM_MIN + 1) +
               RANDOM_NUM_MIN);

   /* Return: Random number */
   return rndNumber;
}

/* **********************************************************
   Definition: displayCPUChoice

   This function displays the computer's choice, after the
   player has made his or her choice.
   ********************************************************** */

void displayCPUChoice(int rndNumber, string cpuName)
{
   /* Variables: ASCII rock, ASCII paper, ASCII scissors */
   string rock = "O ROCK",
          paper = "[] PAPER",
          scissors = "%< SCISSORS";
     
      /* Determine and display the CPU's choice, once the
         player made his or her choice */
      if (rndNumber == 1)
      {
         cout << "" << cpuName << " chooses: "
            << fixed << setw(12) << left << rock << "\n\n";
      }
      else if (rndNumber == 2)
      {
         cout << "" << cpuName << " chooses: "
            << fixed << setw(12) << left << paper << "\n\n";
      }
      else if (rndNumber == 3)
      {
         cout << "" << cpuName << " chooses: "
            << fixed << setw(12) << left << scissors << "\n\n";
      }
}

/* **********************************************************
   Definition: getPlayerChoice

   This function gets and returns the player's choice.
   ********************************************************** */

int getPlayerChoice(int playerChoice, string playerName)
{
   /* Variables: ASCII rock, ASCII paper, ASCII scissors */
   string rock = "O ROCK",
          paper = "[] PAPER",
          scissors = "%< SCISSORS";

   /* Get: The player's choice */
   cout << "\n1. " << rock << "\t2. " << paper << "\t3. "
        << scissors << "\n"
        << "Choose: ";
   cin >> playerChoice;

   /* Validate: The player's choice */
   while (playerChoice < 1 || playerChoice > 3)
   {
      cout << "\n" << playerName << "! You have selected a\n"
           << "symbol that does not exist in our kingdom!\n"
           << "Choose: ";
      cin >> playerChoice;
   }

   /* Determine and display the players choice */
   if (playerChoice == 1)
   {
      cout << "\n" << playerName << " chooses:"
           << fixed << setw(15) << right << rock << "\n";
   }
   else if (playerChoice == 2)
   {
      cout << "\n" << playerName << " chooses:"
           << fixed << setw(17) << right << paper << "\n";
   }
   else if (playerChoice == 3)
   {
      cout << "\n" << playerName << " chooses:"
           << fixed << setw(20) << right << scissors << "\n";
   }

   /* Return: playerChoice */
   return playerChoice;
}

/* **********************************************************
   Definition: getWinner

   This function accepts the following arguments:
  
      * The player's choice
      * The CPU's random number

   It determines whether the player or CPU has won, and keeps
   track of the wins and losses of both sides. If there is a
   draw, the function returns draw, and a new round starts
   and is played until a winner is determined.
   ********************************************************** */

int getWinner(int playerChoice, int rndNumber, string playerName, string cpuName,
              int &numWinsPlayer, int &numWinsCpu)
{
   /* Static Variables: Player wins (initialized to 1), CPU wins (initialized
      to 2), Draw (initialized to 3), Winner */
   static int playerWins = 1,
              cpuWins = 2,
              draw = 3,
              winner = 0;

   /* The ternary operator determines the winner, by comparing the possible
      winning choices. If the player wins, winner gets playerWins, else
      if the CPU wins, winner gets cpuWins */
   winner = playerChoice == 1 && rndNumber == 3 ||
            playerChoice == 2 && rndNumber == 1 ||
            playerChoice == 3 && rndNumber == 2 ?
      playerWins : cpuWins;

   /* If the player's choice equals the CPU's choice, Draw is displayed,
      the function exits and returns draw */
   if (playerChoice == rndNumber)
   {
      cout << "Draw!\n";
      return draw;
   }

   /* If the player wins, winningChoice is called, the number of wins
      increases and the winner is returned */
   if (winner == playerWins)
   {
      winningChoice(winner, playerChoice, rndNumber, playerName, cpuName);
      numWinsPlayer += 1;
      return playerWins;
   }

   /* If the CPU wins, winningChoice is called, the number of wins
      increases and the winner is returned */
   else if (winner == cpuWins)
   {
      winningChoice(winner, playerChoice, rndNumber, playerName, cpuName);
      numWinsCpu += 1;
      return cpuWins;
   }

   return 0;
}

/* **********************************************************
   Definition: winningChoice

   This function accepts five arguments:
  
      * The winner, 1 is player one, 2 the computer opponent
      * The player's choice
      * The CPU's choice
      * The name of player one
      * The name of the computer opponent
  
   It announces the winner of a round and displays his or her
   or the computer's name, and the winning choice.
   ********************************************************** */

void winningChoice(int winner, int playerChoice, int rndNumber,
                   string playerName, string cpuName)
{
   /* Variables: Winning Rock, Winning Paper, Winning Scissors */
   string winRock = " < O % ROCK beat SCISSORS",
          winPaper = "[O] PAPER beat ROCK",
          winScissors = "  %<`-_ SCISSORS beat PAPER";

   /* These if/else blocks determines the winning choice of each
      player and displays it when a winner is found */
   if (winner == 1 && playerChoice == 1 && rndNumber == 3)
   {
      cout << "" << winRock << "\t" << playerName << " has won!\n\n";
   }
   else if (winner == 2 && rndNumber == 1 && playerChoice == 3)
   {
      cout << "" << winRock << "\t" << cpuName << " has won!\n\n";
   }

   if (winner == 1 && playerChoice == 2 && rndNumber == 1)
   {
      cout << "" << winPaper << "\t" << playerName << " has won!\n\n";
   }
   else if (winner == 2 && rndNumber == 2 && playerChoice == 1)
   {
      cout << "" << winPaper << "\t" << cpuName << " has won!\n\n";
   }

   if (winner == 1 && playerChoice == 3 && rndNumber == 2)
   {
      cout << "" << winScissors << "\t" << playerName << " has won!\n\n";
   }
   else if (winner == 2 && rndNumber == 3 && playerChoice == 2)
   {
      cout << "" << winScissors << "\t" << cpuName << " has won!\n\n";
   }
}

/* **********************************************************
   Definition: displayScore
  
   This function displays the player's and the CPU's scores.
   ********************************************************** */

void displayScore(int numWinsPlayer, int numWinsCPU, string playerName,
              string cpuName)
{
   /* Display: The score */
   cout << "\n" << playerName << " has won "
        << numWinsPlayer << " times\n";
   cout << "" << cpuName << " has won "
        << numWinsCPU << " times\n\n";
}

/* **********************************************************
   Definition: showQuitMessage

   This function displays a quit message, in which the player
   and the computer scores are displayed.
   ********************************************************** */

void showQuitMessage(string playerName, string cpuName,
                     int numWinsPlayer, int numWinsCpu)
{
   /* Display: A quit message, The winning score */
   cout << "\n" << cpuName << " nods and says with a sad voice: \n"
        << "I come to like you, " << playerName << " you were a worthy\n"
        << "opponent!\n"
        << "\nAcknowledging your skills, he continues\n\n"
        << "You beat me all of " << numWinsPlayer << " times\n"
        << "Yet I wasn't too bad myself with " << numWinsCpu << " wins\n\n"
        << "So then, fare the well, " << playerName << "!\n"
        << "Come back any time for another game!\n\n";
}

Example Output: 








No comments:

Post a Comment