Make a Reset() Function

I just finished making a hangman game and I can't figure out how to make a reset function

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
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <cstdlib>

void PlayGame();
void Rules();
std::string CreateHiddenWord(const std::string &SelectedTopic);
void PrintMan();
void PrintTopic(const std::string &SelectedTopic);
void PrintUnderscore(const std::string &HiddenWord, std::vector <char> &ReplaceUnderscore);
void CheckGameStatus(const std::vector <char> &ReplaceUnderscore, const std::string &HiddenWord);
std::string InputGuess();
std::vector <char> TestGuess(const std::string &Guess, const std::string &HiddenWord, std::vector <char> &ReplaceUnderscore);
void GameWon(const std::string &HiddenWord);
void GameLost(const std::string &HiddenWord);
void AskToPlayAgain();
void Reset();

int Errors = 0;

int main() {
	srand((unsigned int(time(NULL))));
	PlayGame();
	return 0;
}

void PlayGame() {
	std::vector <char> ReplaceUnderscore;

	const std::string Topic[] = { "Animals", "Football", "C++" };
	const std::string SelectedTopic = Topic[rand() % 3];

	std::string HiddenWord = CreateHiddenWord(SelectedTopic);

	Rules();

	while (true) {
		PrintMan();
		PrintTopic(SelectedTopic);
		PrintUnderscore(HiddenWord, ReplaceUnderscore);
		CheckGameStatus(ReplaceUnderscore, HiddenWord);

		std::string Guess = InputGuess();

		ReplaceUnderscore = TestGuess(Guess, HiddenWord, ReplaceUnderscore);
		std::cout << std::flush;
		system("CLS");
	}
}

void Rules() {
	std::cout << "Basic Rules: 1. 7 Chances For Errors. 2. Only use lowercase. 3. Use only 1 letter.\n\n";
}

std::string CreateHiddenWord(const std::string &SelectedTopic) {
	std::string HiddenWord;

	const std::string RandomAnimal[] = { "dog", "cat", "elephant", "monkey", "bird", "panda", "snake", "donkey" };
	const std::string RandomFootball[] = { "gators", "bulldogs", "patriots", "football", "kickoff", "quarter" };
	const std::string RandomCPP[] = { "switch", "for", "while", "vector", "class", "pointer", "array", "header" };

	switch (SelectedTopic[0]) {
	case 'A':
		HiddenWord = RandomAnimal[rand() % 8];
		break;
	case 'F':
		HiddenWord = RandomFootball[rand() % 6];
		break;
	case 'C':
		HiddenWord = RandomCPP[rand() % 8];
		break;
	}
	return HiddenWord;
}

void PrintMan() {
	switch (Errors) {
	case 0:
		std::cout << "    #######\n";
		std::cout << "    ##\n";
		std::cout << "    ##\n";
		std::cout << "    ##\n";
		std::cout << "    ##\n";
		std::cout << "    ##\n";
		std::cout << "   #########\n";
		break;
	case 1:
		std::cout << "    #######\n";
		std::cout << "    ##   |\n";
		std::cout << "    ##\n";
		std::cout << "    ##\n";
		std::cout << "    ##\n";
		std::cout << "    ##\n";
		std::cout << "   #########\n";
		break;
	case 2:
		std::cout << "    #######\n";
		std::cout << "    ##   |\n";
		std::cout << "    ##   @\n";
		std::cout << "    ##\n";
		std::cout << "    ##\n";
		std::cout << "    ##\n";
		std::cout << "   #########\n";
		break;
	case 3:
		std::cout << "    #######\n";
		std::cout << "    ##   |\n";
		std::cout << "    ##   @\n";
		std::cout << "    ##   |\n";
		std::cout << "    ##\n";
		std::cout << "    ##\n";
		std::cout << "   #########\n";
		break;
	case 4:
		std::cout << "    #######\n";
		std::cout << "    ##   | \n";
		std::cout << "    ##   @ \n";
		std::cout << "    ##  -| \n";
		std::cout << "    ##\n";
		std::cout << "    ##\n";
		std::cout << "   #########\n";
		break;
	case 5:
		std::cout << "    #######\n";
		std::cout << "    ##   | \n";
		std::cout << "    ##   @ \n";
		std::cout << "    ##  -|- \n";
		std::cout << "    ##\n";
		std::cout << "    ##\n";
		std::cout << "   #########\n";
		break;
	case 6:
		std::cout << "    #######\n";
		std::cout << "    ##   | \n";
		std::cout << "    ##   @ \n";
		std::cout << "    ##  -|- \n";
		std::cout << "    ##  / \n";
		std::cout << "    ##\n";
		std::cout << "   #########\n";
		break;
	case 7:
		std::cout << "    #######\n";
		std::cout << "    ##   | \n";
		std::cout << "    ##   @ \n";
		std::cout << "    ##  -|-\n";
		std::cout << "    ##  / \\\n";
		std::cout << "    ##\n";
		std::cout << "   #########\n";
		break;
	}

	std::cout << "\n\n";
}

