Game of pig

The program is called Game of Pig I may have over thought it and made it to complex I tend to do this. Its a user verses the computer game first one to 100 wins. My issue is the user will hit 100 and the computer will take another turn. The program should stop after the user hits 100 but doesn't and then the other issue I'm having is when it asks if the user wants to play again entering y for yes nothing happens, the loop doesn't start back over. I have gone blind to this problem and I'm sure the answer is staring me in the face but I can't see it.

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
// Pigdice.cpp : the dice game of pig.
// Author: Ken Thompson
//Last modified: 9/13/12

#include "stdafx.h"
#include <string> 
#include <conio.h>
#include <iostream>
#include <time.h>


using namespace std;
int rollDice();
char playerRollsOrHolds(); 
char playAgain();
int playerTurn(int playerTotalScore);
int computerTurn(int computerTotalScore);

int _tmain(int argc, _TCHAR* argv[])
{
	srand(time(0));
	char keepPlaying;
	int playerCurrentScore=0;
	int computerCurrentScore=0;
	int playerTotalScore=0;
    int computerTotalScore=0;
    string playername;
	//char playGame; //commented out for testing
	char playAgain();
	char playerResponse;
	int playerRoll;
    /* commeted out for testing
         cout << "What is your name? \n";
         cin >> playername;
		 cout << "Shall we play a game " << playername << "? Y or N :\n";
		 cin >> playGame;
		 if (playGame == 'n' || playGame == 'N')
		 {  
			 cout << "You chose not to play today. Goodbye " << playername <<".\n" << endl; 
				 getch();
				 return 0;
		 }
			
    system("cls");
    
	cout << "                              Game of Pig                          \n" ;
	cout << "================================================================== \n" ;
    cout << "The goal of Pig is to reach 100 points or more before the other player does.\n";
    cout << "Each time you roll the playerRoll points are added to your turn total.\n";
    cout << "If you roll a 2-6, then you can choose to roll again or hold \n";
    cout << "If you hold, then the points are added to your score.\n";
    cout << "But if you roll a 1, then all your points for that turn are lost!\n";
	cout << endl;
    cout << endl;
	cout << "Press Enter to continue.\n";
	getch();
    system("cls");
    
	cout << "                              Game of Pig                         \n";
	cout << "==================================================================\n";
end comment out for testing*/
	 
      do
    { 
		
      playerTotalScore=playerTurn(playerTotalScore);
      computerTotalScore=computerTurn(computerTotalScore);
    
    if (playerTotalScore>=100 && computerTotalScore<=99)
    {
       cout << " Congradulations " << playername << ", you win!\n";
    }
    
    if (playerTotalScore<=99 && computerTotalScore>=100)
    {
       cout << "Sorry " << playername << ", you lost.\n";
    }
  
	}
    while (playerTotalScore<=99 && computerTotalScore<=99);
	{
	}
	
	keepPlaying = playAgain();
    while (keepPlaying == 'y' || keepPlaying == 'Y');
	{
		cout << "A strange game. The only winning move is not to play.\n";
		cout << "How about a nice game of chess?\n";
	}
    getch();
}
int playerTurn(int playerTotalScore)
{
    int playerCurrentScore =0;
	int rollDice();
    char playerResponse;
    
    
    do 
      { 
	  playerResponse = 'R';
	  int rollDice();
      int playerRoll = rollDice(); 
      cout << "Player rolled a " << playerRoll << endl;
      
      if (playerRoll == 1)  
      {
            cout << "Player score for this round is lost. \n";  
            playerCurrentScore = 0;
			break;
      }
      else
      {
            playerCurrentScore += playerRoll;
            cout << "Player current total : " << playerCurrentScore << ". \n"; 
            playerResponse = playerRollsOrHolds();
            if (playerResponse !='r' && playerResponse != 'R')
			{
            playerTotalScore+=playerCurrentScore;
                        cout << " Player total score : " << playerTotalScore << ".\n";
                        break;
            }
  
            else
               continue;
      }
      }
      while (playerResponse == 'r' || playerResponse == 'R');
	  {
      return playerTotalScore;
	  }
}

int computerTurn(int computerTotalScore)
{
    int computerCurrentScore=0;

    do
    { 
      int playerRoll = rollDice(); 
      cout << "Computer rolled a " << playerRoll << ". \n";
      
      if (playerRoll == 1)  
      {
            cout << "Computer's score for this round is lost. \n";  
            computerCurrentScore = 0;
			break;
      }
      else
      {
            computerCurrentScore+= playerRoll;
            cout << "Computer's current total is " << computerCurrentScore << ".\n";
            if (computerCurrentScore>=20)
			{
            computerTotalScore+=computerCurrentScore;
                        cout << "Then computer hold. Computer's total score : " << computerTotalScore << ".\n";
            }
            
            
            else
               continue;
      }
      }
      while (computerCurrentScore<=19);
	  {
      return computerTotalScore;
      }
}
//Functions

