summaryrefslogtreecommitdiffstats
path: root/labb5/src/Boggle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'labb5/src/Boggle.cpp')
-rwxr-xr-xlabb5/src/Boggle.cpp119
1 files changed, 89 insertions, 30 deletions
diff --git a/labb5/src/Boggle.cpp b/labb5/src/Boggle.cpp
index be4d40b..06880e8 100755
--- a/labb5/src/Boggle.cpp
+++ b/labb5/src/Boggle.cpp
@@ -11,6 +11,7 @@
#include "shuffle.h"
#include "strlib.h"
#include <chrono>
+#include <algorithm>
static const int NUM_CUBES = 16; // the number of cubes in the game
static const int CUBE_SIDES = 6; // the number of sides on each cube
@@ -29,7 +30,7 @@ vector<point> neighbours_in_range_filt(const point& p, int width, int height, co
if (y + dy < 0 || y + dy >= height) continue;
for (int dx = -1; dx <= 1; dx++) {
if (dy == 0 && dx == 0) continue;
- if (x + dx < 0 || x + dx >= height) continue;
+ if (x + dx < 0 || x + dx >= width) continue;
point new_p = make_pair(x + dx, y + dy);
if (visited.count(new_p)) continue;
res.push_back(new_p);
@@ -63,9 +64,10 @@ bool Boggle::letters_from_string(const string& letters) {
}
void Boggle::clear() {
- valid_words.clear();
user_words.clear();
+ computer_words.clear();
user_score = 0;
+ computer_score = 0;
}
void Boggle::shuffle() {
@@ -79,41 +81,80 @@ void Boggle::shuffle() {
::shuffle(board);
}
-void Boggle::find_all_words() {
+bool Boggle::find_single_word(const string& word) const {
auto start = std::chrono::high_resolution_clock::now();
+ bool found = false;
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
- find_words_helper(make_pair(x, y), string(1, board[y][x]), set<point>());
+ found = find_single_word_helper(word, make_pair(x, y), string(1, board[y][x]), set<point>());
+ if (found) break;
}
+ if (found) break;
}
auto end = std::chrono::high_resolution_clock::now();
- cout << valid_words.size()
- << " words in "
+ if (found) {
+ cout << "Found word";
+ } else {
+ cout << "Didn't find word";
+ }
+ cout << " in "
<< std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()/1000.0
<< " ms"
<< endl;
+ return found;
+}
+
+bool prefix_matches(const string& prefix, const string& word) {
+ for (int i = 0; i < prefix.length(); i++) {
+ if (prefix[i] != word[i]) return false;
+ }
+ return true;
}
-void Boggle::find_words_helper(point cur_point, string cur_word, set<point> visited) {
- if (cur_word.length() >= 4 && valid_words.count(cur_word) == 0 && dictionary.contains(cur_word)) {
- valid_words.insert(cur_word);
+bool Boggle::find_single_word_helper(const string& word, point cur_point, string cur_word, set<point> visited) const {
+ 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)];
- if (dictionary.containsPrefix(new_word)) {
- find_words_helper(neighbour, new_word, visited);
+ if (prefix_matches(new_word, word)) {
+ if (find_single_word_helper(word, neighbour, new_word, visited)) {
+ return true;
+ }
}
}
- visited.erase(cur_point);
+ return false;
}
-string Boggle::debug_words() const {
- string res = "";
- for (const auto& word : valid_words) {
- res += word + " ";
+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++) {
+ find_all_words_helper(words, make_pair(x, y), string(1, board[y][x]), set<point>());
+ }
+ }
+ auto end = std::chrono::high_resolution_clock::now();
+ cout << words.size()
+ << " words in "
+ << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()/1000.0
+ << " ms"
+ << endl;
+ return words;
+}
+
+void Boggle::find_all_words_helper(set<string>& words, point cur_point, string cur_word, set<point> visited) const {
+ if (cur_word.length() >= 4 && words.count(cur_word) == 0 && dictionary.contains(cur_word)) {
+ 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)];
+ if (dictionary.containsPrefix(new_word)) {
+ find_all_words_helper(words, neighbour, new_word, visited);
+ }
}
- return res;
}
string Boggle::board_to_string() const {
@@ -127,6 +168,24 @@ string Boggle::board_to_string() const {
return res;
}
+void Boggle::do_computer_turn() {
+ set<string> all_words = find_all_words();
+ set_difference(all_words.begin(), all_words.end(),
+ user_words.begin(), user_words.end(),
+ inserter(computer_words, computer_words.begin()));
+ for (const auto& word : computer_words) {
+ computer_score += word.length() - 3;
+ }
+}
+
+int Boggle::get_computer_words_size() const {
+ return computer_words.size();
+}
+
+int Boggle::get_computer_score() const {
+ return computer_score;
+}
+
int Boggle::get_user_words_size() const {
return user_words.size();
}
@@ -135,29 +194,29 @@ int Boggle::get_user_score() const {
return user_score;
}
-bool Boggle::word_is_valid(const string& word) const {
- return valid_words.count(word);
-}
-
bool Boggle::word_is_unplayed(const string& word) const {
return !user_words.count(word);
}
-bool Boggle::add_user_word(const string& word) {
- if (word_is_valid(word) && word_is_unplayed(word) && word.length() >= 4) {
- user_words.insert(word);
- user_score += word.length() - 3;
- return true;
- }
- return false;
+void Boggle::add_user_word(const string& word) {
+ user_words.insert(word);
+ user_score += word.length() - 3;
}
string Boggle::user_words_to_string(int words_per_line) const {
+ return words_to_string(user_words, words_per_line);
+}
+
+string Boggle::computer_words_to_string(int words_per_line) const {
+ return words_to_string(computer_words, words_per_line);
+}
+
+string Boggle::words_to_string(const set<string>& words, int words_per_line) const {
string res = "";
long unsigned int cur_word_idx = 0;
- for (const auto& word : user_words) {
+ for (const auto& word : words) {
res += word;
- if (cur_word_idx != user_words.size() - 1) {
+ if (cur_word_idx != words.size() - 1) {
// comma after every word except the final
res += ", ";