summaryrefslogtreecommitdiffstats
path: root/labb5
diff options
context:
space:
mode:
Diffstat (limited to 'labb5')
-rwxr-xr-xlabb5/src/Boggle.cpp55
-rwxr-xr-xlabb5/src/Boggle.h19
-rwxr-xr-xlabb5/src/boggleplay.cpp8
3 files changed, 47 insertions, 35 deletions
diff --git a/labb5/src/Boggle.cpp b/labb5/src/Boggle.cpp
index 7eb37e8..065d923 100755
--- a/labb5/src/Boggle.cpp
+++ b/labb5/src/Boggle.cpp
@@ -47,10 +47,10 @@ vector<point> neighbours_in_range_filt(const point& p, int width, int height, co
}
/*
- * Return wether word starts with prefix.
+ * Return whether word starts with prefix.
*/
-// There is a string::starts_with in C++20.
bool prefix_matches(const string& prefix, const string& word) {
+ //NOTE There is a string::starts_with in C++20.
for (int i = 0; i < prefix.length(); i++) {
if (prefix[i] != word[i]) return false;
}
@@ -58,12 +58,12 @@ bool prefix_matches(const string& prefix, const string& word) {
}
Boggle::Boggle() {
- board = Grid<char>(4, 4);
+ board = Grid<char>(BOARD_SIZE, BOARD_SIZE);
dictionary = Lexicon(DICTIONARY_FILE);
}
bool Boggle::letters_from_string(const string& letters) {
- if (letters.length() != 16) {
+ if (letters.length() != BOARD_SIZE * BOARD_SIZE) {
return false;
}
for (const auto& letter : letters) {
@@ -72,9 +72,9 @@ bool Boggle::letters_from_string(const string& letters) {
}
}
- for (int y = 0; y < 4; y++) {
- for (int x = 0; x < 4; x++) {
- char c = letters[4*y + x];
+ for (int y = 0; y < BOARD_SIZE; y++) {
+ for (int x = 0; x < BOARD_SIZE; x++) {
+ char c = letters[BOARD_SIZE*y + x];
board[y][x] = c;
}
}
@@ -90,9 +90,9 @@ void Boggle::clear() {
void Boggle::shuffle() {
// Shuffle each dice separately
- for (int y = 0; y < 4; y++) {
- for (int x = 0; x < 4; x++) {
- board[y][x] = CUBES[4*y + x][randomInteger(0, CUBE_SIDES-1)];
+ for (int y = 0; y < BOARD_SIZE; y++) {
+ for (int x = 0; x < BOARD_SIZE; x++) {
+ board[y][x] = CUBES[(BOARD_SIZE*y + x) % NUM_CUBES][randomInteger(0, CUBE_SIDES-1)];
}
}
// Shuffle positions
@@ -101,11 +101,11 @@ void Boggle::shuffle() {
bool Boggle::find_single_word(const string& word) const {
auto start = std::chrono::high_resolution_clock::now();
- // We break immediately if we find a match
- // Without the clock we would return right away
+ // We break immediately if we find a match.
+ // Without the clock we would return right away.
bool found = false;
- for (int y = 0; y < 4; y++) {
- for (int x = 0; x < 4; x++) {
+ for (int y = 0; y < BOARD_SIZE; y++) {
+ for (int x = 0; x < BOARD_SIZE; x++) {
found = find_single_word_helper(word, make_pair(x, y), string(1, board[y][x]), set<point>());
if (found) break;
}
@@ -127,12 +127,14 @@ bool Boggle::find_single_word(const string& word) const {
}
bool Boggle::find_single_word_helper(const string& word, point cur_point, string cur_word, set<point> visited) const {
- if (cur_word == word && dictionary.contains(cur_word)) {
+ if (cur_word == word) {
return true;
}
visited.insert(cur_point);
- for (const auto& neighbour : neighbours_in_range_filt(cur_point, 4, 4, visited)) {
- string new_word = cur_word + board[get<1>(neighbour)][get<0>(neighbour)];
+ for (const auto& neighbour : neighbours_in_range_filt(cur_point, BOARD_SIZE, BOARD_SIZE, visited)) {
+ int n_x, n_y;
+ tie(n_x, n_y) = neighbour;
+ string new_word = cur_word + board[n_y][n_x];
if (prefix_matches(new_word, word)) {
if (find_single_word_helper(word, neighbour, new_word, visited)) {
return true;
@@ -145,8 +147,8 @@ bool Boggle::find_single_word_helper(const string& word, point cur_point, string
set<string> Boggle::find_all_words() const {
set<string> words;
auto start = std::chrono::high_resolution_clock::now();
- for (int y = 0; y < 4; y++) {
- for (int x = 0; x < 4; x++) {
+ for (int y = 0; y < BOARD_SIZE; y++) {
+ for (int x = 0; x < BOARD_SIZE; x++) {
find_all_words_helper(words, make_pair(x, y), string(1, board[y][x]), set<point>());
}
}
@@ -166,8 +168,10 @@ void Boggle::find_all_words_helper(set<string>& words, point cur_point, string c
words.insert(cur_word);
}
visited.insert(cur_point);
- for (const auto& neighbour : neighbours_in_range_filt(cur_point, 4, 4, visited)) {
- string new_word = cur_word + board[get<1>(neighbour)][get<0>(neighbour)];
+ for (const auto& neighbour : neighbours_in_range_filt(cur_point, BOARD_SIZE, BOARD_SIZE, visited)) {
+ int n_x, n_y;
+ tie(n_x, n_y) = neighbour;
+ string new_word = cur_word + board[n_y][n_x];
if (dictionary.containsPrefix(new_word)) {
find_all_words_helper(words, neighbour, new_word, visited);
}
@@ -176,9 +180,10 @@ void Boggle::find_all_words_helper(set<string>& words, point cur_point, string c
string Boggle::board_to_string() const {
string res = "";
- for (int y = 0; y < 4; y++) {
- for (int x = 0; x < 4; x++) {
+ for (int y = 0; y < board.numRows(); y++) {
+ for (int x = 0; x < board.numCols(); x++) {
res += board[y][x];
+ res += ' ';
}
res += '\n';
}
@@ -215,6 +220,10 @@ bool Boggle::word_is_unplayed(const string& word) const {
return !user_words.count(word);
}
+bool Boggle::word_is_valid(const string& word) const {
+ return dictionary.contains(word);
+}
+
void Boggle::add_user_word(const string& word) {
user_words.insert(word);
user_score += word.length() - 3;
diff --git a/labb5/src/Boggle.h b/labb5/src/Boggle.h
index 8e923a9..26cc524 100755
--- a/labb5/src/Boggle.h
+++ b/labb5/src/Boggle.h
@@ -19,9 +19,6 @@ using point = pair<int, int>;
class Boggle {
public:
- const string DICTIONARY_FILE = "EnglishWords.dat";
- const int MIN_WORD_LENGTH = 4;
- static const int BOARD_SIZE = 4;
bool debug_mode = false;
Boggle();
@@ -46,8 +43,9 @@ public:
void shuffle();
/*
- * Return wether a word can be constructed on the current board or not.
+ * Return whether a word can be constructed on the current board or not.
*
+ * Does not check if the word is a valid word or not.
* Times itself if debug_mode is enabled.
*/
bool find_single_word(const string& word) const;
@@ -82,28 +80,31 @@ public:
string words_to_string(const set<string>& words, int words_per_line = 8) const;
/*
- * Run calculations for when it's the computers turn.
+ * Run calculations for when it's the computer's turn.
*
- * Finds which words the computer found and how many points they're worths.
+ * Finds which words the computer found and how many points they're worth.
*/
void do_computer_turn();
+
int get_computer_words_size() const;
int get_computer_score() const;
-
int get_user_words_size() const;
int get_user_score() const;
-
bool word_is_valid(const string& word) const;
bool word_is_unplayed(const string& word) const;
/*
* Add a word the user has found and awards points.
*
- * Does not do any checks.
+ * Does not perform any checks.
*/
void add_user_word(const string& word);
private:
+ const string DICTIONARY_FILE = "EnglishWords.dat";
+ const int MIN_WORD_LENGTH = 4;
+ static const int BOARD_SIZE = 4;
+
void find_all_words_helper(set<string>& words, point cur_point, string cur_word, set<point> visited) const;
bool find_single_word_helper(const string& word, point cur_point, string cur_word, set<point> visited) const;
diff --git a/labb5/src/boggleplay.cpp b/labb5/src/boggleplay.cpp
index f9bf79d..f41c156 100755
--- a/labb5/src/boggleplay.cpp
+++ b/labb5/src/boggleplay.cpp
@@ -55,7 +55,7 @@ void playOneGame(Boggle& boggle) {
clearConsole();
cout << endl; // this is later replaced by the response to the prev word
- if (boggle.debug_mode) cout << endl; // debug mode means two lines
+ if (boggle.debug_mode) cout << endl; // debug mode means two prints per guess
string user_input;
while (true) {
if (boggle.debug_mode) cout << boggle.words_to_string(words_left) << endl << endl;
@@ -67,8 +67,10 @@ void playOneGame(Boggle& boggle) {
if (user_input == "") {
break;
}
- if (!boggle.find_single_word(user_input)) {
- cout << "Your word is invalid" << endl;
+ if (!boggle.word_is_valid(user_input)) {
+ cout << "Your word is invalid!" << endl;
+ } else if (!boggle.find_single_word(user_input)) {
+ cout << "Your word couldn't be found!" << endl;
} else if (!boggle.word_is_unplayed(user_input)) {
cout << "Your word has already been played!" << endl;
} else if (user_input.length() < 4) {