int rollDice()
{
	return rand()%6+1;
}

char playerRollsOrHolds()
{
	char playerResponse;
	cout << "Would you like to Roll or Hold (R or H): ";
				cin >> playerResponse;
				return playerResponse;
}
	
char playAgain()
{
	char keepPlaying;
	cout << "Would you like to play again? (y or n) ";
				cin >> keepPlaying;
				return keepPlaying;
}
@wyildcard

I believe the main problem is while (playerTotalScore<=99 && computerTotalScore<=99);. By using the && (and) both have to be true, to exit. Try using while (playerTotalScore<=99 || computerTotalScore<=99);, as || (or), will let it finish when either becomes true.
@ whitenite1
Thank you for your quick reply.
I tried changing while (playerTotalScore<=99 && computerTotalScore<=99) to while (playerTotalScore<=99 || computerTotalScore<=99);
the program completely skipped the play again option.

The output (would be easier if I could paste a screen shot) is as follows.

Player total score : 105.
Computer rolled a 4
Computer's current score is 4.
Computer rolled a 4
Computer's current score is 8.
Computer rolled a 6
Computer's current score is 14.
Computer rolled a 3
Computer's current score is 17.
Computer rolled a 2
Computer's current score is 19.
Computer rolled a 5
Computer's current score is 24.
Then the computer holds. Computer's total score : 71.
Congratulations , you win!
Player rolled a 1
Player score for this round lost.
Computer rolled a 1.
Computer's score for this round lost.
Congratulations , you win!
Player rolled a 4
Player current total : 4
Would you like to Roll or Hold (R or H):

Any other suggests, I'm completely open to them.
@wyildcard

Give me a little time, and I'll see what I can come up with. One question, though. When you choose to hold, shouldn't your score carry on to the next round? The way it is right now, I don't know if the player or the computer, could ever reach 100. Or, are you supposed to just get a higher score than your opponent each round, to win? Knowing this, I'll be better able to follow the game logic. Thanks in advance.
whitenite1
Yes the way it works right now the current score is added to the total score at hold and both the player and the computer can reach 100 or more.

