Need slight help with adding two more code words for user to guess

Hey y'all, the basis of my program is similar to hangman. I want to display 3 code words out of the 10 that I have for the user to guess. As you can probably see, the user has to guess a word each time until they guess the code word right.

The only issue I'm having is displaying 3 code words for the user to guess as I only have one for them to guess. Can someone help me with that?

#include <iostream>
#include <string>
#include <algorithm>
#include <ctime>
#include <cctype>
#include <cstdlib>
#include <array>
#include <random>
#include <chrono>

using namespace std;

int main()
{
string name;
// Display Title of the program to the user
cout << "This is the Keywords II Code Breaker Training Simulation Program.";
// Ask the recruit to log in using their name
cout << " Can you please log in with your first name?\n";
cin >> name;

// Hold the recruit's name in a var, and address them by it throughout the simulation

// Display an overview of what Keywords II is to the recruit
cout << "\nWe love the work you have been showing us recruit " << name << ". Recently the enemy is using single scrambled low-tech keywords to signal other enemies to start attacks which our current code decryption programs have not been successful against. Here at the CIA we are developing a new codebreaking team that relies on human expertise to detect these low tech scrambled keywords.\n";
// Display directions to the recruit on how to use Keywords
cout << "\nTo start, I have a list of 10 words of which I will pick 3 random words out of. And you will have to guess the letters for the secret words that I pick out.\n";

// Create a collection of 10 words you had written down manually

unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
vector<string> WORDS;
WORDS.push_back("QUESTION");
WORDS.push_back("FORCES");
WORDS.push_back("ANSWER");
WORDS.push_back("OCEAN");
WORDS.push_back("FRAGILE");
WORDS.push_back("CRACKED");
WORDS.push_back("BOTTLE");
WORDS.push_back("CHIEFS");
WORDS.push_back("KANSAS");
WORDS.push_back("CITY");
// Shuffles the words and picks a random one.
shuffle(WORDS.begin(), WORDS.end(), std::default_random_engine(seed));
const string THE_WORD1 = WORDS[0]; // The word to guess

// Create an int var to count the number of simulations being run starting at 1
int counter = 1;
// Display the simulation # is starting to the recruit
cout << "You are starting at simulation " << counter << "\n";
//The number of incorrect guesses
int wrong = 0;
//That it maximum number of incorrect guesses allowed
int nomore = 8;
// Pick new 3 random words from your collection as the secret code word the recruit has to guess

string soFar(THE_WORD1.size(), '-'); //The word guessed so far
string already = ""; // The letters that already guessed
// While recruit hasn’t made too many incorrect guesses and hasn’t guessed the secret word
while ((wrong < nomore) && (soFar != THE_WORD1))
{
// Increment the number of incorrect guesses the recruit has made
nomore - wrong++;
// Tell recruit how many incorrect guesses he or she has left
cout << "\n\nYou have " << (nomore - wrong) << " guesses left\n";
// Show recruit the letters he or she has guessed
cout << "\nYou've used the following letters:\n"
<< already << "\n\n";
char guess;
cout << "Go ahead and enter your guess.\n";

// Get recruit ’s guess
cin >> guess;
guess = toupper(guess);
// While recruit has entered a letter that he or she has already guessed
while (already.find(guess) != string::npos)
{
// Show player how much of the secret word he or she has guessed
cout << "\nYou've already guessed " << guess << endl;
// Get recruit's next guess
cin >> guess;
guess = toupper(guess);
}
// Add the new guess to the group of used letters
already += guess;

// If the guess is in the secret word
if (THE_WORD1.find(guess) != string::npos)
{
// Tell the recruit the guess is correct
cout << "It's right!! " << guess << " is in the word.\n";
// Update the word guessed so far with the new letter
for (int i = 0; i < THE_WORD1.length(); ++i)
{
if (THE_WORD1[i] == guess)
{
soFar[i] = guess;
}
}
}
// Otherwise
else
{
// Tell the recruit the guess is incorrect
cout << "Sorry," << guess << " isn't in the word.\n";
// Putting the incrementer here does not work with my program
}
}
// If the recruit has made too many incorrect guesses
if (wrong == nomore)
{
// Tell the recruit that he or she has failed the Keywords II course
// Ask the recruit if they would like to run the simulation again
cout << "\nYou have failed recruit, if you would like to play again, enter Y and if not enter N.";
char playagain;
cin >> playagain;
// If the recruit wants to run the simulation again
if (playagain == 'Y' || playagain == 'y')
{
counter++;
// Increment the number of simulations ran counter
cout << "You are now on simulation " << counter++ << "\n";
// Move program execution back up to // Display the simulation # is starting to the recruit
return main();
}
// Otherwise
else if (playagain == 'N' || playagain == 'n')
{
// Display End of Simulations to the recruit
cout << "Simulation " << counter << " is now over.\n";
// Pause the Simulation with press any key to continue
cout << system("pause");
}
}
// Otherwise
else
{
// Congratulate the recruit on guessing the secret words
cout << "\nYou guessed the right letter recruit!";
}
cout << "\nThe word was " << THE_WORD1 << endl;

return 0;
}
jrfootball13,
Please use code tags (the <>button when creating a post) to put your code in. It helps us tell which stuff is code and which is not. A couple of links on how to use code tags:
http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/


