diff options
-rw-r--r-- | Userland/Games/MasterWord/WordGame.cpp | 49 | ||||
-rw-r--r-- | Userland/Games/MasterWord/WordGame.h | 6 | ||||
-rw-r--r-- | Userland/Games/MasterWord/main.cpp | 23 |
3 files changed, 61 insertions, 17 deletions
diff --git a/Userland/Games/MasterWord/WordGame.cpp b/Userland/Games/MasterWord/WordGame.cpp index 0758034981..a067ab587d 100644 --- a/Userland/Games/MasterWord/WordGame.cpp +++ b/Userland/Games/MasterWord/WordGame.cpp @@ -23,6 +23,7 @@ WordGame::WordGame() read_words(); m_num_letters = Config::read_i32("MasterWord", "", "word_length", 5); m_max_guesses = Config::read_i32("MasterWord", "", "max_guesses", 6); + m_check_guesses = Config::read_bool("MasterWord", "", "check_guesses_in_dictionary", false); reset(); pick_font(); } @@ -74,22 +75,29 @@ void WordGame::keydown_event(GUI::KeyEvent& event) // If we can still add a letter and the key was alpha if (m_current_guess.length() < m_num_letters && is_ascii_alpha(event.code_point())) { m_current_guess = String::formatted("{}{}", m_current_guess, event.text().to_uppercase()); + m_last_word_not_in_dictionary = false; } // If backspace pressed and already have some letters entered else if (event.key() == KeyCode::Key_Backspace && m_current_guess.length() > 0) { m_current_guess = m_current_guess.substring(0, m_current_guess.length() - 1); + m_last_word_not_in_dictionary = false; } // If enough letters and return pressed else if (m_current_guess.length() == m_num_letters && event.key() == KeyCode::Key_Return) { - add_guess(m_current_guess); - auto won = m_current_guess == m_current_word; - m_current_guess = {}; - if (won) { - GUI::MessageBox::show(window(), "You win!", "MasterWord"); - reset(); - } else if (m_guesses.size() == m_max_guesses) { - GUI::MessageBox::show(window(), String::formatted("You lose!\nThe word was {}", m_current_word), "MasterWord"); - reset(); + if (is_in_dictionary(m_current_guess)) { + m_last_word_not_in_dictionary = false; + add_guess(m_current_guess); + auto won = m_current_guess == m_current_word; + m_current_guess = {}; + if (won) { + GUI::MessageBox::show(window(), "You win!", "MasterWord"); + reset(); + } else if (m_guesses.size() == m_max_guesses) { + GUI::MessageBox::show(window(), String::formatted("You lose!\nThe word was {}", m_current_word), "MasterWord"); + reset(); + } + } else { + m_last_word_not_in_dictionary = true; } } @@ -126,6 +134,9 @@ void WordGame::paint_event(GUI::PaintEvent& event) } else if (guess_index == m_guesses.size()) { if (letter_index < m_current_guess.length()) painter.draw_text(this_rect, m_current_guess.substring_view(letter_index, 1), font(), Gfx::TextAlignment::Center, m_text_color); + if (m_last_word_not_in_dictionary) { + painter.fill_rect(this_rect, m_word_not_in_dict_color); + } } painter.draw_rect(this_rect, m_border_color); @@ -140,6 +151,11 @@ Gfx::IntRect WordGame::letter_rect(size_t guess_number, size_t letter_number) co return Gfx::IntRect(int(letter_left), int(letter_top), m_letter_width, m_letter_height); } +bool WordGame::is_in_dictionary(AK::StringView guess) +{ + return !m_check_guesses || !m_words.ensure(guess.length()).find(guess).is_end(); +} + void WordGame::read_words() { m_words.clear(); @@ -153,7 +169,7 @@ void WordGame::read_words() while (!words_file->eof()) { auto current_word = words_file->read_line(); if (!current_word.starts_with('#') and current_word.length() > 0) - m_words.ensure(current_word.length()).append(current_word); + m_words.ensure(current_word.length()).append(current_word.to_uppercase()); } } @@ -162,7 +178,7 @@ Optional<String> WordGame::random_word(size_t length) auto words_for_length = m_words.get(length); if (words_for_length.has_value()) { auto i = get_random_uniform(words_for_length->size()); - return words_for_length->at(i).to_uppercase(); + return words_for_length->at(i); } return {}; @@ -216,6 +232,17 @@ void WordGame::set_max_guesses(size_t max_guesses) reset(); } +void WordGame::set_check_guesses_in_dictionary(bool b) +{ + m_check_guesses = b; + update(); +} + +bool WordGame::is_checking_guesses() const +{ + return m_check_guesses; +} + Gfx::IntSize WordGame::game_size() const { auto w = 2 * m_outer_margin + m_num_letters * m_letter_width + (m_num_letters - 1) * m_letter_spacing; diff --git a/Userland/Games/MasterWord/WordGame.h b/Userland/Games/MasterWord/WordGame.h index 1c62605fd3..02cf32e4b9 100644 --- a/Userland/Games/MasterWord/WordGame.h +++ b/Userland/Games/MasterWord/WordGame.h @@ -19,6 +19,7 @@ public: void reset(); void set_use_system_theme(bool b); + void set_check_guesses_in_dictionary(bool b); void set_word_length(size_t length); void set_max_guesses(size_t max_guesses); Gfx::IntSize game_size() const; @@ -26,8 +27,10 @@ public: Optional<String> random_word(size_t length); size_t shortest_word(); size_t longest_word(); + bool is_checking_guesses() const; void add_guess(AK::StringView guess); + bool is_in_dictionary(AK::StringView guess); private: WordGame(); @@ -42,6 +45,8 @@ private: size_t m_max_guesses { 6 }; size_t m_num_letters { 5 }; + bool m_check_guesses { false }; + bool m_last_word_not_in_dictionary { false }; static constexpr int m_letter_width { 40 }; static constexpr int m_letter_spacing { 5 }; static constexpr int m_outer_margin { 20 }; @@ -53,6 +58,7 @@ private: Color m_wrong_letter_color { m_border_color }; Color m_background_color { Color::from_rgb(0x121213) }; Color m_text_color { Color::White }; + Color m_word_not_in_dict_color { Color::from_argb(0x40aa0000) }; enum LetterState { Correct, diff --git a/Userland/Games/MasterWord/main.cpp b/Userland/Games/MasterWord/main.cpp index abdeee8ff7..28c3dd6978 100644 --- a/Userland/Games/MasterWord/main.cpp +++ b/Userland/Games/MasterWord/main.cpp @@ -59,7 +59,15 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) TRY(game_menu->try_add_action(GUI::Action::create("&New Game", { Mod_None, Key_F2 }, [&](auto&) { game->reset(); }))); - TRY(game_menu->try_add_action(GUI::Action::create("Set &Word Length", [&](auto&) { + + TRY(game_menu->try_add_separator()); + TRY(game_menu->try_add_action(GUI::CommonActions::make_quit_action([](auto&) { + GUI::Application::the()->quit(); + }))); + + auto settings_menu = TRY(window->try_add_menu("&Settings")); + + TRY(settings_menu->try_add_action(GUI::Action::create("Set &Word Length", [&](auto&) { auto word_length = Config::read_i32("MasterWord", "", "word_length", 5); auto word_length_string = String::number(word_length); if (GUI::InputBox::show(window, word_length_string, "Word length:", "MasterWord") == GUI::InputBox::ExecResult::OK && !word_length_string.is_empty()) { @@ -75,7 +83,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) window->resize(game->game_size()); } }))); - TRY(game_menu->try_add_action(GUI::Action::create("Set &Number Of Guesses", [&](auto&) { + TRY(settings_menu->try_add_action(GUI::Action::create("Set &Number Of Guesses", [&](auto&) { auto max_guesses = Config::read_i32("MasterWord", "", "max_guesses", 5); auto max_guesses_string = String::number(max_guesses); if (GUI::InputBox::show(window, max_guesses_string, "Maximum number of guesses:", "MasterWord") == GUI::InputBox::ExecResult::OK && !max_guesses_string.is_empty()) { @@ -92,10 +100,13 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) } }))); - TRY(game_menu->try_add_separator()); - TRY(game_menu->try_add_action(GUI::CommonActions::make_quit_action([](auto&) { - GUI::Application::the()->quit(); - }))); + auto toggle_check_guesses = GUI::Action::create_checkable("Check &Guesses in dictionary", [&](auto& action) { + auto checked = action.is_checked(); + game->set_check_guesses_in_dictionary(checked); + Config::write_bool("MasterWord", "", "check_guesses_in_dictionary", checked); + }); + toggle_check_guesses->set_checked(game->is_checking_guesses()); + TRY(settings_menu->try_add_action(toggle_check_guesses)); auto theme_menu = TRY(window->try_add_menu("&Theme")); auto system_theme_action = GUI::Action::create("&System", [&](auto&) { |