From 31d3f7ad0f3f04b5c270d7bccc77df888183f291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Sun, 16 Aug 2020 03:51:28 +0200 Subject: initial lab2 hangman --- lab2/evilhangman/src/evilhangman.cpp | 137 +++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 lab2/evilhangman/src/evilhangman.cpp (limited to 'lab2/evilhangman/src') diff --git a/lab2/evilhangman/src/evilhangman.cpp b/lab2/evilhangman/src/evilhangman.cpp new file mode 100644 index 0000000..57c0d0f --- /dev/null +++ b/lab2/evilhangman/src/evilhangman.cpp @@ -0,0 +1,137 @@ +#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; + } +} -- cgit v1.2.1