First of all, your program isn't very readable, although it's better than a lot I've seen. It's always a good idea to use plenty of whitespace– empty lines separating chunks of code, and indenting code within braces.

e.g.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

int main ()
{
     // thing
     while (/*condition*/)
     {
          // stuff happens
     }

     std::cout << "Hello world" << std::endl;
     
     return 0;
}

See? Lots of whitespace and indenting makes it easier to read code in chunks that can be visually broken down and processed.

Using plenty of comments like you did is good though, so brownie points for that ;)

Onto more relevant stuff, when I compiled your code in Clang, I got this:
$ c++ -g -Wall -Wextra -pedantic -o code_words code_words.cc
code_words.cc:44:1: error: no matching function for call to 'shuffle'
shuffle(WORDS.begin(), WORDS.end(), std::default_random_engine(seed));
^~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/algorithm:3282:10: note: candidate function
      [with _RandomAccessIterator = std::__1::__wrap_iter<std::__1::basic_string<char> *>,
      _UniformRandomNumberGenerator = std::__1::linear_congruential_engine<unsigned int, 48271, 0,
      2147483647>] not viable: expects an l-value for 3rd argument
    void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
         ^
code_words.cc:63:8: warning: expression result unused [-Wunused-value]
nomore - wrong++;
~~~~~~ ^ ~~~~~~~
code_words.cc:124:8: warning: ISO C++ does not allow 'main' to be used by a program [-Wmain]
return main();
       ^
code_words.cc:144:2: warning: no newline at end of file [-Wnewline-eof]
}
 ^
code_words.cc:93:19: warning: comparison of integers of different signs: 'int' and
      'std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>
      >::size_type' (aka 'unsigned long') [-Wsign-compare]
for (int i = 0; i < THE_WORD1.length(); ++i)
                ~ ^ ~~~~~~~~~~~~~~~~~~
4 warnings and 1 error generated.

Ok, that's not good.
Note: I copied and pasted your code into my code editor, so the line numbers should be correct.

The error– no matching function for call to "shuffle." Well, you included <algorithm>, and it looks like you did all the parameters right. I don't know, maybe my algorithm file is screwed up. Does it compile OK for you?

First warning. Uh, what...
1
2
// Increment the number of incorrect guesses the recruit has made
nomore - wrong++;

I've never seen anyone do this before. That just will not work. Did you mean nomore = wrong++;?

Second warning. What is this?
118
119
120
121
122
123
124
125
if (playagain == 'Y' || playagain == 'y')
{
counter++;
// Increment the number of simulations ran counter
cout << "You are now on simulation " << counter++ << "\n";
// Move program execution back up to // Display the simulation # is starting to the recruit
return main();
}

You're...returning main()? Why? That doesn't work. And you don't need it. The program will automatically go on to whatever is after the else statements after it.

Third warning. Uh, ok, that's stupid, seriously. I don't even know why that is a warning...?

Fourth warning. Ok, you're comparing an int and an unsigned long...with different signs? That doesn't sound like a big deal. Try making the "int i" into an "unsigned i" and see if that gets rid of it.

Well, I hope this gives you something to start with!
max
Last edited on
Thank you so much for helping me Max. Yes, my program compiles perfectly with MinGW.

And for for the nomore - wrong++ , what I was trying to do was subract the number of incorrect guesses from the max allowed number of incorrect guesses and then increment that. But I think I could just do wrong++ if I'm not mistaking.

And I did the return main() to give the user the option to restart the program because the words are being shuffled so they wouldn't be doing the same code word again. The only issue with that is I don't want the intro with directions to be displayed again, I just want it to go straight into the next code word for the user to guess. So, I guess in order to do that, I would have to create another function that stores another code word into and return that instead of return main(), right?
Per the standard, you should not recursively call main(). Use a loop instead. And yes, splitting some of your functionality out of main would make your code more readable, in my opinion.
Last edited on
You need another outer loop to deal with simulations. If you're covered functions, then these could usefully be used to simplify the main code. You can index WORDS with the simulation number (if less than the number of words) so shuffle only once and you know you're getting 3 unique words.

Also, you might want to consider allowing the user to have a guess at entering the whole word if they think they know it.

With an outer simulation loop, perhaps something like this:

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
#include <iostream>
#include <string>
#include <algorithm>
#include <ctime>
#include <cctype>
#include <random>
#include <chrono>

