#include #include #include #include #include #include #include #include using namespace std; const string ALPHABET = "abcdefghijklmnopqrstuvwxyz"; void openDictionary(map> &wordsByLength, string path) { ifstream input; input.open(path); string word; while (input >> word) { int length = word.length(); if (wordsByLength.count(length) == 0) { wordsByLength[length] = list(); } wordsByLength[length].push_front(word); } input.close(); } // update prototype void getWordPrototype(string &wordCandidate, string &word, char guess) { for (int i = 0; i < word.size(); i++) { if (word[i] == guess) { wordCandidate[i] = guess; } } } // populate wordGroup with the biggest word group after selecting words for guess from word, return wether prototype changed bool getWordGroup(list &wordGroup, string &wordPrototype, char guess) { unordered_map> wordGroups; for (string &word: wordGroup) { if (word.find(guess) == string::npos) { // word doesn't contain guess if (wordGroups.count(wordPrototype) == 0) { wordGroups[wordPrototype] = list(); } wordGroups[wordPrototype].push_back(word); } else { // word contains guess at least once string newWordPrototype(wordPrototype); getWordPrototype(newWordPrototype, word, guess); if (wordGroups.count(newWordPrototype) == 0) { wordGroups[newWordPrototype] = list(); } wordGroups[newWordPrototype].push_back(word); } } // find biggest word group int maxSize = 0; string maxWord; for (auto &n: wordGroups) { int size = n.second.size(); if (size > maxSize) { maxSize = size; maxWord = n.first; } } wordGroup = wordGroups[maxWord]; if (wordPrototype == maxWord) { return false; } else { wordPrototype = maxWord; return true; } } int main() { cout << "Welcome to Hangman." << endl; map> wordsByLength; openDictionary(wordsByLength, "res/dictionary.txt"); int wordLength; while (cout << "Choose a word length to guess: " && cin >> wordLength) { if (wordsByLength.count(wordLength) == 0) { cout << "No words of that length found." << endl; } else { break; } } int guesses; cout << "Choose number of guesses: "; cin >> guesses; bool showWordsLeft; { char response; cout << "Would you like to see the number of words left? [Y/n]: "; cin >> response; showWordsLeft = (response != 'n'); } string wordPrototype; for (int i = 0; i < wordLength; i++) { wordPrototype.push_back('-'); } list wordGroup = wordsByLength[wordLength]; set guessedChars; bool won = false; while (guesses > 0 && !won) { if (showWordsLeft) { cout << "(" << wordGroup.size() << ") "; } cout << wordPrototype << " with " << guesses << " guesses left. Guessed characters: "; for (char c: guessedChars) { cout << c; } cout << endl; cout << "Guess a letter: "; char guess; cin >> guess; if (getWordGroup(wordGroup, wordPrototype, guess)) { won = (wordPrototype.find('-') == string::npos); } else { guessedChars.insert(guess); guesses--; } } if (won) { cout << "Well done!" << endl; } else { cout << "The word was '" << wordGroup.front() << "'. Better luck next time." << endl; } }