void PrintTopic(const std::string &SelectedTopic) {
	std::cout << "Topic = " << SelectedTopic;
	std::cout << "\n\n";
}

void PrintUnderscore(const std::string &HiddenWord, std::vector <char> &ReplaceUnderscore) {
	std::vector <char> Output;

	if (ReplaceUnderscore.size() > 0) {
		if (ReplaceUnderscore.size() == 1) {
			for (size_t i = 0; i < HiddenWord.length(); i++) {
				if (ReplaceUnderscore[0] == HiddenWord[i]) {
					std::cout << HiddenWord[i] << " ";
				}
				else {
					std::cout << "_ ";
				}
			}
		}
		else {
			for (size_t i = 0; i < HiddenWord.length(); i++) {
				Output.push_back('_');
			}
			for (size_t j = 0; j < ReplaceUnderscore.size(); j++) {
				for (size_t i = 0; i < Output.size(); i++) {
					if (HiddenWord[i] == ReplaceUnderscore[j]) {
						Output[i] = ReplaceUnderscore[j];
					}
				}
			}
			for (size_t i = 0; i < Output.size(); i++) {
				std::cout << Output[i] << " ";
			}
		}
	}
	else {
		for (size_t i = 0; i < HiddenWord.length(); i++) {
			std::cout << "_ ";
		}
	}
	std::cout << "\n\n";
}

void CheckGameStatus(const std::vector <char> &ReplaceUnderscore, const std::string &HiddenWord) {
	std::string VectorString(ReplaceUnderscore.begin(), ReplaceUnderscore.end());
	int Repeat = 0;
	int Correct = 0;
	
	for (size_t j = 0; j < HiddenWord.length(); j++) {
		for (size_t i = 0; i < HiddenWord.length(); i++) {
			if (HiddenWord[j] == HiddenWord[i] && j != i) {
				Repeat += 1;
			}
		}
	}
	for (size_t j = 0; j < VectorString.length(); j++) {
		for (size_t i = 0; i < HiddenWord.length(); i++) {
			if (VectorString[j] == HiddenWord[i]) {
				Correct += 1;
			}
		}
	}
	Correct -= Repeat;

	if (Correct == VectorString.length() && Correct == HiddenWord.length()) {
		GameWon(HiddenWord);
	}
	else if (Errors == 7) {
		GameLost(HiddenWord);
	}
}

std::string InputGuess() {
	std::string Guess;
	std::cout << "Enter your guess: ";
	std::getline(std::cin, Guess);
	return Guess;
}

std::vector <char> TestGuess(const std::string &Guess, const std::string &HiddenWord, std::vector <char> &ReplaceUnderscore) {
	int Correct = 0;

	for (size_t i = 0; i < HiddenWord.length(); i++) {
		if (HiddenWord[i] == Guess[0]) {
			ReplaceUnderscore.push_back(HiddenWord[i]);
			Correct += 1;
		}
	}
	if (Correct == 0) {
		Errors += 1;
	}
	return ReplaceUnderscore;
}

void GameWon(const std::string &HiddenWord) {
	std::cout << "You won! Hidden word was " << HiddenWord;
	AskToPlayAgain();
}

void GameLost(const std::string &HiddenWord) {
	std::cout << "You lost! Hidden word was " << HiddenWord;
	AskToPlayAgain();
}

void AskToPlayAgain() {
	std::string Choice;
	std::cout << "\n\nDo you want to play again? [Y/N]: ";
	std::cin >> Choice;

	switch (Choice[0]) {
	case 'y':
	case 'Y':
		break;
	case 'n':
	case 'N':
		exit(0);
		break;
	default:
		std::cout << "\n\nIncorrect answer, try again.";
		AskToPlayAgain();
		break;
	}
	Reset();
	PlayGame();
}