using namespace std;

int main()
{
	string name;

	// Display Title of the program to the user
	cout << "This is the Keywords II Code Breaker Training Simulation Program.";

	// Ask the recruit to log in using their name
	cout << " Can you please log in with your first name?\n";
	cin >> name;

	// Hold the recruit's name in a var, and address them by it throughout the simulation

	// Display an overview of what Keywords II is to the recruit
	cout << "\nWe love the work you have been showing us recruit " << name << ". Recently the enemy is using single scrambled low-tech keywords to signal other enemies to start attacks which our current code decryption programs have not been successful against. Here at the CIA we are developing a new codebreaking team that relies on human expertise to detect these low tech scrambled keywords.\n";

	// Display directions to the recruit on how to use Keywords
	cout << "\nTo start, I have a list of 10 words of which I will pick 3 random words out of. And you will have to guess the letters for the secret words that I pick out.\n";

	// Create a collection of 10 words you had written down manually

	const unsigned seed {static_cast<unsigned>(std::chrono::system_clock::now().time_since_epoch().count())};

	vector<string> WORDS {"QUESTION", "FORCES", "ANSWER", "OCEAN", "FRAGILE", "CRACKED", "BOTTLE", "CHIEFS", "KANSAS", "CITY"};

	// Shuffles the words and picks a random one.
	shuffle(WORDS.begin(), WORDS.end(), std::default_random_engine(seed));

	//That it maximum number of incorrect guesses allowed
	const unsigned nomore {8};

	// Create an int var to count the number of simulations being run starting at 1
	unsigned counter {1};

	// Display the simulation # is starting to the recruit
	cout << "You are starting at simulation " << counter << "\n";

	while (counter <= 3) {
		const string THE_WORD1 {WORDS[counter - 1]}; // The word to guess

		//The number of incorrect guesses
		unsigned wrong {};

		// Pick new 3 random words from your collection as the secret code word the recruit has to guess

		string soFar(THE_WORD1.size(), '-'); //The word guessed so far
		string already; // The letters that already guessed

		// While recruit hasn’t made too many incorrect guesses and hasn’t guessed the secret word
		while ((wrong < nomore) && (soFar != THE_WORD1))
		{
			// Increment the number of incorrect guesses the recruit has made
			//nomore - wrong++;
			wrong++;

			// Tell recruit how many incorrect guesses he or she has left
			cout << "\n\nYou have " << (nomore - wrong + 1) << " guesses left\n";

			// Show recruit the letters he or she has guessed
			cout << "\nYou've used the following letters:\n" << already << "\n\n";
			cout << "Go ahead and enter your guess.\n";

			// Get recruit ’s guess
			char guess;
			cin >> guess;

			// While recruit has entered a letter that he or she has already guessed
			while (already.find(guess) != string::npos)
			{
				// Show player how much of the secret word he or she has guessed
				cout << "\nYou've already guessed " << guess << '\n';

				// Get recruit's next guess
				cin >> guess;
				guess = static_cast<char>(toupper(static_cast<unsigned char>(guess)));
			}

			// Add the new guess to the group of used letters
			already += guess;

			// If the guess is in the secret word
			if (THE_WORD1.find(guess) != string::npos)
			{
				// Tell the recruit the guess is correct
				cout << "It's right!! " << guess << " is in the word.\n";

				// Update the word guessed so far with the new letter
				for (size_t i = 0; i < THE_WORD1.length(); ++i)
					if (THE_WORD1[i] == guess)
						soFar[i] = guess;
			} else
			{
				// Otherwise
				// Tell the recruit the guess is incorrect
				cout << "Sorry," << guess << " isn't in the word.\n";
				// Putting the incrementer here does not work with my program
			}
		}

		// If the recruit has made too many incorrect guesses
		if (wrong == nomore)
		{
			// Tell the recruit that he or she has failed the Keywords II course
			// Ask the recruit if they would like to run the simulation again
			cout << "\nThe word was " << THE_WORD1 << '\n';
			cout << "\nYou have failed recruit, if you would like to play again, enter Y and if not enter N.";

			char playagain;
			cin >> playagain;
			playagain = static_cast<char>(toupper(static_cast<unsigned char>(playagain)));

			// If the recruit wants to run the simulation again
			if (playagain == 'Y')
			{
				//counter++;
				// Increment the number of simulations ran counter
				cout << "You are now on simulation " << ++counter << "\n";
				// Move program execution back up to // Display the simulation # is starting to the recruit
				//return main();
			} else if (playagain == 'N')
			{
				// Otherwise
				// Display End of Simulations to the recruit
				cout << "Simulation " << counter << " is now over.\n";
				// Pause the Simulation with press any key to continue
				//cout << system("pause");
				break;
			}
		} else
		{
			// Otherwise
			// Congratulate the recruit on guessing the secret words
			cout << "\nYou guessed the right letter recruit!";
		}
	}
}

