If I understand what you are doing, you are making things quite a bit harder of yourself than they need to be. You are already using std::string
. To find if the current character in user_guess
appears elsewhere in word
, you can simply use the std::basic_string::find_first_of member function by searching word
from the current index for a character that matches the current character in user_guess
.
For example, you can simply do:
std::string fun2 (std::string user_guess, std::string word)
{
if (user_guess == word) { /* words are equal, all green */
std::cout << "\033[30;42m" << user_guess << "\033[0m\n";
return "Success";
}
/* loop over each char (up to shorter of either string) */
for (int i = 0; user_guess[i] && word[i]; i++) {
if (user_guess[i] == word[i]) { /* chars match, green */
std::cout << "\033[30;42m" << user_guess[i] << "\033[0m";
}
/* current char found elsewhere in word - yellow */
else if (word.find_first_of (user_guess[i], i) != std::string::npos) {
std::cout << "\033[30;103m" << user_guess[i] << "\033[0m";
}
else { /* current char does not exist in word - red */
std::cout << "\033[30;41m" << user_guess[i] << "\033[0m";
}
}
return "\nThanks";
}
(note: there is no need for an else
after user_guess
and word
match, you are simply done at that point. Simply return from inside that block rather than using an else
and forcing an additional level of indentation for the remainder of the code in the else
block)
To match the current character in user_guess
to any character in word
starting from the beginning of word
instead of the current index, you can use word.find_first_of (user_guess[i], 0)
.
The line using namespace std;
was removed. See Why is “using namespace std;” considered bad practice?
Hardcoding strings makes it impossible to change word
or user_guess
without recompiling your code. You shouldn't have to recompile your code to simply provide a different word
or user_guess
, that's what the parameters to main()
, e.g. int argc, char **argv
, are for.
Simply pass word
and user_guess
as the first two arguments on the command line (or prompt the user for input and read from stdin
). Taking the arguments as the first two command line parameters, you could do:
#include <iostream>
#include <string>
...
int main (int argc, char **argv)
{
if (argc < 3) {
std::cerr << "usage: ./prog word user_guess.\n";
return 1;
}
std::string word { argv[1] };
std::string user_guess { argv[2] };
std::cout << fun2(user_guess, word) << '\n';
}
(note: those are the only two headers required by your code. Avoid including superfluous header files)
Example Use/Output
If I understood your goal, using:
$ ./bin/word_game_color cake fake
fake
Thanks
Where fake
is red,green,green,green
.
If we change it to: ./bin/word_game_color cake feke
then the output of feke
is red,yellow,green,green
.
In case of a match, you have, e.g.
$ ./bin/word_game_color cake cake
cake
Success
Where cake
is output all green.
Handling user_guess
Longer Than word
You likely want to handle cases where user_guess
and word
are of differing length. In that case simply add an additional loop to loop over any remaining characters in user_guess
while searching for the matching character anywhere in word
from the beginning.
You can do that with:
std::string fun2 (std::string user_guess, std::string word)
{
int i = 0;
if (user_guess == word) { /* words are equal, all green */
std::cout << "\033[30;42m" << user_guess << "\033[0m\n";
return "Success";
}
/* loop over each char (up to shorted of either string) */
for (; user_guess[i] && word[i]; i++) {
if (user_guess[i] == word[i]) { /* chars match, green */
std::cout << "\033[30;42m" << user_guess[i] << "\033[0m";
}
/* current char found elsewhere in word - yellow */
else if (word.find_first_of (user_guess[i], 0) != std::string::npos) {
std::cout << "\033[30;103m" << user_guess[i] << "\033[0m";
}
else { /* current char does not exist in word - red */
std::cout << "\033[30;41m" << user_guess[i] << "\033[0m";
}
}
/* user_guess longer than word -- loop remaining chars */
for (; user_guess[i]; i++) {
/* current char found elsewhere in word - yellow */
if (word.find_first_of (user_guess[i], 0) != std::string::npos) {
std::cout << "\033[30;103m" << user_guess[i] << "\033[0m";
}
else { /* current char does not exist in word - red */
std::cout << "\033[30;41m" << user_guess[i] << "\033[0m";
}
}
return "\nThanks";
}
In that case if you used "cake"
for word
and "cakebake"
for user_guess
you would have:
$ ./bin/word_game_color cake cakebake
cakebake
Thanks
Where cakebake
is green,green,green,green,red,yellow,yellow,yellow
.
Let me know if I misunderstood what your goal was. This made sense given what you had so far -- but greatly simplified things.