This is the section of code that tallies the current score to the total score.
player
1
2
3
4
5
6
7
8
9
10
11
else
      {
            playerCurrentScore += playerRoll;
            cout << "Player current total : " << playerCurrentScore << ". \n"; 
            playerResponse = playerRollsOrHolds();
            if (playerResponse !='r' && playerResponse != 'R')
			{
            playerTotalScore+=playerCurrentScore;
                        cout << " Player total score : " << playerTotalScore << ".\n";
                        break;
            }


Computer
1
2
3
4
5
6
7
8
9
  else
      {
            computerCurrentScore+= playerRoll;
            cout << "Computer's current total is " << computerCurrentScore << ".\n";
            if (computerCurrentScore>=20)
			{
            computerTotalScore+=computerCurrentScore;
                        cout << "Then computer hold. Computer's total score : " << computerTotalScore << ".\n";
            }
Try using a bool type variable for play again - and use the toupper function when dealing with y, Y n, N chars, so then you have logic for just Y or N.


With this code:
1
2
3
4
5
while keepPlaying == 'y' || keepPlaying == 'Y');
	{
		cout << "A strange game. The only winning move is not to play.\n";
		cout << "How about a nice game of chess?\n";
	}


It doesn't start the game again.

Try:

1
2
3
4
5
6
7
8
bool keepPlaying = true;
while (keepPlaying) {
  //game code
//prompt for keep playing 
//toupper(answer);
//if (answer == 'N')
      keepPlaying = false;
}


Alternatively, you could use a bool Quit variable, with the logic reversed.

HTH

@wyildcard

The game now works as I believe you intended. When either you or the computer holds on the die throw, and end up with 100 or more, game ends. You then enter 'Y' or "N' as a response to play again. I added a clear screen function, to get away from the system call, and added the player name to the playerTurn function, so that the player's name is printed with their rolls. Change it back if you don't like it.
Interesting game.

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
// Game of Pig.cpp : main project file.
// Pigdice.cpp : the dice game of pig.
// Author: Ken Thompson
//Last modified: 9/13/12

#include "stdafx.h"
#include <string> 
#include <conio.h>
#include <iostream>
#include <ctime>
#include <Windows.h>


using namespace std;

int rollDice();
char playerRollsOrHolds(); 
char playAgain();
int playerTurn(int playerTotalScore, string playername);
int computerTurn(int computerTotalScore);
void ClearScreen();

int main()
{
	time_t t;
	srand((unsigned) time(&t));
	char keepPlaying = 'X';
	int playerCurrentScore=0;
	int computerCurrentScore=0;
	int playerTotalScore=0;
	int computerTotalScore=0;
	string playername = "Human";
	string Line(80,'_');
	string Pig(80,'=');
	char playGame;
	char playAgain();

	cout << "What is your name? \n";
	cin >> playername;
	cout << "Shall we play a game " << playername << "? Y or N :\n";
	cin >> playGame;
	playGame = toupper(playGame);
	if (playGame == 'N')
	{  
		cout << "You chose not to play today. Goodbye " << playername << endl; 
		_getch();
		return 0;
	}

	ClearScreen();

	cout << "                              Game of Pig                          \n" ;
	cout << "================================================================== \n" ;
	cout << "The goal of Pig is to reach 100 points or more before the other player does.\n";
	cout << "Each time you roll the playerRoll points are added to your turn total.\n";
	cout << "If you roll a 2-6, then you can choose to roll again or hold \n";
	cout << "If you hold, then the points are added to your score.\n";
	cout << "But if you roll a 1, then all your points for that turn are lost!\n";
	cout << endl;
	cout << endl;
	cout << "Press Enter to continue.\n";
	_getch();

	do
	{
		do
		{ 
			ClearScreen();
			cout << "                              Game of Pig                         \n";
			cout << Pig;
			cout << Line << endl << "\t\t" << playername << "'s total score = "
 << playerTotalScore << "\tComputer's total score = " << computerTotalScore
 << endl << Line << endl;
			if (computerTotalScore<100)
				playerTotalScore=playerTurn(playerTotalScore, playername);

			if (playerTotalScore<100)
				computerTotalScore=computerTurn(computerTotalScore);

		}while (playerTotalScore < 100  && computerTotalScore < 100);

		if (playerTotalScore>=100 && computerTotalScore<=99)
		{
			cout << " Congratulations " << playername << ", you win!" << endl;
		}

		if (playerTotalScore<=99 && computerTotalScore>=100)
		{
			cout << "Sorry " << playername << ", you lost." << endl;
		}

		keepPlaying = playAgain();
		if ( keepPlaying == 'N')
		{
			cout << Line << endl;
			cout << "A strange game. The only winning move is not to play." << endl;
			cout << "How about a nice game of chess?" << endl;
			cout << Line << endl;
			_getch();
		}
		playerTotalScore = 0;
		computerTotalScore = 0;
	}while (keepPlaying == 'Y');

}
int playerTurn(int playerTotalScore, string playername)
{
	int playerCurrentScore =0;
	int rollDice();
	char playerResponse;


	do 
	{ 
		playerResponse = 'R';
		int rollDice();
		int playerRoll = rollDice(); 
		cout << playername << " rolled a " << playerRoll << endl;

		if (playerRoll == 1)  
		{
			cout << playername << "'s score for this round was lost." << endl;  
			playerCurrentScore = 0;
			break;
		}
		else
		{
			playerCurrentScore += playerRoll;
			cout << playername << "'s current total : " << playerCurrentScore << ". \n"; 
			playerResponse = playerRollsOrHolds();
			if (playerResponse != 'R')
			{
				playerTotalScore+=playerCurrentScore;
				cout << endl << playername << "'s total score : " << playerTotalScore << endl;
				break;
			}

			else
				continue;
		}
	} while (playerResponse == 'R');
	return playerTotalScore;
}

int computerTurn(int computerTotalScore)
{
	int computerCurrentScore=0;

	do
	{ 
		int ComputerRoll = rollDice(); 
		cout << "Computer rolled a " << ComputerRoll << ". \n";
		Sleep(600); // Small delay so you watch screen.
		if (ComputerRoll == 1)  
		{
			cout << endl << "Computer's score for this round was lost." << endl;  
			computerCurrentScore = 0;
			break;
		}
		else
		{
			computerCurrentScore+= ComputerRoll;
			cout << endl << "Computer's current total is " << computerCurrentScore << endl;
			if (computerCurrentScore>=20)
			{
				computerTotalScore+=computerCurrentScore;
				cout << endl << "Computer chose hold. Computer's total score : " << computerTotalScore << endl;
			}
		}
	}
	while (computerCurrentScore<=19);
	{
		return computerTotalScore;
	}
}
//Functions

int rollDice()
{
	return rand()%6+1;
}

char playerRollsOrHolds()
{
	char playerResponse;
	cout << endl << "Would you like to Roll or Hold (R or H): ";
	do
	{
		cin >> playerResponse;
		playerResponse = toupper(playerResponse);
		if (playerResponse!='R' && playerResponse != 'H')
			cout << "Enter an 'R' or an 'H', only" << endl << endl;
	} while ( playerResponse !='R' && playerResponse != 'H'); 
	return playerResponse;
}

char playAgain()
{
	char keepPlaying;
	cout << "Would you like to play again? (y or n) ";
	do
	{
		cin >> keepPlaying;
		keepPlaying = toupper(keepPlaying);
		if (keepPlaying!='R' && keepPlaying != 'H')
			cout << "Enter only a 'Y' or an 'N', please!" << endl << endl;
	} while ( keepPlaying !='Y' && keepPlaying != 'N'); 

	return keepPlaying;
}

void ClearScreen()
  {
   DWORD n;
  DWORD size;
  COORD coord = {0};
  CONSOLE_SCREEN_BUFFER_INFO csbi;
  HANDLE h = GetStdHandle ( STD_OUTPUT_HANDLE );
  GetConsoleScreenBufferInfo ( h, &csbi );
  size = csbi.dwSize.X * csbi.dwSize.Y;
  FillConsoleOutputCharacter ( h, TEXT ( ' ' ), size, coord, &n );
  GetConsoleScreenBufferInfo ( h, &csbi );
  FillConsoleOutputAttribute ( h, csbi.wAttributes, size, coord, &n );
  SetConsoleCursorPosition ( h, coord );
  }
Last edited on
You got it whitenite1. Sorry it took so long to get back to you today long crazy day.
No problem wyildcard. If you have any questions on what I did, or why, please ask. I'll be happy to explain my reasoning.

EDIT::
I made a small boo-boo in the function of playAgain(). The 'if' statement has a sentence print out if the input is not 'R' or 'H', and of course, it should be 'Y' or 'N'.

corrected code..
1
2
3
4
5
6
7
8
9
10
11
12
13
char playAgain()
{
	char keepPlaying;
	cout << "Would you like to play again? (y or n) ";
	do
	{
		cin >> keepPlaying;
		keepPlaying = toupper(keepPlaying);
		if (keepPlaying!='Y' && keepPlaying != 'N')
			cout << "Enter only a 'Y' or an 'N', please!" << endl << endl;
	} while ( keepPlaying !='Y' && keepPlaying != 'N'); 
	return keepPlaying;
}
Last edited on
I do have a couple of questions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void ClearScreen()
  {
   DWORD n;
  DWORD size;
  COORD coord = {0};
  CONSOLE_SCREEN_BUFFER_INFO csbi;
  HANDLE h = GetStdHandle ( STD_OUTPUT_HANDLE );
  GetConsoleScreenBufferInfo ( h, &csbi );
  size = csbi.dwSize.X * csbi.dwSize.Y;
  FillConsoleOutputCharacter ( h, TEXT ( ' ' ), size, coord, &n );
  GetConsoleScreenBufferInfo ( h, &csbi );
  FillConsoleOutputAttribute ( h, csbi.wAttributes, size, coord, &n );
  SetConsoleCursorPosition ( h, coord );
  }


Could you explain this clear screen function and correct me if I'm wrong but wouldn't system(cls); perform the same thing?

and what is the difference between getch(); and _getch(); ?


( keepPlaying !='Y' && keepPlaying != 'N')

If you use a bool variable, then you can avoid the rather ugly code above, and avoid doing the test twice as well. Actually there are several places where keepPlaying is tested.

I also try to avoid using do loops wherever possible, they can almost always be written as a while or for loop.

There is an article on this site, all about system(cls); and the like.

HTH
@wyildcard

You asked..
what is the difference between getch(); and _getch(); ?


Not much, really, in my opinion. But my compiler gives the below warning, so I I just use the _getch();, to avoid it. I find the program works the same with either one. So, use you preference.

Warning C4996: 'getch': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _getch. See online help for details.


And TheIdeasMan already gave you the answer for system("cls");. See http://www.cplusplus.com/articles/j3wTURfi/ , for why system("cls"); is evil..
@TheIdeasMan
Thank you very much for your input. I am playing with your suggestion of using a bool variable. I 'll let you know if I can get it to work for me.
@whitenite1
Thanks for clearing up my questions. I have another question.
In my code I was using
#include <time.h>
and in your code you are using
1
2
#include <ctime>
#include <Windows.h> 

Could you explain the reason for this?
@wyildcard

You use <time.h> for C and you use <ctime> for C++. I also get the warning when compiling, so I just use <ctime>. I'm not sure if one has more built-in functions than the other, but I only use a few anyway, so I don't think it matters to much. You can continue using it, if you wish, if your compiler doesn't give you the warnings. Otherwise, it might be a good idea to use the other includes.

As to <windows.h>, it has the Sleep function I wanted to use to space out the rolls for the computer. It would happen so fast, sometimes I didn't know that my turn was over. I only figured it was because I saw my score starting over at 2 or more.
@ whitenite1.
Thank you for all your help and for answering my questions, I'm sure I will have plenty more down the road.
I actually increased the sleep time on the computer rolls because it was still too fast for me.
Topic archived. No new replies allowed.