void Reset() {
	// ???????????????????/////
	std::cout << std::flush;
	system("CLS");
}
Last edited on
Reset what?

You need to have a better structure, so sub-functions return a status back up the call chain.
Endless recursion won't work in the long run.

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
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <cstdlib>

void PlayGame();
void Rules();
std::string CreateHiddenWord(const std::string & SelectedTopic);
void PrintMan();
void PrintTopic(const std::string & SelectedTopic);
void PrintUnderscore(const std::string & HiddenWord, std::vector < char >&ReplaceUnderscore);
bool CheckGameStatus(const std::vector < char >&ReplaceUnderscore, const std::string & HiddenWord);
std::string InputGuess();
std::vector < char >TestGuess(const std::string & Guess, const std::string & HiddenWord,
                              std::vector < char >&ReplaceUnderscore);
void GameWon(const std::string & HiddenWord);
void GameLost(const std::string & HiddenWord);
bool AskToPlayAgain();
void Reset();

int Errors = 0;

int main()
{
  srand((unsigned int)time(NULL));  //!! This didn't even compile as you posted it.
  do {
    PlayGame();
  } while ( AskToPlayAgain() );
  return 0;
}

void PlayGame()
{
  std::vector < char >ReplaceUnderscore;

  const std::string Topic[] = { "Animals", "Football", "C++" };
  const std::string SelectedTopic = Topic[rand() % 3];

  std::string HiddenWord = CreateHiddenWord(SelectedTopic);

  Rules();

  bool gameOver = false;
  while ( !gameOver ) {
    PrintMan();
    PrintTopic(SelectedTopic);
    PrintUnderscore(HiddenWord, ReplaceUnderscore);
    std::string Guess = InputGuess();
    ReplaceUnderscore = TestGuess(Guess, HiddenWord, ReplaceUnderscore);
    gameOver = CheckGameStatus(ReplaceUnderscore, HiddenWord);
  }
}

void Rules()
{
  std::cout << "Basic Rules: 1. 7 Chances For Errors. 2. Only use lowercase. 3. Use only 1 letter.\n\n";
}

std::string CreateHiddenWord(const std::string & SelectedTopic)
{
  std::string HiddenWord;

  const std::string RandomAnimal[] = { "dog", "cat", "elephant", "monkey", "bird", "panda", "snake", "donkey" };
  const std::string RandomFootball[] = { "gators", "bulldogs", "patriots", "football", "kickoff", "quarter" };
  const std::string RandomCPP[] = { "switch", "for", "while", "vector", "class", "pointer", "array", "header" };

  switch (SelectedTopic[0]) {
  case 'A':
    HiddenWord = RandomAnimal[rand() % 8];
    break;
  case 'F':
    HiddenWord = RandomFootball[rand() % 6];
    break;
  case 'C':
    HiddenWord = RandomCPP[rand() % 8];
    break;
  }
  return HiddenWord;
}

void PrintMan()
{
  switch (Errors) {
  case 0:
    std::cout << "    #######\n";
    std::cout << "    ##\n";
    std::cout << "    ##\n";
    std::cout << "    ##\n";
    std::cout << "    ##\n";
    std::cout << "    ##\n";
    std::cout << "   #########\n";
    break;
  case 1:
    std::cout << "    #######\n";
    std::cout << "    ##   |\n";
    std::cout << "    ##\n";
    std::cout << "    ##\n";
    std::cout << "    ##\n";
    std::cout << "    ##\n";
    std::cout << "   #########\n";
    break;
  case 2:
    std::cout << "    #######\n";
    std::cout << "    ##   |\n";
    std::cout << "    ##   @\n";
    std::cout << "    ##\n";
    std::cout << "    ##\n";
    std::cout << "    ##\n";
    std::cout << "   #########\n";
    break;
  case 3:
    std::cout << "    #######\n";
    std::cout << "    ##   |\n";
    std::cout << "    ##   @\n";
    std::cout << "    ##   |\n";
    std::cout << "    ##\n";
    std::cout << "    ##\n";
    std::cout << "   #########\n";
    break;
  case 4:
    std::cout << "    #######\n";
    std::cout << "    ##   | \n";
    std::cout << "    ##   @ \n";
    std::cout << "    ##  -| \n";
    std::cout << "    ##\n";
    std::cout << "    ##\n";
    std::cout << "   #########\n";
    break;
  case 5:
    std::cout << "    #######\n";
    std::cout << "    ##   | \n";
    std::cout << "    ##   @ \n";
    std::cout << "    ##  -|- \n";
    std::cout << "    ##\n";
    std::cout << "    ##\n";
    std::cout << "   #########\n";
    break;
  case 6:
    std::cout << "    #######\n";
    std::cout << "    ##   | \n";
    std::cout << "    ##   @ \n";
    std::cout << "    ##  -|- \n";
    std::cout << "    ##  / \n";
    std::cout << "    ##\n";
    std::cout << "   #########\n";
    break;
  case 7:
    std::cout << "    #######\n";
    std::cout << "    ##   | \n";
    std::cout << "    ##   @ \n";
    std::cout << "    ##  -|-\n";
    std::cout << "    ##  / \\\n";
    std::cout << "    ##\n";
    std::cout << "   #########\n";
    break;
  }

  std::cout << "\n\n";
}

