Please look at my code that simulates dice game

I'm up to Programming Project 11 in Chapter 3 of Walt Savitch's Absolute C++ book.

Could you guys have a look at what I've done and see if it's the best way or not, given that I'm a beginner I have no idea!

I haven't covered arrays or classes or structures, etc, yet.

Thanks

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
/*The game of Pig is a simple two player dice game in which the first player to
reach 100 or more points wins. Players take turns. On each turn a player rolls a
six-sided die. After each roll:

	If the player rolls a 2-6 then he can either:
	
	— ROLL AGAIN
	
	or
	
	— HOLD. At this point the sum of all rolls made this turn is added to the
			player’s total score and it becomes the other player’s turn.

	If the player rolls a 1 then the player loses his turn. He gets no new points and
	it becomes the opponent’s turn.

If a player reaches 100 or more points after holding then the player wins.

Write a program that plays the game of Pig, where one player is a human and the
other is the computer. Allow the human to input “r” to roll again or “h” to hold.
The computer program should play according to the following rule:

Keep rolling on the computer's turn until it has accumulated 20 or more points, then hold.
Of course, if the computer wins or rolls a 1 then the turn ends immediately.
Allow the human to roll first. Write your program using at least two functions:

	int humanTurn(int humanTotalScore);
	int computerTurn(int computerTotalScore);

These functions should perform the necessary logic to handle a single turn for
either the computer or the human. The input parameter is the total score for the
human or computer. The functions should return the turn total to be added to
the total score upon completion of the turn. For example, if the human rolls a 3
and 6 and then holds, then humanTurn should return 9. However, if the human
rolls a 3 and 6 and then a 1, then the function should return 0.*/

#include <iostream>
#include <cstdlib>

using std::cout;
using std::cin;
using std::endl;

int dieRoll();
int humanTurn(int);
int computerTurn(int);

int main()
{
	int humanTotalScore = 0, computerTotalScore = 0;
		
	//loop to keep playing until someone scores 100+
	do
	{
		humanTotalScore = humanTotalScore + humanTurn(humanTotalScore); //add the score from a new turn to the running total
		cout << "Your total score so far is " << humanTotalScore << "." << endl;
		if(humanTotalScore >= 100)
		{
			cout << "You win!";
			break;
		}
		computerTotalScore = computerTotalScore + computerTurn(computerTotalScore); //add the score from a new turn to the running total
		cout << "CPU total score so far is " << computerTotalScore << "." << endl;
		if(computerTotalScore >= 100)
		{
			cout << "Computer wins!";
			break;
		}
	}
	while(humanTotalScore < 100 && computerTotalScore < 100);
		
	return 0;
}

//simulate rolling of die
int dieRoll()
{
		return (rand() % 6) + 1; //call to rand() returns 0-5, + 1 to give range 1-6, best way to avoid impossible die roll of 0
}

int humanTurn(int humanTotalScore)
{
	int thisTurnScore = 0, score = 0;
	char rollOrHold;
	
	//loop to keep going as long the player chooses Roll Again or a 1 is thrown
	do
	{
			score = dieRoll(); //roll the die
		
		if(score == 1)
		{
			cout << "You rolled a 1.  End of turn." << endl;
			break;
		}
		
		thisTurnScore = thisTurnScore + score; //running total for this turn only
				
		cout << "You rolled a " << score << ".  Score so far this turn is " << thisTurnScore << "." << endl;
		cout << "Roll again (r) or Hold (h)? ";
		cin >> rollOrHold;
	}
	while(rollOrHold == 'r' || rollOrHold == 'R');
	
	if(rollOrHold == 'h' || rollOrHold == 'H') return thisTurnScore; //finsh turn and return total score if player chooses to Hold
		
	return 0; //will only get this far if player rolled a 1
}

int computerTurn(int computerTotalScore)
{
	int thisTurnScore = 0, score = 0;
	
	//loop to keep going as long the CPU score for this turn is less than 20
	do
	{
		score = dieRoll(); //roll the dice
		
		if(score == 1)
		{
			cout << "CPU rolled a 1.  End of turn." << endl;
			break;
		}
		
		thisTurnScore = thisTurnScore + score; //running total for this turn only
				
		cout << "CPU rolled a " << score << ".  Score so far this turn is " << thisTurnScore << "." << endl;
	}
	while(thisTurnScore < 20);

	//finsh turn and return total score if the CPU scored 20+
	if(thisTurnScore >= 20)
	{
		cout << "CPU holds." << endl;
		return thisTurnScore;
	}
		
	return 0; //will only get this far if CPU rolled a 1
}
It looks pretty good.

Only thing I noticed was in playerTurn: what happens if the user enters unexpected input, like 'g'?

Take a look:

1
2
3
4
5
6
7
8
9
10
11
12
	do
	{
		...
		cin >> rollOrHold;   // <<<assume user entered bad input, like 'g'
	}
	while(rollOrHold == 'r' || rollOrHold == 'R');  // <<<the loop will exit because g is not 'r' or 'R'
	
	// <<<'g' is not 'h' or 'H' so the player will not hold
	if(rollOrHold == 'h' || rollOrHold == 'H') return thisTurnScore; //finsh turn and return total score if player chooses to Hold
		
	// <<<so it will reach here (their score is totally trashed!)
	return 0; //will only get this far if player rolled a 1 
Also, you should call srand() in main(), otherwise you'll roll the same numbers every
time you run the program.
Disch: Actually I did think about that earlier, and meant to add code to catch users inputting an illegal character.

jsmith: Do I just call srand() as is, or do I need to pass a value into it?
Usually you can just pass the current timestamp as a seed like so: srand(time(NULL));
You'll need <ctime> for the time() function.
Walt Savitch provide the prototypes for turn-calculating functions:

1
2
	int humanTurn(int humanTotalScore);
	int computerTurn(int computerTotalScore);


And i'm see, that the parameters humanTotalScore and computerTotalScore is not used, but this is prompting. Then, suppose situation: human (computer) had 90 points, make a turn and obtain 20 points. 20+90=110 points and 1 (minimum) redundant turn. In other words, here turn finishes when:
1)rolls a 1;
2) player holds,
and regardless of human(computer)TotalScore.
IMHO human(computer)TotalScore calculation and checking must be placed inside turn function.

Sorry my English.
jsmith: Any reason I should call srand() in main() and not in dieRoll()?

mechanicus: Thanks, I didn't calculate TotalScore inside turn function because the task asked me not to, it asked for the turn function to only return the score for that turn:

"The functions should return the turn total to be added to
the total score upon completion of the turn. For example, if the human rolls a 3
and 6 and then holds, then humanTurn should return 9. However, if the human
rolls a 3 and 6 and then a 1, then the function should return 0"
Improved version:

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
/*The game of Pig is a simple two player dice game in which the first player to
reach 100 or more points wins. Players take turns. On each turn a player rolls a
six-sided die. After each roll:

	If the player rolls a 2-6 then he can either:
	
	— ROLL AGAIN
	
	or
	
	— HOLD. At this point the sum of all rolls made this turn is added to the
			player’s total score and it becomes the other player’s turn.

	If the player rolls a 1 then the player loses his turn. He gets no new points and
	it becomes the opponent’s turn.

If a player reaches 100 or more points after holding then the player wins.

Write a program that plays the game of Pig, where one player is a human and the
other is the computer. Allow the human to input “r” to roll again or “h” to hold.
The computer program should play according to the following rule:

Keep rolling on the computer's turn until it has accumulated 20 or more points, then hold.
Of course, if the computer wins or rolls a 1 then the turn ends immediately.
Allow the human to roll first. Write your program using at least two functions:

	int humanTurn(int humanTotalScore);
	int computerTurn(int computerTotalScore);

These functions should perform the necessary logic to handle a single turn for
either the computer or the human. The input parameter is the total score for the
human or computer. The functions should return the turn total to be added to
the total score upon completion of the turn. For example, if the human rolls a 3
and 6 and then holds, then humanTurn should return 9. However, if the human
rolls a 3 and 6 and then a 1, then the function should return 0.*/

#include <iostream>
#include <cstdlib>
#include <ctime>

using std::cout;
using std::cin;
using std::endl;

int dieRoll();
int humanTurn(int);
int computerTurn(int);

int main()
{
	int humanTotalScore = 0, computerTotalScore = 0;
	
	srand(time(NULL)); //set a different seed for rand() every time to get different game outputs
		
	//loop to keep playing until someone scores 100+
	do
	{
		humanTotalScore = humanTotalScore + humanTurn(humanTotalScore); //add the score from a new turn to the running total
		cout << "Your total score so far is " << humanTotalScore << "." << endl;
		if(humanTotalScore >= 100)
		{
			cout << "You win!";
			return 0;
		}
		computerTotalScore = computerTotalScore + computerTurn(computerTotalScore); //add the score from a new turn to the running total
		cout << "CPU total score so far is " << computerTotalScore << "." << endl;
		if(computerTotalScore >= 100)
		{
			cout << "Computer wins!";
			return 0;
		}
	}
	while(humanTotalScore < 100 && computerTotalScore < 100);
}

//simulate rolling of die
int dieRoll()
{
	return (rand() % 6) + 1; //call to rand() returns 0-5, + 1 to give range 1-6, best way to avoid impossible die roll of 0
}

int humanTurn(int humanTotalScore)
{
	int thisTurnScore = 0, score = 0;
	char rollOrHold;
	
	//loop to keep going as long the player chooses Roll Again or a 1 is thrown
	do
	{
		score = dieRoll(); //roll the die
		
		if(score == 1)
		{
			cout << "You rolled a 1.  End of turn." << endl;
			return 0;
		}
		
		thisTurnScore = thisTurnScore + score; //running total for this turn only
				
		cout << "You rolled a " << score << ".  Score so far this turn is " << thisTurnScore << "." << endl;
				
		//loop to keep asking, if user inputs illegal character
                do
		{
			cout << "Roll again (r) or Hold (h)? ";
			cin >> rollOrHold;
		}
		while(rollOrHold != 'r' && rollOrHold != 'R' && rollOrHold != 'h' && rollOrHold != 'H');
	}
	while(rollOrHold == 'r' || rollOrHold == 'R');
	
	if(rollOrHold == 'h' || rollOrHold == 'H') return thisTurnScore; //finsh turn and return total score if player chooses to Hold
}

int computerTurn(int computerTotalScore)
{
	int thisTurnScore = 0, score = 0;
	
	//loop to keep going as long the CPU score for this turn is less than 20
	do
	{
		score = dieRoll(); //roll the dice
		
		if(score == 1)
		{
			cout << "CPU rolled a 1.  End of turn." << endl;
			return 0;
		}
		
		thisTurnScore = thisTurnScore + score; //running total for this turn only
				
		cout << "CPU rolled a " << score << ".  Score so far this turn is " << thisTurnScore << "." << endl;
	}
	while(thisTurnScore < 20);

	//finsh turn and return total score if the CPU scored 20+
	if(thisTurnScore >= 20)
	{
		cout << "CPU holds." << endl;
		return thisTurnScore;
	}
}
Last edited on
Topic archived. No new replies allowed.