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
|
#include <iostream>
#include <fstream>
#include <vector>
#include <random>
class guessMyWord {
public:
guessMyWord(std::string& myBook, int length);
bool bAnagram(std::string lhs, std::string rhs);
void showSecretWords(std::string& guess, bool hiddenWord);
// all words from the dictionary
std::vector<std::string> words;
std::pair<std::string, std::string> secretWord; // !!!
private:
int randomNumber(const int min_, const int max_);
void selectWord();
std::string shuffleWord(std::string& word);
};
// constructor
guessMyWord::guessMyWord(std::string& myBook, int length)
{
std::string word;
std::ifstream input_file(myBook);
if (!input_file.is_open())
{
std::cout << "Could not open the file " << myBook << std::endl;
exit(EXIT_FAILURE);
}
while (input_file >> word)
if (word.size() == length)
words.push_back(word);
input_file.close();
// selects one word in the main vector
selectWord();
}
int guessMyWord::randomNumber(const int min_, const int max_)
{
static std::random_device rd;
static std::mt19937 rng{ rd() };
static std::uniform_int_distribution<int> uid(min_, max_);
return uid(rng);
}
void guessMyWord::selectWord()
{
size_t rn = randomNumber(1, words.size() - 1);
secretWord.first = words[rn];
secretWord.second = shuffleWord(words[rn]); // debug mode
// std::cout << "Hidden word : " << secretWord.first << " " << secretWord.second << std::endl;
}
std::string guessMyWord::shuffleWord(std::string& word)
{
again:
std::string tmp = word;
std::random_shuffle(tmp.begin(), tmp.end());
// check if the shuffled word is not a valid answer
if (std::find(words.begin(), words.end(), tmp) != words.end())
goto again; // I know I know...
return tmp;
}
bool guessMyWord::bAnagram(std::string lhs, std::string rhs)
{
std::sort(lhs.begin(), lhs.end());
std::sort(rhs.begin(), rhs.end());
return lhs == rhs;
}
void guessMyWord::showSecretWords(std::string& guess, bool showHiddenWord)
{
std::cout << std::endl;
std::cout << "Anagrams available for this word (alternative good answers) :" << std::endl;
int occ = 0;
if (showHiddenWord)
{
std::cout << secretWord.first << std::endl;
occ++;
}
for (int i = 0; i < words.size(); i++)
{
if (bAnagram(secretWord.first, words[i]) && guess != words[i])
{
std::cout << words[i] << std::endl;
occ++;
}
}
// no occurrence for anagrams
if ((occ == 0) ? std::cout << "[nothing]" << std::endl << std::endl
: std::cout << std::endl);
}
int main()
{
std::string dico = "dictionary.txt";
int letters = 4;
while (true)
{
int tries = NULL;
std::string myGuess;
// select a word
guessMyWord gmw(dico, letters);
std::cout << "~~ Guess My Word ~~" << std::endl;
std::cout << "Words in the dictionary with " << letters << " letters : " << gmw.words.size() << std::endl;
std::cout << std::endl;
do
{
std::cout << "What is your suggestion for the letters [" << gmw.secretWord.second << "] ? " << std::endl;
std::cin >> myGuess;
// to lower case
std::transform(myGuess.begin(), myGuess.end(), myGuess.begin(), [](unsigned char c) { return std::tolower(c); });
tries++;
if (myGuess == "*cheat")
{
gmw.showSecretWords(gmw.secretWord.first, true);
return EXIT_SUCCESS;
}
// boring game?
if (myGuess == "exit")
return EXIT_SUCCESS;
// not the right word length
if (myGuess.length() != gmw.secretWord.first.length())
std::cout << "Not the same length" << std::endl;
else if (!gmw.bAnagram(myGuess, gmw.secretWord.first)) // one or more letters are not in the secret word
std::cout << "Not the right letters" << std::endl; // the letters are good, the length too, but this word is weird
else if (gmw.bAnagram(myGuess, gmw.secretWord.first) && std::find(gmw.words.begin(), gmw.words.end(), myGuess) == gmw.words.end())
std::cout << "It seems that this word does not exist" << std::endl;
} while (!gmw.bAnagram(myGuess, gmw.secretWord.first) || std::find(gmw.words.begin(), gmw.words.end(), myGuess) == gmw.words.end());
// check if two strings are anagrams and if the guessed word exists in the dictionary - or loop again
std::cout << "Correct! You got it in " << tries << " guesses!" << std::endl;
// display alternatives - except the guessed word
gmw.showSecretWords(myGuess, false);
// increase difficulty
letters++;
// max difficulty
if (letters > 14)letters = 14;
}
return EXIT_SUCCESS;
}
|