void PrintTopic(const std::string & SelectedTopic)
{
  std::cout << "Topic = " << SelectedTopic;
  std::cout << "\n\n";
}

void PrintUnderscore(const std::string & HiddenWord, std::vector < char >&ReplaceUnderscore)
{
  std::vector < char >Output;

  if (ReplaceUnderscore.size() > 0) {
    if (ReplaceUnderscore.size() == 1) {
      for (size_t i = 0; i < HiddenWord.length(); i++) {
        if (ReplaceUnderscore[0] == HiddenWord[i]) {
          std::cout << HiddenWord[i] << " ";
        } else {
          std::cout << "_ ";
        }
      }
    } else {
      for (size_t i = 0; i < HiddenWord.length(); i++) {
        Output.push_back('_');
      }
      for (size_t j = 0; j < ReplaceUnderscore.size(); j++) {
        for (size_t i = 0; i < Output.size(); i++) {
          if (HiddenWord[i] == ReplaceUnderscore[j]) {
            Output[i] = ReplaceUnderscore[j];
          }
        }
      }
      for (size_t i = 0; i < Output.size(); i++) {
        std::cout << Output[i] << " ";
      }
    }
  } else {
    for (size_t i = 0; i < HiddenWord.length(); i++) {
      std::cout << "_ ";
    }
  }
  std::cout << "\n\n";
}

bool CheckGameStatus(const std::vector < char >&ReplaceUnderscore, const std::string & HiddenWord)
{
  bool gameOver = false;
  std::string VectorString(ReplaceUnderscore.begin(), ReplaceUnderscore.end());
  int Repeat = 0;
  int Correct = 0;

  for (size_t j = 0; j < HiddenWord.length(); j++) {
    for (size_t i = 0; i < HiddenWord.length(); i++) {
      if (HiddenWord[j] == HiddenWord[i] && j != i) {
        Repeat += 1;
      }
    }
  }
  for (size_t j = 0; j < VectorString.length(); j++) {
    for (size_t i = 0; i < HiddenWord.length(); i++) {
      if (VectorString[j] == HiddenWord[i]) {
        Correct += 1;
      }
    }
  }
  Correct -= Repeat;

  if (Correct == VectorString.length() && Correct == HiddenWord.length()) {
    GameWon(HiddenWord);
    gameOver = true;
  } else if (Errors == 7) {
    gameOver = true;
    GameLost(HiddenWord);
  }
  return gameOver;
}

std::string InputGuess()
{
  std::string Guess;
  std::cout << "Enter your guess: ";
  std::getline(std::cin, Guess);
  return Guess;
}

std::vector < char >TestGuess(const std::string & Guess, const std::string & HiddenWord,
                              std::vector < char >&ReplaceUnderscore)
{
  int Correct = 0;

  for (size_t i = 0; i < HiddenWord.length(); i++) {
    if (HiddenWord[i] == Guess[0]) {
      ReplaceUnderscore.push_back(HiddenWord[i]);
      Correct += 1;
    }
  }
  if (Correct == 0) {
    Errors += 1;
  }
  return ReplaceUnderscore;
}

void GameWon(const std::string & HiddenWord)
{
  std::cout << "You won! Hidden word was " << HiddenWord;
}

void GameLost(const std::string & HiddenWord)
{
  std::cout << "You lost! Hidden word was " << HiddenWord;
}

