Stumped on Rock Paper Scissors against Computer

Hello everyone. So I need to create Rock, Paper, Scissors game with player 1 being a user and player 2 being the computer. Most of this code was provided by the professor but I fiddled with some of it. Player2 is the only function I created.

The original code had player 2 as another user. In order to change player 2 to the computer, I figured I need to make a function that generates a random number between 1 and 3 and then assigns that number to enum ROCK, PAPER, SCISSOR.

I spent nearly 10 hours trying to get Player2() to be useful but it barely runs. Now it's simply providing 9 digit numbers all throughout the code when I compile it. It's also giving me a run time error.

Is there a better way to generate a random number? Is it possible for me to assign numbers to enum types? Should the Player2 function be embedded into one of the existing functions? How can I bring a useful obejectType into the Player2 function? What about my number generator is causing 9 digit numbers to form?

Any guidance is greatly appreciated!
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
  #include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>

using namespace std;

enum objectType { ROCK, PAPER, SCISSORS };



//Function prototypes
void displayRules();
objectType retrievePlay(char selection);
int Player2();
bool validSelection(char selection);
void convertEnum(objectType object);
objectType winningObject(objectType play1, objectType play2);
void gameResult(objectType play1, objectType play2,
	int& winner);
void displayResults(int gCount, int wCount1, int wCount2);

int main()
{


	//srand(time(NULL));
	//Step 1
	int gameCount; //variable to store the number of
				   //games played
	int winCount1; //variable to store the number of games
				   //won by player 1
	int winCount2; //variable to store the number of games
				   //won by player 2
	int gamewinner;
	char response;  //variable to get the user's response to
					//play the game
	char selection1;
	//int selection2;

	objectType play1;  //player1's selection
					   //objectType play2;  //player2's selection
	objectType play2;
	//Initialize variables; Step 2
	gameCount = 0;
	winCount1 = 0;
	winCount2 = 0;

	displayRules();                               //Step 3

	int compChoice;
	compChoice = Player2();

	cout << "Enter Y/y to play the game: ";       //Step 4
	cin >> response;                              //Step 5
	cout << endl;

	while (response == 'Y' || response == 'y')   //Step 6
	{
		cout << "Player 1 enter your choice: ";   //Step 6a
		cin >> selection1;                        //Step 6b
		cout << endl;

		//cout << "Player 2 enter your choice: ";   //Step 6c
		cout << "The computer chose: " << Player2();                      
 //Step 6d
 //cout << endl;
//Step 6e
		if (validSelection(selection1)
			&& Player2())
		{
			play1 = retrievePlay(selection1);
			play2 = retrievePlay(compChoice);
			gameCount++;                          //Step 6e.i
			gameResult(play1, play2, gamewinner); //Step 6e.ii

			if (gamewinner == 1)                  //Step 6e.iii
				winCount1++;
			else if (gamewinner == 2)
				winCount2++;
		}//end if

		cout << "Enter Y/y to play the game: ";   //Step 6f
		cin >> response;                          //Step 6g
		cout << endl;
	}//end while

	displayResults(gameCount, winCount1,
		winCount2);                    //Step 7

	return 0;
}//end main

void displayRules()
{
	cout << "  Welcome to the game of Rock, Paper, "
		<< "and Scissors." << endl;
	cout << "This is a game for two players. The second "
		<< "player is the computer." << endl;
	cout << "For each game, each" << endl;
	cout << " player selects one of the objects, Rock, "
		<< "Paper or Scissors." << endl;
	cout << " The rules for winning the game are: " << endl;
	cout << "1. If both players selects the same object, it "
		<< "is a tie." << endl;
	cout << "2. Rock breaks Scissors: So player who selects "
		<< "Rock wins." << endl;
	cout << "3. Paper covers Rock: So player who selects "
		<< "Paper wins." << endl;
	cout << "4. Scissors cuts Paper: So player who selects "
		<< "Scissors wins." << endl << endl;
	cout << "Enter R or r to select Rock, P or p to select "
		<< "Paper, and S or s to select Scissors." << endl;
}

bool validSelection(char selection)
{
	switch (selection)
	{
	case 'R':
	case 'r':
	case 'P':
	case 'p':
	case 'S':
	case 's':
	case '1':
	case '2':
	case '3':
		return true;
	default:
		return false;
	}
}


objectType retrievePlay(char selection)
{
	objectType object;
	//objectType compChoice = static_cast<objectType>(rand()%3 + 1);

	switch (selection)
	{
	case 'R':
	case 'r':
	case '1':
		object = ROCK;
		break;
	case 'P':
	case 'p':
	case '2':
		object = PAPER;
		break;
	case '3':
	case 'S':
	case 's':
		object = SCISSORS;
	}

	return object;
}

void convertEnum(objectType object)
{
	switch (object)
	{
	case ROCK:
		cout << "Rock";
		break;
	case PAPER:
		cout << "Paper";
		break;
	case SCISSORS: cout << "Scissors";
	}
}

objectType winningObject(objectType play1, objectType play2)
{
	if ((play1 == ROCK && play2 == SCISSORS)
		|| (play2 == ROCK && play1 == SCISSORS))
		return ROCK;
	else if ((play1 == ROCK && play2 == PAPER)
		|| (play2 == ROCK && play1 == PAPER))
		return PAPER;
	else
		return SCISSORS;
}

