Compare commits

..

10 Commits

4 changed files with 123 additions and 16 deletions

View File

@ -10,21 +10,103 @@
#include "random.h" #include "random.h"
#include "shuffle.h" #include "shuffle.h"
#include "strlib.h" #include "strlib.h"
#include <fstream>
#include <sstream> #include <sstream>
#include <unordered_set>
// The res folder isn't copied the same way on macOS // The res folder isn't copied the same way on macOS
#ifdef __APPLE__ #ifdef __APPLE__
const std::string Boggle::DICTIONARY_FILE = "../../../EnglishWords.dat"; const std::string Boggle::s_DICTIONARY_FILE = "../../../EnglishWords.dat";
#else #else
const std::string Boggle::DICTIONARY_FILE = "EnglishWords.dat"; const std::string Boggle::DICTIONARY_FILE = "EnglishWords.dat";
#endif #endif
static const int NUM_CUBES = 16; // the number of cubes in the game static const int g_NUM_CUBES = 16; // the number of cubes in the game
static const int CUBE_SIDES = 6; // the number of sides on each cube static const int g_CUBE_SIDES = 6; // the number of sides on each cube
static std::string CUBES[NUM_CUBES] = { // the letters on all 6 sides of every cube static std::string g_CUBES[g_NUM_CUBES] =
{ // the letters on all 6 sides of every cube
"AAEEGN", "ABBJOO", "ACHOPS", "AFFKPS", "AOOTTW", "CIMOTU", "AAEEGN", "ABBJOO", "ACHOPS", "AFFKPS", "AOOTTW", "CIMOTU",
"DEILRX", "DELRVY", "DISTTY", "EEGHNW", "EEINSU", "EHRTVW", "DEILRX", "DELRVY", "DISTTY", "EEGHNW", "EEINSU", "EHRTVW",
"EIOSST", "ELRTTY", "HIMNQU", "HLNNRZ"}; "EIOSST", "ELRTTY", "HIMNQU", "HLNNRZ"};
// TODO: implement the members you declared in Boggle.h std::array<std::string, g_NUM_ROLLED_CUBES> rollSides() {
// Intermediate array to shuffle
std::array<std::string, g_NUM_CUBES> cubes;
std::copy(std::begin(g_CUBES), std::end(g_CUBES), cubes.begin());
shuffle(cubes.data(), cubes.size());
// Just return the first g_NUM_ROLLED_CUBES (4pcs) entries
std::array<std::string, g_NUM_ROLLED_CUBES> ret;
std::copy(cubes.begin(), cubes.begin() + g_NUM_ROLLED_CUBES, ret.begin());
return ret;
}
Boggle::Boggle()
: m_showingSides(rollSides()), m_englishWords(Boggle::s_DICTIONARY_FILE) {}
bool Boggle::isWordEnglish(const std::string &word) const {
return m_englishWords.contains(word);
}
bool Boggle::isWordLongEnough(const std::string &word) const {
return word.length() >= s_MIN_WORD_LENGTH;
}
bool Boggle::isWordPlayed(const std::string &word) const {
return std::find(m_playedWords.begin(), m_playedWords.end(), word) !=
m_playedWords.end();
}
unsigned int Boggle::getPointsForWord(const std::string &word) {
// This is kept as a variable to avoid static_cast<int>
const int pointsForValidWord = word.length() - s_MIN_WORD_LENGTH;
return std::min(pointsForValidWord, 0);
}
bool Boggle::userInsert(std::string word){
bool existsAlready = std::find(m_playedWords.begin(), m_playedWords.end(), word) != m_playedWords.end();
if (existsAlready)
return false;
m_playedWords.push_back(std::move(word));
return true;
}
std::vector<std::string> Boggle::computerPlay() const {
std::unordered_set<std::string> visited;
std::vector<std::string> valiWords;
for (const std::string &cube : m_showingSides) {
visited.insert(cube);
std::string word;
for (const char c : word) {
word.push_back(c);
backtrack(valiWords, visited, word);
}
}
return valiWords;
}
void Boggle::backtrack(std::vector<std::string> &validWords,
std::unordered_set<string> &visited,
std::string &word) const {
if (!m_englishWords.containsPrefix(word))
return;
if (word.size() >= s_MIN_WORD_LENGTH && m_englishWords.contains(word))
validWords.push_back(word);
for (const std::string &neighbor : m_showingSides) {
bool neighborAlreadyVisited = visited.find(neighbor) != visited.end();
if (neighborAlreadyVisited)
continue;
visited.insert(word);
for (const char neighborChar : neighbor) {
word.push_back(neighborChar);
backtrack(validWords, visited, word);
word.pop_back();
}
}
}

View File

@ -9,21 +9,48 @@
#ifndef _boggle_h #ifndef _boggle_h
#define _boggle_h #define _boggle_h
#include "lexicon.h"
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <unordered_set>
#include <vector>
static const int g_NUM_ROLLED_CUBES = 4;
class Boggle { class Boggle {
public: public:
static const std::string DICTIONARY_FILE; static const std::string s_DICTIONARY_FILE;
const int MIN_WORD_LENGTH = 4; static const int s_MIN_WORD_LENGTH = 4;
const int BOARD_SIZE = 4; static const int s_BOARD_SIZE = 4;
// TODO: decide the public member functions and declare them Boggle();
bool isWordEnglish(const std::string &word) const;
bool isWordLongEnough(const std::string &word) const;
bool isWordPlayed(const std::string &word) const;
static unsigned int getPointsForWord(const std::string &word);
/**
* @brief userInsert saves the users word
* @return false if the word is already inserted
*/
bool userInsert(std::string word);
/**
* @brief computerPlay calculates all possible english words which can be
* formed from the Lexicon recursivly
* @return all possible words of the current board
*/
std::vector<std::string> computerPlay() const;
private: private:
// TODO: decide the private member variables/functions and declare them void backtrack(std::vector<std::string> &validWords,
std::unordered_set<string> &visited, std::string &word) const;
private:
// This is kept as a vector since there's max 16 words
std::vector<std::string> m_playedWords;
std::array<std::string, g_NUM_ROLLED_CUBES> m_showingSides;
Lexicon m_englishWords;
}; };
#endif #endif

View File

@ -11,11 +11,10 @@
#include "Boggle.h" #include "Boggle.h"
#include <string> #include <string>
using namespace std;
void intro(); void intro();
void playOneGame(Boggle& boggle); void playOneGame(Boggle& boggle);
bool yesOrNo(string prompt); bool yesOrNo(std::string prompt);
void clearConsole(); void clearConsole();
#endif #endif

View File

@ -15,7 +15,6 @@
* 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) {
// TODO: implement this function (and add any other functions you like to help you)
} }