bool AskToPlayAgain()
{
  bool result = false;
  bool again = true;
  do {
    std::string Choice;
    std::cout << "\n\nDo you want to play again? [Y/N]: ";
    std::cin >> Choice;

    switch (Choice[0]) {
    case 'y':
    case 'Y':
        result = true;
        again = false;
        break;
    case 'n':
    case 'N':
        result = false;
        again = false;
        break;
    default:
        std::cout << "\n\nIncorrect answer, try again.";
        break;
    }
  } while ( again );
  return result;
}

void Reset()
{
  // ???????????????????/////
  std::cout << std::flush;
  system("CLS");
}
Rather than passing parameters all over, create a Hangman class that contains the hidden word and replaceUnderscore. Then, if you make AskToPlayAgain a function outside the class, you can easily reset all the data by creating a new Hangman object each time you want to play the 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
class Hangman {
public:
    std::string HiddenWord;
    std::vector<char> ReplaceUnderscore;

    void PlayGame();
    void Rules();
    void CreateHiddenWord(const std::string & SelectedTopic);
    void PrintMan();
    void PrintTopic(const std::string & SelectedTopic);
    void PrintUnderscore();
    bool CheckGameStatus();
    std::string InputGuess();
    void TestGuess(const std::string & Guess);
    void GameWon();
    void GameLost();
    void Reset();
    int Errors = 0;
};

do {
        Hangman hangman;
        hangman.PlayGame();
    } while (AskToPlayAgain());


I've somewhat arbitrarily left SelectedTopic and Guess as local variables that are passed as parameters when needed. Others might prefer to make those class members too.

In general, data is much smaller than code. In printMap, just create an array of cstrings holding the characters to print for each man:
1
2
3
4
5
6
7
8
9
10
11
    static const char *men[] = {
        "    #######\n"         // 0
        "    ##\n"
        "    ##\n"
        "    ##\n"
        "    ##\n"
        "    ##\n"
        "   #########\n",
        ...
};
std::cout << men[Errors] << "\n\n";


I've used a lesser-known feature of C++ here: you can continue a string literal on the next line by just restarting it:
1
2
"Hello "
"World"

is the same as
"Hello World"

Building on salem c's code. I've left the Reset() method, although I don't think you need 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
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
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <cstdlib>

class Hangman {
public:
    std::string HiddenWord;
    std::vector<char> ReplaceUnderscore;

    void PlayGame();
    void Rules();
    void CreateHiddenWord(const std::string & SelectedTopic);
    void PrintMan();
    void PrintTopic(const std::string & SelectedTopic);
    void PrintUnderscore();
    bool CheckGameStatus();
    std::string InputGuess();
    void TestGuess(const std::string & Guess);
    void GameWon();
    void GameLost();
    void Reset();
    int Errors = 0;
};

// AskToPlayAgain() isn't part of the game itself.  This way You can
// construct a new game object each time they want to play.  See main()
bool AskToPlayAgain();

int
main()
{
    srand((unsigned int) time(NULL));		 //!! This didn't even compile as you posted it.
    do {
	Hangman hangman;
	hangman.PlayGame();
    } while (AskToPlayAgain());
    return 0;
}

void
Hangman::PlayGame()
{
    const std::string Topic[] = { "Animals", "Football", "C++" };
    const std::string SelectedTopic = Topic[rand() % 3];

    CreateHiddenWord(SelectedTopic);
    Rules();

    bool gameOver = false;
    while (!gameOver) {
	PrintMan();
	PrintTopic(SelectedTopic);
	PrintUnderscore();
	std::string Guess = InputGuess();
	TestGuess(Guess);
	gameOver = CheckGameStatus();
    }
}

void
Hangman::Rules()
{
    std::
	cout <<
	"Basic Rules: 1. 7 Chances For Errors. 2. Only use lowercase. 3. Use only 1 letter.\n\n";
}

void
Hangman::CreateHiddenWord(const std::string & SelectedTopic)
{
    const std::string RandomAnimal[] =
	{ "dog", "cat", "elephant", "monkey", "bird", "panda", "snake", "donkey" };
    const std::string RandomFootball[] =
	{ "gators", "bulldogs", "patriots", "football", "kickoff", "quarter" };
    const std::string RandomCPP[] =
	{ "switch", "for", "while", "vector", "class", "pointer", "array", "header" };

    switch (SelectedTopic[0]) {
    case 'A':
	HiddenWord = RandomAnimal[rand() % 8];
	break;
    case 'F':
	HiddenWord = RandomFootball[rand() % 6];
	break;
    case 'C':
	HiddenWord = RandomCPP[rand() % 8];
	break;
    }
}