void gameResult(objectType play1, objectType play2,
	int& winner)
{
	objectType winnerObject;

	if (play1 == play2)
	{
		winner = 0;
		cout << "Both players selected ";
		convertEnum(play1);
		cout << ". This game is a tie." << endl;
	}
	else
	{
		winnerObject = winningObject(play1, play2);

		//Output each player's choice
		cout << "Player 1 selected ";
		convertEnum(play1);
		cout << " and player 2 selected ";
		convertEnum(play2);
		cout << ". ";

		//Decide the winner
		if (play1 == winnerObject)
			winner = 1;
		else if (play2 == winnerObject)
			winner = 2;

		//Output the winner
		cout << "Player " << winner << " wins this game."
			<< endl;
	}
}
int Player2()
{
	int compChoice;
	//srand(time(0));
	compChoice = rand() % 3 + 1;


	if (compChoice == 1)
	{

		compChoice = retrievePlay('r');
		cout << retrievePlay << endl;
	}
	else if (compChoice == 2)
	{
		compChoice = retrievePlay('p');
		cout << retrievePlay << endl;
	}
	else
	{
		compChoice = retrievePlay('s');
		cout << retrievePlay << endl;
	}

	return (compChoice);
}

void displayResults(int gCount, int wCount1, int wCount2)
{
	cout << "The total number of plays: " << gCount
		<< endl;
	cout << "The number of plays won by player 1: "
		<< wCount1 << endl;
	cout << "The number of plays won by player 2: "
		<< wCount2 << endl;
}
Last edited on
Lines 233, 238, 243: What is this "value" retrievePlay that you print?
Line 27: Uncomment this line. This is the correct place to seed the RNG.

Line 52: Why are you calling Player2() here?

Line 65: Player2() is going to return a random value and that is going to be displayed. But that value is not going to be used at line 73. Should be this instead:
1
2
    compChoice = Player2();
    cout << "The computer chose: " << compChoice << endl;         


Line 54: It's a little silly asking here if you want to play the game. Initialize response to 'Y' instead.

Line 83: This should say "Play again?"

Line 233, 238, 243: You're displaying the address of the function. You're not calling the function. This is why you're getting 8 digits. Since you set compChoice on the previous line, you really want to be displaying compChoice.

Line 141: You have problems with this switch statement. You have cases for ASCII '1', '2' and '3'. However the values of your enum are binary 0, 1, 2.

Line 226: Your random number is not going to line up with your enum. enums, if not explicitly assigned, start at 0. Your random number is going to be 1-3.
Last edited on
A data driven approach would be simpler. Something along these lines:

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
#include <iostream>
#include <cctype>
#include <cstdlib>
#include <ctime>

enum object { ROCK, PAPER, SCISSORS, NUM_OBJECTS, INVALID = -1 };
const char* const object_name[NUM_OBJECTS] = { "Rock", "Paper", "Scissors" } ;

const bool result[NUM_OBJECTS][NUM_OBJECTS] = { { 0, 0, 1 }, { 1, 0, 0 }, { 0, 1, 0 } } ;

const char* const msg[NUM_OBJECTS][NUM_OBJECTS] =
{
    { "It is a tie!", "Paper wins. Paper covers Rock", "Rock wins. Rock breaks Scissors" },
    { "Paper wins. Paper covers Rock", "It is a tie!", "Scissors wins. Scissors cuts Paper" },
    { "Rock wins. Rock breaks Scissors", "Scissors wins. Scissors cuts Paper", "It is a tie!" },
};

object char_to_object( char c )
{
    c = std::toupper(c) ;
    for( int i = 0 ; i < NUM_OBJECTS ; ++i ) if( object_name[i][0] == c ) return object(i) ;
    return INVALID ;
}

object choose_object()
{
    std::cout << "\nenter your choice R/P/S [(R)ock (P)aper (S)cissors]: " ;
    char c ;
    std::cin >> c ;

    object obj = char_to_object(c) ;
    if( obj != INVALID )
    {
        std::cout << "Player chooses " << object_name[obj] << '\n' ;
        return obj ;
    }

    std::cout << "invalid input. try again\n" ;
    return choose_object() ;
}

object generated_choice()
{
    const auto obj = object( std::rand() % NUM_OBJECTS ) ;
    std::cout << "Computer chooses " << object_name[obj] << '\n' ;
    return obj ;
}

bool again()
{
    std::cout << "\nplay again? (Y/N)? " ;
    char c ;
    std::cin >> c ;
    return c == 'y' || c == 'Y' ;
}

int main()
{
    std::srand( std::time(nullptr) ) ;

    int num_wins_player = 0 ;
    int num_wins_computer = 0 ;
    int num_ties = 0 ;

    do
    {
        const object one = choose_object() ;
        const object two = generated_choice() ; // choose_object(2) ;

        std::cout << "\nPlayer's " << object_name[one] << " vs Computer's " << object_name[two] << '\n'
                  << "result: " << msg[one][two] << '\n' ;

        if( one == two ) ++num_ties ;
        else if( result[one][two] ) ++num_wins_player ;
        else ++num_wins_computer ;

        std::cout << "\nResult so far:\n------------\n"
                  << "          total: " << num_wins_player + num_wins_computer + num_ties << '\n'
                  << "  won by player: " << num_wins_player << '\n'
                  << "won by computer: " << num_wins_computer << '\n'
                  << "           ties: " << num_ties << '\n' ;
    }
    while( again() ) ;
}
Topic archived. No new replies allowed.