mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 03:27:45 +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();
|
read_words();
|
||||||
m_num_letters = Config::read_i32("MasterWord", "", "word_length", 5);
|
m_num_letters = Config::read_i32("MasterWord", "", "word_length", 5);
|
||||||
m_max_guesses = Config::read_i32("MasterWord", "", "max_guesses", 6);
|
m_max_guesses = Config::read_i32("MasterWord", "", "max_guesses", 6);
|
||||||
|
m_check_guesses = Config::read_bool("MasterWord", "", "check_guesses_in_dictionary", false);
|
||||||
reset();
|
reset();
|
||||||
pick_font();
|
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 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())) {
|
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_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
|
// If backspace pressed and already have some letters entered
|
||||||
else if (event.key() == KeyCode::Key_Backspace && m_current_guess.length() > 0) {
|
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_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
|
// If enough letters and return pressed
|
||||||
else if (m_current_guess.length() == m_num_letters && event.key() == KeyCode::Key_Return) {
|
else if (m_current_guess.length() == m_num_letters && event.key() == KeyCode::Key_Return) {
|
||||||
add_guess(m_current_guess);
|
if (is_in_dictionary(m_current_guess)) {
|
||||||
auto won = m_current_guess == m_current_word;
|
m_last_word_not_in_dictionary = false;
|
||||||
m_current_guess = {};
|
add_guess(m_current_guess);
|
||||||
if (won) {
|
auto won = m_current_guess == m_current_word;
|
||||||
GUI::MessageBox::show(window(), "You win!", "MasterWord");
|
m_current_guess = {};
|
||||||
reset();
|
if (won) {
|
||||||
} else if (m_guesses.size() == m_max_guesses) {
|
GUI::MessageBox::show(window(), "You win!", "MasterWord");
|
||||||
GUI::MessageBox::show(window(), String::formatted("You lose!\nThe word was {}", m_current_word), "MasterWord");
|
reset();
|
||||||
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()) {
|
} else if (guess_index == m_guesses.size()) {
|
||||||
if (letter_index < m_current_guess.length())
|
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);
|
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);
|
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);
|
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()
|
void WordGame::read_words()
|
||||||
{
|
{
|
||||||
m_words.clear();
|
m_words.clear();
|
||||||
|
@ -153,7 +169,7 @@ void WordGame::read_words()
|
||||||
while (!words_file->eof()) {
|
while (!words_file->eof()) {
|
||||||
auto current_word = words_file->read_line();
|
auto current_word = words_file->read_line();
|
||||||
if (!current_word.starts_with('#') and current_word.length() > 0)
|
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);
|
auto words_for_length = m_words.get(length);
|
||||||
if (words_for_length.has_value()) {
|
if (words_for_length.has_value()) {
|
||||||
auto i = get_random_uniform(words_for_length->size());
|
auto i = get_random_uniform(words_for_length->size());
|
||||||
return words_for_length->at(i).to_uppercase();
|
return words_for_length->at(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -216,6 +232,17 @@ void WordGame::set_max_guesses(size_t max_guesses)
|
||||||
reset();
|
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
|
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;
|
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 reset();
|
||||||
void set_use_system_theme(bool b);
|
void set_use_system_theme(bool b);
|
||||||
|
void set_check_guesses_in_dictionary(bool b);
|
||||||
void set_word_length(size_t length);
|
void set_word_length(size_t length);
|
||||||
void set_max_guesses(size_t max_guesses);
|
void set_max_guesses(size_t max_guesses);
|
||||||
Gfx::IntSize game_size() const;
|
Gfx::IntSize game_size() const;
|
||||||
|
@ -26,8 +27,10 @@ public:
|
||||||
Optional<String> random_word(size_t length);
|
Optional<String> random_word(size_t length);
|
||||||
size_t shortest_word();
|
size_t shortest_word();
|
||||||
size_t longest_word();
|
size_t longest_word();
|
||||||
|
bool is_checking_guesses() const;
|
||||||
|
|
||||||
void add_guess(AK::StringView guess);
|
void add_guess(AK::StringView guess);
|
||||||
|
bool is_in_dictionary(AK::StringView guess);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WordGame();
|
WordGame();
|
||||||
|
@ -42,6 +45,8 @@ private:
|
||||||
|
|
||||||
size_t m_max_guesses { 6 };
|
size_t m_max_guesses { 6 };
|
||||||
size_t m_num_letters { 5 };
|
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_width { 40 };
|
||||||
static constexpr int m_letter_spacing { 5 };
|
static constexpr int m_letter_spacing { 5 };
|
||||||
static constexpr int m_outer_margin { 20 };
|
static constexpr int m_outer_margin { 20 };
|
||||||
|
@ -53,6 +58,7 @@ private:
|
||||||
Color m_wrong_letter_color { m_border_color };
|
Color m_wrong_letter_color { m_border_color };
|
||||||
Color m_background_color { Color::from_rgb(0x121213) };
|
Color m_background_color { Color::from_rgb(0x121213) };
|
||||||
Color m_text_color { Color::White };
|
Color m_text_color { Color::White };
|
||||||
|
Color m_word_not_in_dict_color { Color::from_argb(0x40aa0000) };
|
||||||
|
|
||||||
enum LetterState {
|
enum LetterState {
|
||||||
Correct,
|
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&) {
|
TRY(game_menu->try_add_action(GUI::Action::create("&New Game", { Mod_None, Key_F2 }, [&](auto&) {
|
||||||
game->reset();
|
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 = Config::read_i32("MasterWord", "", "word_length", 5);
|
||||||
auto word_length_string = String::number(word_length);
|
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()) {
|
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());
|
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 = Config::read_i32("MasterWord", "", "max_guesses", 5);
|
||||||
auto max_guesses_string = String::number(max_guesses);
|
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()) {
|
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());
|
auto toggle_check_guesses = GUI::Action::create_checkable("Check &Guesses in dictionary", [&](auto& action) {
|
||||||
TRY(game_menu->try_add_action(GUI::CommonActions::make_quit_action([](auto&) {
|
auto checked = action.is_checked();
|
||||||
GUI::Application::the()->quit();
|
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 theme_menu = TRY(window->try_add_menu("&Theme"));
|
||||||
auto system_theme_action = GUI::Action::create("&System", [&](auto&) {
|
auto system_theme_action = GUI::Action::create("&System", [&](auto&) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue