Paper, rock, scissor game

I just wrote a program for Paper, rock, scissor game.

Is this correct?

#include <iostream>
using namespace std;

int main()
{
char a,b;

cout<<"p = paper"<<endl;
cout<<"r = rock"<<endl;
cout<<"s = scissor"<<endl;

cout<<"Player 1 choose"<<endl;
cin>>a;

cout<<"Player 2 choose"<<endl;
cin>>b;


if ((a=='r') && (b=='r') || (a=='p') && (b=='p') || (a=='s') && (b=='s') )
{
cout<<"tie";
}

else if ((a=='p') && (b=='r') || (a=='r') && (b=='s') || (a=='s') && (b=='p') )
{
cout<<"Player 1 won";
}
else if ((a=='r') && (b=='p') || (a=='s') && (b=='r') || (a=='p') && (b=='s') )
{
cout<<"Player 2 won";
}
}


Add a line of validation to check if the player selected a correct move and then just compare if a = b for the tie check so it reads better.
this condition is sufficient for tie
1
2
if(a==b)
   std::cout<<"tie"<<std::endl;
else if ((a=='r') && (b=='p') || (a=='s') && (b=='r') || (a=='p') && (b=='s') ) This should be else if ((a=='r' && b=='p') || (a=='s' && b=='r') || (a=='p' && b=='s') ) The first one needs to be similar also. Btw you could just do an else for the tie.
Last edited on
to make the game more versatile you also have to account human error.....
like
1
2
if(a!='r' || a!='p' || a!='s' )
cout<<"invalid";//etc........ 

then you can create a loop to re-enter input.......
@programmer007:

if(a!='r' || a!='p' || a!='s' )

This condition will always be true.

You probably wanted && here instead of ||.

Although any time you are stringing together a bunch of &&s or ||s you should probably reconsider your approach. There is usually a better way.


EDIT:

for instance this:

1
2
if ((a=='r') && (b=='r') || (a=='p') && (b=='p') || (a=='s') && (b=='s') )
// tie 


is largely redundant. You could greatly simplify this like so:

1
2
if(a == b)
// tie 
Last edited on
@disch

what if the user puts an input not expected by program???
Validating input should not be part of the game logic. That should be done (if it's going to be done) prior to the first if condition.
To make the logic easier, convert the user's input to lower (or upper) case. You'll also want to validate it as others have said. You could put all this in a function:

1
2
3
4
5
bool normalize(char &c)
{
    c = tolower(c);
    return c == 'r' || c == 'p' || c == 's';
}


You might also put the logic for a winner into a function:
1
2
3
4
5
6
// Return true if FIRST beats SECOND. Both parameters must be normalized
// (i.e., either 'r', 'p' or 's')
firstIsWinner(char first, char second)
{
    return  first=='p' && second=='r' || first=='r' && second=='s' || first=='s' && second=='p';
}


Now your main logic gets easier and your code can double check itself:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cout<<"Player 1 choose"<<endl;
cin>>a;
if (!normalize(a)) return 1;

cout<<"Player 2 choose"<<endl;
cin>>b;
if (!normalize(b)) return 1;

if (a ==b )
{
    cout<<"tie";
}
else if (firstIsWinner(a,b) )
{
    cout<<"Player 1 won";
}
else if (firstIsWinner(b,a) )
{
    cout<<"Player 2 won";
} else {
    cout << "Logic error!";
}
return 0;
I thank you all. :)
try this too:
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
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;

char a,b;
string PLAYER_1,PLAYER_2;
string YN;
int x;
int main()
{
while(x!=1){
cout << "Enter your name:"<<endl;
cin >> PLAYER_1;
cout << "Enter your name:"<<endl;
cin >> PLAYER_2;
system("cls");

cout<<"P = paper"<<endl;
cout<<"R = rock"<<endl;
cout<<"S = scissor"<<endl;

cout<<"Player 1 choose"<<endl;
cin>>a;
system("cls");

cout<<"P = paper"<<endl;
cout<<"R = rock"<<endl;
cout<<"S = scissor"<<endl;

cout<<"Player 2 choose"<<endl;
cin>>b;
system("cls");

if ((a=='r'||a=='R') && (b=='r'||b=='R') || (a=='p'||a=='P') && (b=='p'||b=='P') || (a=='s'||a=='S') && (b=='s'||b=='S') )
{
cout<<"\n\n\n\n\n\n\n\n\n\n\n                                                   "<<PLAYER_1<<" and "<<PLAYER_2<<" TIE!";
}

else if ((a=='p'||a=='P') && (b=='r'||b=='R') || (a=='r'||a=='R') && (b=='s'||b=='S') || (a=='s'||a=='S') && (b=='p'||b=='P') )
{
cout<<"\n\n\n\n\n\n\n\n\n\n\n                                                   "<< PLAYER_1 <<" WON!";
}
else if ((a=='r'||a=='R') && (b=='p'||b=='P') || (a=='s'||a=='S') && (b=='r'||b=='R') || (a=='p'||a=='P') && (b=='s'||b=='S') )
{
cout<<"\n\n\n\n\n\n\n\n\n\n\n                                                   "<< PLAYER_2 <<" WON!\n";
}else cout << "Logic Error!";
cout << "\nHit the spacebar to play again";
Sleep(2000);
if(GetAsyncKeyState(VK_SPACE)){
    system("cls");
}else{x=1;}}
system("cls");
cout << "Ending program in 2 seconds";
Sleep(2000);
system("cls");
system("exit");
}
Last edited on
Please use indentations.

1
2
3
4
if ((a=='r'||a=='R') && (b=='r'||b=='R') || (a=='p'||a=='P') && (b=='p'||b=='P') || (a=='s'||a=='S') && (b=='s'||b=='S') )
{
cout<<"\n\n\n\n\n\n\n\n\n\n\n                                                   "<<PLAYER_1<<" and "<<PLAYER_2<<" TIE!";
}
there are much better ways to check if it is a tie. Such as if neither player won then it is a tie. Or something like if(a == b) or better yet if(toupper(a) == toupper(b))

Check out his way http://www.cplusplus.com/forum/beginner/141476/#msg747686
Last edited on
kk
You don't have to right the tie statement. Think about it. If player 1 doesn't win.. and if player 2 doesn't win...then ...ELSE {cout << "tie" ; }
If player 1 doesn't win.. and if player 2 doesn't win...then ...ELSE {cout << "tie" ; }

It could also be a logic error
Last edited on
Technically speaking logic error shouldn't be within the game conditions. That should be checked while you get the input. I think I also mentioned the else on my earlier post. http://www.cplusplus.com/forum/beginner/141476/#msg747290
Topic archived. No new replies allowed.