void
Hangman::PrintMan()
{
    static const char *men[] = {
	"    #######\n"		// 0
	"    ##\n"
	"    ##\n"
	"    ##\n"
	"    ##\n"
	"    ##\n"
	"   #########\n",

	"    #######\n"		// 1
	"    ##   |\n"
	"    ##\n"
	"    ##\n"
	"    ##\n"
	"    ##\n"
	"   #########\n",

	"    #######\n"		// 2
	"    ##   |\n"
	"    ##   @\n"
	"    ##\n"
	"    ##\n"
	"    ##\n"
	"   #########\n",

	"    #######\n"		// 3
	"    ##   |\n"
	"    ##   @\n"
	"    ##   |\n"
	"    ##\n"
	"    ##\n"
	"   #########\n",

	"    #######\n"		// 4
	"    ##   | \n"
	"    ##   @ \n"
	"    ##  -| \n"
	"    ##\n"
	"    ##\n"
	"   #########\n",

	"    #######\n"		// 5
	"    ##   | \n"
	"    ##   @ \n"
	"    ##  -|- \n"
	"    ##\n"
	"    ##\n"
	"   #########\n",

	"    #######\n"		// 6
	"    ##   | \n"
	"    ##   @ \n"
	"    ##  -|- \n"
	"    ##  / \n"
	"    ##\n"
	"   #########\n",

	"    #######\n"		// 7
	"    ##   | \n"
	"    ##   @ \n"
	"    ##  -|-\n"
	"    ##  / \\\n"
	"    ##\n"
	"   #########\n"
    };
    std::cout << men[Errors] << "\n\n";
}

void
Hangman::PrintTopic(const std::string & SelectedTopic)
{
    std::cout << "Topic = " << SelectedTopic;
    std::cout << "\n\n";
}

void
Hangman::PrintUnderscore()
{
    std::vector < char >Output;

    if (ReplaceUnderscore.size() > 0) {
	if (ReplaceUnderscore.size() == 1) {
	    for (size_t i = 0; i < HiddenWord.length(); i++) {
		if (ReplaceUnderscore[0] == HiddenWord[i]) {
		    std::cout << HiddenWord[i] << " ";
		} else {
		    std::cout << "_ ";
		}
	    }
	} else {
	    for (size_t i = 0; i < HiddenWord.length(); i++) {
		Output.push_back('_');
	    }
	    for (size_t j = 0; j < ReplaceUnderscore.size(); j++) {
		for (size_t i = 0; i < Output.size(); i++) {
		    if (HiddenWord[i] == ReplaceUnderscore[j]) {
			Output[i] = ReplaceUnderscore[j];
		    }
		}
	    }
	    for (size_t i = 0; i < Output.size(); i++) {
		std::cout << Output[i] << " ";
	    }
	}
    } else {
	for (size_t i = 0; i < HiddenWord.length(); i++) {
	    std::cout << "_ ";
	}
    }
    std::cout << "\n\n";
}

bool
Hangman::CheckGameStatus()
{
    bool gameOver = false;
    std::string VectorString(ReplaceUnderscore.begin(), ReplaceUnderscore.end());
    int Repeat = 0;
    unsigned Correct = 0;

    for (size_t j = 0; j < HiddenWord.length(); j++) {
	for (size_t i = 0; i < HiddenWord.length(); i++) {
	    if (HiddenWord[j] == HiddenWord[i] && j != i) {
		Repeat += 1;
	    }
	}
    }
    for (size_t j = 0; j < VectorString.length(); j++) {
	for (size_t i = 0; i < HiddenWord.length(); i++) {
	    if (VectorString[j] == HiddenWord[i]) {
		Correct += 1;
	    }
	}
    }
    Correct -= Repeat;

    if (Correct == VectorString.length() && Correct == HiddenWord.length()) {
	GameWon();
	gameOver = true;
    } else if (Errors == 7) {
	gameOver = true;
	GameLost();
    }
    return gameOver;
}

