mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 17:17:44 +00:00
MasterWord: Check guesses against the word list
Previously guesses were not checked which allowed guesses like 'aaaaa' to be entered. Currently there's an option to set if a guess should be checked against the dictionary and rejected if it doesn't exist there. Additionally settings from Game menu have been moved to its own entry - Settings.
This commit is contained in:
parent
1297f81ddf
commit
01c7158ffe
3 changed files with 61 additions and 17 deletions
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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&) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue