Compare commits

..

2 Commits

Author SHA1 Message Date
7611d51bc4 Fix points + computerPlay
- computerPlay was iterating over an empty word
- Boggle::getPointsForWord was using std::min instead of std::max
2024-09-12 22:26:57 +02:00
316e212ab4 getter for user played words 2024-09-12 16:29:05 +02:00
3 changed files with 139 additions and 11 deletions

View File

@ -42,7 +42,15 @@ std::array<std::string, g_NUM_ROLLED_CUBES> rollSides() {
} }
Boggle::Boggle() Boggle::Boggle()
: m_showingSides(rollSides()), m_englishWords(Boggle::s_DICTIONARY_FILE) {} : m_showingSides(rollSides()), m_englishWords(Boggle::s_DICTIONARY_FILE) {
std::cout << "Lexicon size: " << m_englishWords.size() << std::endl;
}
const std::vector<string> &Boggle::playedWords() const { return m_playedWords; }
const std::array<string, g_NUM_ROLLED_CUBES> Boggle::showingSides() const {
return m_showingSides;
}
bool Boggle::isWordEnglish(const std::string &word) const { bool Boggle::isWordEnglish(const std::string &word) const {
return m_englishWords.contains(word); return m_englishWords.contains(word);
@ -60,11 +68,12 @@ bool Boggle::isWordPlayed(const std::string &word) const {
unsigned int Boggle::getPointsForWord(const std::string &word) { unsigned int Boggle::getPointsForWord(const std::string &word) {
// This is kept as a variable to avoid static_cast<int> // This is kept as a variable to avoid static_cast<int>
const int pointsForValidWord = word.length() - s_MIN_WORD_LENGTH; const int pointsForValidWord = word.length() - s_MIN_WORD_LENGTH;
return std::min(pointsForValidWord, 0); return std::max(pointsForValidWord, 0);
} }
bool Boggle::userInsert(std::string word) { bool Boggle::userInsert(std::string word) {
bool existsAlready = std::find(m_playedWords.begin(), m_playedWords.end(), word) != m_playedWords.end(); bool existsAlready = std::find(m_playedWords.begin(), m_playedWords.end(),
word) != m_playedWords.end();
if (existsAlready) if (existsAlready)
return false; return false;
@ -76,10 +85,11 @@ std::vector<std::string> Boggle::computerPlay() const {
std::unordered_set<std::string> visited; std::unordered_set<std::string> visited;
std::vector<std::string> valiWords; std::vector<std::string> valiWords;
std::cout << "showing sides: "<<m_showingSides.size() <<std::endl;
for (const std::string &cube : m_showingSides) { for (const std::string &cube : m_showingSides) {
visited.insert(cube); visited.insert(cube);
std::string word; std::string word;
for (const char c : word) { for (const char c : cube) {
word.push_back(c); word.push_back(c);
backtrack(valiWords, visited, word); backtrack(valiWords, visited, word);
} }

View File

@ -23,8 +23,14 @@ public:
static const int s_MIN_WORD_LENGTH = 4; static const int s_MIN_WORD_LENGTH = 4;
static const int s_BOARD_SIZE = 4; static const int s_BOARD_SIZE = 4;
public:
Boggle(); Boggle();
/**
* Getter for the users played words
*/
const std::vector<std::string> &playedWords() const;
const std::array<std::string, g_NUM_ROLLED_CUBES> showingSides() const;
bool isWordEnglish(const std::string &word) const; bool isWordEnglish(const std::string &word) const;
bool isWordLongEnough(const std::string &word) const; bool isWordLongEnough(const std::string &word) const;
bool isWordPlayed(const std::string &word) const; bool isWordPlayed(const std::string &word) const;

View File

@ -2,20 +2,132 @@
// Also remove these comments here and add your own. // Also remove these comments here and add your own.
// TODO: remove this comment header and replace with your own // TODO: remove this comment header and replace with your own
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <sstream>
#include "Boggle.h" #include "Boggle.h"
#include "bogglemain.h" #include "bogglemain.h"
#include "strlib.h" #include "strlib.h"
// TODO: include any other header files you need #include <cstdlib>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <thread>
static const size_t LINE_LENGTH = 80;
void printSlow(const char *const str, unsigned int msBetween) {
for (const char *c = str; *c; c++) {
std::cout << *c;
std::flush(std::cout);
std::this_thread::sleep_for(std::chrono::milliseconds(msBetween));
}
}
std::string wordsToStringLimit(const std::vector<std::string> &words,
const size_t limitMaxLine,
const size_t startLine) {
if (words.empty())
return "{}";
const std::string linePrefix(startLine, ' ');
std::string ret = "{";
int lineLength = startLine + 1; // +1 for the '{'
for (size_t i = 0; i < words.size(); i++) {
std::string word = "\"" + words[i] + "\"";
if (i != words.size() - 1) {
word += ",";
}
if (word.size() + lineLength <= limitMaxLine) {
ret += word + " ";
lineLength += word.size() + 1; // +1 for the space
continue;
}
// Start a new line, with the prefix
ret += "\n" + linePrefix + word + " ";
lineLength = startLine + word.size() + 1; // +1 for the space
}
ret.back() = '}';
return ret;
}
/* /*
* Plays one game of Boggle using the given boggle game state object. * Plays one game of Boggle using the given boggle game state object.
*/ */
void playOneGame(Boggle &boggle) { void playOneGame(Boggle &boggle) {
std::string userInput;
size_t userScore = 0;
std::cout << "It's your turn!\n";
std::cout << "Showing sides:\n";
for (const std::string &side : boggle.showingSides())
std::cout << ' ' << side << '\n';
while (true) {
const std::vector<std::string> &words = boggle.playedWords();
std::string wordsInfo =
"Your words (" + std::to_string(words.size()) + "): ";
// std::endl flushes the line, it's not necessary yet, hence the \n
std::cout << wordsInfo
<< wordsToStringLimit(words, LINE_LENGTH, wordsInfo.length())
<< '\n';
std::cout << "Your score: " << userScore << '\n';
std::cout << "Type a word (or press Enter to end your turn): ";
std::flush(std::cout); // Finally flush!
std::string answer;
std::getline(std::cin, answer);
if (answer.empty())
break;
if (answer.size() > 16) {
std::cout << "Your word may not be longer than 16 characters!"
<< std::endl;
continue;
}
if (!boggle.isWordLongEnough(answer)) {
std::cout << "Your word is not long enough!" << std::endl;
continue;
}
if (boggle.isWordPlayed(answer)) {
std::cout << "You've already played that word!" << std::endl;
continue;
}
if (!boggle.isWordEnglish(answer)) {
std::cout << "Silly human, that's not a real word!" << std::endl;
continue;
}
boggle.userInsert(answer);
userScore += Boggle::getPointsForWord(answer);
}
std::cout << "It's my turn!" << std::endl;
std::vector<std::string> words = boggle.computerPlay();
size_t myScore = 0;
for (const std::string &word : words)
myScore += Boggle::getPointsForWord(word);
std::string wordsInfo = "My words (" + std::to_string(words.size()) + "): ";
std::cout << wordsInfo
<< wordsToStringLimit(words, LINE_LENGTH, wordsInfo.length())
<< '\n';
std::cout << "My score: " << myScore << '\n';
if (myScore > userScore) {
std::cout << "Ha ha ha, I destroyed you. Better luck next time, puny human!"
<< std::endl;
} else {
std::flush(std::cout);
printSlow("¡Que pasa! You", 25);
printSlow("... won 😭", 150);
std::this_thread::sleep_for(std::chrono::milliseconds(200));
std::cout << '\n';
printSlow("Well", 70);
printSlow(", uhhhhh", 200);
printSlow(", well played!", 50);
printSlow(", I suppose", 200);
}
} }
/* /*