May 8, 2018 at 6:52pm UTC
I'm trying to recreate rock paper scissors for a class, and for whatever reason the program doesn't allow the user to enter any information after the first round. Everything seems to work fine until after the user says they'd like to play again, then it skips every cin causing it to loop infinitely displaying
"Try Again?(Y/N): "
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
#include <time.h>
#include <iostream>
#include <stdlib.h>
using namespace :: std;
enum choice{rock=1,paper=2,scissors=3};
int PScore=0;
int CScore=0;
string player_name;
string cpu_name;
string FindWinner(choice player, choice cpu)
{
if (player==cpu)
return ("tie" );
else
switch (player)
{
case 1: if (cpu==2) return ("cpu" ); else return ("player" );
case 2: if (cpu==3) return ("cpu" ); else return ("player" );
case 3: if (cpu==1) return ("cpu" ); else return ("player" );
}
}
void AreYouSure()
{
bool done=false ;
while (done==false )
{
char ans;
cout << "Are you sure that's your final decision?(Y/N): " ;
cin >> ans;
if ((ans=='Y' )||(ans=='N' )||(ans=='n' )||(ans=='y' ))
done=true ;
}
}
void DisplayChoice(choice x)
{
switch (x)
{
case 1:cout << "Rock" << endl; break ;
case 2:cout << "Paper" << endl; break ;
case 3:cout << "Scissors" << endl; break ;
}
}
void Results()
{
cout << player_name << "'s (W/L): " << PScore << "/" << CScore << endl;
cout << cpu_name << "'s (W/L): " << CScore << "/" << PScore << endl;
}
void DisplayChoices(choice player, choice cpu)
{
cout << "--------Results--------" << endl;
cout << player_name << ": " ;
DisplayChoice(player);
cout << cpu_name << ": " ;
DisplayChoice(cpu);
}
choice PlayerAction()
{
string action;
do
{
cout << "Enter an action(rock/paper/scissors): " ;
cin >> action;
}while ((action!="scissors" ) && (action!="rock" ) && (action!="paper" ));
if (action == "scissors" )
return (choice(3));
else if (action == "rock" )
return (choice(1));
else
return (choice(2));
}
void PlayGame()
{
choice player=PlayerAction();
choice cpu=choice(rand() % 3 + 1);
DisplayChoices(player,cpu);
string winner = FindWinner(player,cpu);
if (winner=="cpu" )
{
cout << cpu_name << " wins!" << endl;
CScore++;
}
else if (winner=="tie" )
cout << "It was a tie!" << endl;
else
{
cout << player_name << " wins!" << endl;
PScore++;
}
}
int main()
{
int cont='Y' ;
char start;
cout << "--------Rock-Paper-Scissors--------" << endl;
cout << "Enter your name: " ;
cin >> player_name;
cout << "Enter your opponent's name: " ;
cin >> cpu_name;
cout << "Are you ready to play?(Y/N): " ;
cin >> start;
while ((cont!='N' ) && (cont!='n' ))
{
if ((start=='N' )||(start=='n' ))
{
cout << "Are you ready now, that you have had some time to think it over?(Y/N): " ;
cin >> start;
}
else
{
PlayGame();
do
{
cout << "Try Again? (Y/N):" ;
cin >> cont;
} while ((cont!='N' ) && (cont!='n' ) && (cont!='y' ) && (cont!='Y' ));
}
}
Results();
return 0;
}
Last edited on May 8, 2018 at 7:05pm UTC
May 8, 2018 at 7:06pm UTC
You have
cont as an int, but your user prompts imply you want the user to enter a character (Y or N).
In general, to prevent std::cin from going haywire after bad input, do something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include <iostream>
#include <limits>
int main()
{
int a;
while (true )
{
if (!(std::cin >> a))
{
std::cout << "Bad input!\n" ;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n' );
}
else
{
std::cout << "You entered " << a << std::endl;
}
}
}
Last edited on May 8, 2018 at 7:07pm UTC
May 8, 2018 at 8:20pm UTC
Hello J0HND03,
As Ganado demonstrated that was also my first suggestion until I realized that line 103 is the real problem. Just change the "int" to a "char" and all the problems are solves.
What is happening is the formatted "cin >> cont" is expecting an "int" and you are trying to give it a char causing the state bits of "cin" to be set putting "cin" in a failed state and not allowing anything to come from the keyboard. That is where Ganado's solution comes in.
Include the header file <cctype> and use the functions "std::toupper(?)" or "std::tolower(?)" with the '?' being the variable name you wish to change.
Hope that helps,
Andy
May 9, 2018 at 12:13am UTC
Thanks, I just didn't realize that I had cont as an int. Changing that solved the problem. Kinda embarrassing that I didn't realize that sooner. Regardless thank you very much for your help.