std::string Hangman::InputGuess()
{
    std::string Guess;
    std::cout << "Enter your guess: ";
    std::getline(std::cin, Guess);
    return Guess;
}

void
Hangman::TestGuess(const std::string & Guess)
{
    int Correct = 0;
    
    for (size_t i = 0; i < HiddenWord.length(); i++) {
	if (HiddenWord[i] == Guess[0]) {
	    ReplaceUnderscore.push_back(HiddenWord[i]);
	    Correct += 1;
	}
    }
    if (Correct == 0) {
	Errors += 1;
    }
}

void
Hangman::GameWon()
{
    std::cout << "You won! Hidden word was " << HiddenWord;
}

void
Hangman::GameLost()
{
    std::cout << "You lost! Hidden word was " << HiddenWord;
}

bool
AskToPlayAgain()
{
    bool result = false;
    bool again = true;
    do {
	std::string Choice;
	std::cout << "\n\nDo you want to play again? [Y/N]: ";
	std::cin >> Choice;

	switch (Choice[0]) {
	case 'y':
	case 'Y':
	    result = true;
	    again = false;
	    break;
	case 'n':
	case 'N':
	    result = false;
	    again = false;
	    break;
	default:
	    std::cout << "\n\nIncorrect answer, try again.";
	    break;
	}
    } while (again);
    return result;
}

void
Hangman::Reset()
{
    // ???????????????????/////
    std::cout << std::flush;
    system("CLS");
}


Hello ChimpCoder,

Generally with a "reset" function one would think that there would be several variables that need reset.

Based on the way the program flows most variables loose scope when the function ends or functions are being called, so its like starting new taking care of most of the variables.

The variable "Errors" is defined as a global variable. This works, but you should try to avoid global variables like this. Something that starts as "constexpr" or "const" are OK because as a constant they can not be changed by the program.

In this program it looks like you define "Errors" and then forgot about it. So when the programs goes to play another game "Errors" already has a value, so your second game starts with errors even before you make a guess.

Because of the program flow I had to reset "Errors" to "-1" because it looks like function "TestGuess" is being called before it should be starting game two with one incorrect answer when there should be none.

The function "AskToPlayAgain" calls "PlayGame" before you even return from when PlayGame" was first called.

Thinking about the program flow "main" should call "PlayGame" and when that function returns back to main the function "AskToPlayAgain" should be called and not after you printed a win or loss. This way you will not have to use the "exit()" as you did and when functions end properly the variables defined there also end meaning that they do not have to be reset.

I still want to do some testing, but for now I am thinking:
1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
	srand((unsigned int(time(NULL))));
	bool contGame{ true };

	while (contGame)
	{
		PlayGame();
		AskToPlayAgain(contGame);
	}

	return 0;
}

And the "AskToPlayAgain" functiom could be something like:
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
void AskToPlayAgain(bool& contGame)
{
	std::string Choice;

	do
	{
		std::cout << "\n\nDo you want to play again? [Y/N]: ";
		std::cin >> Choice;

		switch (Choice[0])
		{
		case 'y':
		case 'Y':
			Reset();  // <--- Moved to here.
			break;
		case 'n':
		case 'N':
			contGame = false;
			break;
		default:
			std::cout << "\n\nIncorrect answer, try again.";
			//AskToPlayAgain(contGame);// <--- Do not call the function. use a do/while loop around the switch.
			break;
		}

	} while (std::tolower(Choice[0]) != 'y' || std::tolower(Choice[0]) != 'n');


	//PlayGame();  // <--- Do not call from here.
}

All you need for "Choice" is a "char" not a "string". Note: "contGame" is is being passed by reference. Or you could have the function return a bool. Eithe way works.

In "PlayGame' I would set up the while in much the same way as I showed you in "main" although I would most likely call the variable "cont" and then pass it be reference to the function(s) that eventually get to the functiions "GameWon" and "GameLost" where you would set "cont" to false.

The point is that you need to end functions before you call them for a second time.

Hope that helps,

Andy
Hello ChimpCoder,

I am not sure what I was thinking at the time, but I found that I had to change the while condition of the "AskToPlayAgain" function from "||" to "&&". It should look like this:
while (std::tolower(choice) !='y' && std::tolower(choice) != 'n'); I also changed "Choice" to "char choice".

Sorry about that.

Hope that helps,

Andy

Edit:
Last edited on
Registered users can post here. Sign in or register to post.