As a simplified and updated version, perhaps consider:

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
#include <iostream>
#include <string>
#include <algorithm>
#include <ctime>
#include <cctype>
#include <random>
#include <chrono>

using namespace std;

std::string intro()
{
	string name;

	// Display Title of the program to the user
	cout << "This is the Keywords II Code Breaker Training Simulation Program.\n";

	// Ask the recruit to log in using their name
	cout << "Can you please log in with your first name: ";
	cin >> name;

	// Hold the recruit's name in a var, and address them by it throughout the simulation

	// Display an overview of what Keywords II is to the recruit
	cout << "\nWe love the work you have been showing us recruit " << name << ". Recently the enemy is using single scrambled low-tech keywords to signal other enemies to start attacks which our current code decryption programs have not been successful against. Here at the CIA we are developing a new codebreaking team that relies on human expertise to detect these low tech scrambled keywords.\n";

	// Display directions to the recruit on how to use Keywords
	cout << "\nTo start, I have a list of 10 words of which I will pick 3 random words out of. And you will have to guess the letters for the secret words that I pick out.\n";

	return name;
}

char getChar(const string& prm)
{
	char playagain;

	do {
		cout << prm;
		cin >> playagain;
		playagain = static_cast<char>(toupper(static_cast<unsigned char>(playagain)));
	} while ((playagain != 'Y' && playagain != 'N') && cout << "Invalid input\n");

	return playagain;
}

char getGuess(const std::string& already)
{
	char guess {};

	do {
		cout << "Go ahead and enter your letter guess: ";
		cin >> guess;
		guess = static_cast<char>(toupper(static_cast<unsigned char>(guess)));
	} while (already.find(guess) != string::npos && (cout << "\nYou've already guessed " << guess << '\n'));

	return guess;
}

void update(string& soFar, const string& THE_WORD, char guess)
{
	for (size_t i = 0; i < THE_WORD.length(); ++i)
		if (THE_WORD[i] == guess)
			soFar[i] = guess;
}

int main()
{
	const unsigned seed {static_cast<unsigned>(chrono::system_clock::now().time_since_epoch().count())};	// Seed for random
	const size_t nomore {8};	// Maxmimum number incorrect guesses
	const size_t require {3};	// Number of words to guess to qualify
	size_t succeed {};	// Number of words guessed
	vector<string> WORDS {"QUESTION", "FORCES", "ANSWER", "OCEAN", "FRAGILE", "CRACKED", "BOTTLE", "CHIEFS", "KANSAS", "CITY"};
	shuffle(WORDS.begin(), WORDS.end(), default_random_engine(seed));

	const auto name {intro()};

	for (size_t counter {}; counter < WORDS.size() && succeed < require; ++counter) {
		cout << "You are now on simulation " << succeed + 1 << '\n';

		const string& THE_WORD {WORDS[counter]}; // The word to guess
		size_t incorrect {};	// Number of incorrect guesses
		string soFar(THE_WORD.size(), '-'); // The word guessed so far
		string already;	// The letters already guessed

		// While recruit hasn’t made too many incorrect guesses and hasn’t guessed the secret word
		while ((incorrect < nomore) && (soFar != THE_WORD)) {
			cout << "\n\nYou have " << (nomore - incorrect) << " guesses left\n";
			cout << "\nYou've used the following letters:\n" << already << "\n\n";

			const char guess {getGuess(already)};

			already += guess; // Add the new guess to the group of used letters
			sort(already.begin(), already.end());

			// If the guess is in the secret word
			if (THE_WORD.find(guess) != string::npos) {
				update(soFar, THE_WORD, guess);
				cout << "It's right!! " << guess << " is in the word.\n";
			} else {
				cout << "Sorry, " << guess << " isn't in the word.\n";
				++incorrect;
			}
			cout << '\n' << soFar << '\n';
		}

		// If the recruit has not guessed
		if (soFar != THE_WORD) {
			cout << "\nThe word was " << THE_WORD << '\n';
			cout << "\nYou have failed recruit "  << name << ". If you would like to try another word , ";

			const char playagain {getChar("Enter Y and if not enter N: ")};

			// If the recruit does not want to run the simulation again
			if (playagain == 'N') {
				cout << "Simulation " << succeed + 1 << " is now over.\n";
				break;	// Break simulation loop
			}
		} else {
			cout << "\nYou guessed the right word recruit " << name << "!\n";
			++succeed;
		}
	}

	if (succeed == require)
		cout << "\nCongratulations. You have passed\n";
	else
		cout << "\nSorry, You have failed\n";
}

Last edited on
Topic archived. No new replies allowed.