// --------------------------------------------------------------------------- // hw1.C // // Alicia Thorsen // CS1129 Hw1 Solution // // Program allows a human player to play a gambling version of the Rock // Paper Scissors game against the computer. Rock beats scissors, scissors // beats paper and paper beats rock. // // The game begins by asking the human player how much money each player // should start with. Then a coin is flipped and the winner sets the bet. // The bet amount is subtracted from each player's balance and added to // the pot. // // Then each player chooses either rock, paper or scissors and the winner // gets the pot. The player who won the last round then gets to set the bet. // This continues until one player runs out of money. After the game ends, // statistics for each player is displayed. // // The computer's betting strategy is as follows: // - If it's losing it bets 1/4 of its balance // - If it's winning by a landslide (it has more than 4 times the human's // balance) it bets all of the human's balance // - If it's winning but not on a winning streak, it bets half the human's // balance // - If it's winning and on a winning streak, it bets up to the entire // human's balance depending on the streak. If it gets the "ultimate // streak" it bets all of the human's balance. // --------------------------------------------------------------------------- #include #include #include using namespace std; int main() { // Constants for readability. const int WIN = 0; const int LOSE = 1; const int DRAW = 2; int bank = 0; // Amt each player starts with. int pot = 0; // Amt of money to win. int bet = 0; // Amt player sets as bet. int coin = 0; // Coin to flip to break ties. bool firstRound = true; // Flag to detect if it's the first round. int humanBal = 0; // Human balance. int computerBal = 0; // Computer balance. bool humanSetsBet = true; // Flag to tell who sets the bet. int humanRoundResult = DRAW; // Either win, lose, draw. char humanChoice = 'r'; // Choose from {r, p, s}. char computerChoice = 'r'; // Choose from {r, p, s}. int randNum = 0; // Random # from 0 to 2 for computer choice. int streak = 0; // Computer's winning streak const int ULTIMATE_STREAK = 6;// Max streak value chosen based on experience int halfHumBal = 0; // Half of the human player's balance double extra = 0; // Extra amt computer bets when it's on a streak // Tally for human choices. int humanChoseR = 0; int humanChoseP = 0; int humanChoseS = 0; // Tally for computer choices. int computerChoseR = 0; int computerChoseP = 0; int computerChoseS = 0; // Statistics for computer choices. double comRockPercent = 0; double comPaperPercent = 0; double comScissorsPercent = 0; // Statistics for human choices. double humRockPercent = 0; double humPaperPercent = 0; double humScissorsPercent = 0; // # of rounds actually played. int roundsCnt = 0; // Seed random number generator. srand(time(0)); // Clear the screen. system("clear"); // Output introduction and rules of game. cout << "\n$$$ Rock Paper Scissors - Las Vegas Style! $$$\n" << "\nThese are the rules to win a round :\n" << "\tRock smashes Scissors\n" << "\tPaper covers Rock\n" << "\tScissors cuts Paper\n"; cout << "\nThese are the rules of betting :\n" << "\tThe bet must be a positive even integer and at least $2.\n" << "\tYou cannot bet more than any player's balance.\n"; cout << "\nHow much money do you want to start with?" << "\nMust an even integer greater than or equal to 2: $"; // ----------------------------------------------- // GET INITIAL AMT, VALIDATE AND SET BALANCES. // ----------------------------------------------- cin >> bank; // Loop until a valid amt is entered (even and >= 2). while ((bank < 2) || (bank % 2 == 1)) { cout << "\nSorry that's an invalid response. Please try again!\n" << "\nHow much money do you want to start with?" << "\nMust be an even integer greater than or equal to 2: $"; cin >> bank; } // Assign money to each player. humanBal = computerBal = bank; cout << "\nTime to play! Each player has $" << bank << "! " << "Good Luck!\n"; // Play continues until someone runs out of money. while ((humanBal > 0) && (computerBal > 0)) { // ----------------------------------------------- // DETERMINE WHO SETS THE BET. // ----------------------------------------------- // If it's the first round or the last round was a draw, // flip a coin to see who bets first. if (firstRound || (humanRoundResult == DRAW)) { if (firstRound) { cout << "\nCoin toss to start the first round.\n"; firstRound = false; } else cout << "\nCoin toss because of draw.\n"; // Coin toss. coin = rand() % 2; // Check to see if human won (coin == 0). if (coin == WIN) { cout << "You won the coin toss, you set the bet\n"; humanSetsBet = true; } else { cout << "You lost the coin toss, computer sets the bet.\n"; humanSetsBet = false; } } else if (humanRoundResult == WIN) { cout << "\nYou won the last round so you will set the bet.\n"; humanSetsBet = true; } else { cout << "\nComputer won the last round so it sets the bet.\n"; humanSetsBet = false; } // ----------------------------------------------- // SET THE BET & ADD TO THE POT. // ----------------------------------------------- // Human sets the bet. if (humanSetsBet) { cout << "\nHow much is the bet? $"; cin >> bet; // Loop until a valid bet amt is entered. while ((bet < 2) || (bet % 2 == 1) || (bet > humanBal) || (bet > computerBal)) { cout << "\nSorry that's an invalid response. Please try again!\n" << "\nComputer balance = $" << computerBal << "\tYour balance = $" << humanBal << "\nHow much is the bet? $"; cin >> bet; } } else { // Computer sets the bet. if (computerBal < humanBal) // Losing: 1/4 compBal. bet = computerBal / 4; else if ((computerBal / 4) > humanBal) // Way ahead: all of humBal. bet = humanBal; else { // Winning: at least 1/2 humBal. halfHumBal = humanBal / 2; extra = 0; // If the computer is on a winning streak it bets a little "extra". // It will bet the entire human's balance if it gets the "ultimate // streak". if (streak >= 2) extra = (static_cast(streak) / ULTIMATE_STREAK) * halfHumBal; bet = halfHumBal + static_cast(extra); } // Minimum bet is 2. if (bet < 2) bet = 2; // Bet must be even. if (bet % 2 == 1) bet++; cout << "\nComputer sets bet at $" << bet << endl; } // Adjust balances and pot with bet. humanBal -= bet; computerBal -= bet; pot = 2 * bet; // Display balance and pot value. cout << "\nPot = $"<< pot << "\tYour balance = $" << humanBal << "\tComputer balance = $" << computerBal << endl; // ----------------------------------------------- // GET PLAYERS' CHOICES: ROCK, PAPER OR SCISSORS? // ----------------------------------------------- // Get computer choice. randNum = rand() % 3; // Convert computer choice to a letter. switch (randNum) { case 0: computerChoice = 'r'; break; case 1: computerChoice = 'p'; break; case 2: computerChoice = 's'; break; default: cout << "Error in random # generator!\n"; } // Get human choice. cout << "\nThe computer has made his decision. What's yours?" << "\nRock Paper or Scissors? (enter r, p or s) : "; cin >> humanChoice; // If response is invalid, loop until it is valid. while (!((humanChoice == 'r') || (humanChoice == 'p') || (humanChoice == 's'))) { cout << "\nSorry that's an invalid response. Please try again!\n" << "Rock, Paper or Scissors? (enter r, p or s) : "; cin >> humanChoice; } // ----------------------------------------------- // DECIDE THE WINNER & AWARD MONEY. // ----------------------------------------------- // Check if human wins. // Rock beats scissors, Paper beats rock, Scissors beats paper. // If the choices are the same, game is a draw. // If none of the 3 cases for the human to win are true, // and the game is not a draw, then the computer wins. if (((humanChoice == 'r') && (computerChoice == 's')) || ((humanChoice == 'p') && (computerChoice == 'r')) || ((humanChoice == 's') && (computerChoice == 'p'))) humanRoundResult = WIN; else if (humanChoice == computerChoice) humanRoundResult = DRAW; else humanRoundResult = LOSE; // Output round result & update scores. if (humanRoundResult == WIN ) { humanBal += pot; cout << "\nYOU WIN!\n"; // Destroy's computer's winning streak streak = 0; } else if (humanRoundResult == LOSE ) { computerBal += pot; if (streak < ULTIMATE_STREAK) streak++; cout << "\nCOMPUTER WINS!\n"; } else { humanBal += (pot / 2); computerBal += (pot / 2); if (streak < ULTIMATE_STREAK) streak++; cout << "\nDRAW!\n"; } // ----------------------------------------------- // OUTPUT PLAYER CHOICES & KEEP TALLY. // ----------------------------------------------- // Output computer choice. cout << "\tComputer chose : "; switch (computerChoice) { case 'r': cout << "Rock\n"; computerChoseR++; break; case 'p': cout << "Paper\n"; computerChoseP++; break; case 's': cout << "Scissors\n"; computerChoseS++; } // Output human choice. cout << "\tHuman chose : "; switch (humanChoice) { case 'r': cout << "Rock\n"; humanChoseR++; break; case 'p': cout << "Paper\n"; humanChoseP++; break; case 's': cout << "Scissors\n"; humanChoseS++; } cout << "\tBalances: You = $" << humanBal << "\tComputer = $" << computerBal << endl; // Keep track of # of rounds played. roundsCnt++; } // end while. // ----------------------------------------------- // OUTPUT WINNER & GAME STATS // ----------------------------------------------- // Output game winner. cout << "\n*** GAME OVER ***\n"; if (humanBal > 0) cout << "\n\tYOU WIN THE GAME! Congratulations!\n"; else cout << "\n\tCOMPUTER WINS THE GAME! Better luck next time!\n\n"; // Calculate game statistics for computer. comRockPercent = static_cast(computerChoseR) / roundsCnt * 100; comPaperPercent = static_cast(computerChoseP) / roundsCnt * 100; comScissorsPercent = static_cast(computerChoseS) / roundsCnt * 100; // Calculate game statistics for human. humRockPercent = static_cast(humanChoseR) / roundsCnt * 100; humPaperPercent = static_cast(humanChoseP) / roundsCnt * 100; humScissorsPercent = static_cast(humanChoseS) / roundsCnt * 100; cout << "\n*** GAME STATISTICS ***\n"; // Format output of percentages. cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(1); // Output game statistics for computer. cout << "\nComputer choices:\n" << "\tRock " << comRockPercent << "%\n" << "\tPaper "<< comPaperPercent << "%\n" << "\tScissors "<< comScissorsPercent << "%\n"; // Output game statistics for human. cout << "\nHuman choices:\n" << "\tRock " << humRockPercent << "%\n" << "\tPaper "<< humPaperPercent << "%\n" << "\tScissors "<< humScissorsPercent << "%\n"; cout << endl; return 0; } // end main.