From 7b4b060b9ce986ab2870d68e9675fbef4774b467 Mon Sep 17 00:00:00 2001 From: Pedro Pereira Date: Sun, 14 Nov 2021 11:53:56 +0000 Subject: Minesweeper: Create field from Difficulty enum This change makes it easier to generate a new field. Instead of using hard-coded values everywhere, we now just need to keep track of the Difficulty enum value. --- Userland/Games/Minesweeper/CustomGameDialog.cpp | 2 +- Userland/Games/Minesweeper/Field.cpp | 34 ++++++++++++++-- Userland/Games/Minesweeper/Field.h | 52 ++++++++++++++++++++++++- Userland/Games/Minesweeper/main.cpp | 17 ++++---- 4 files changed, 91 insertions(+), 14 deletions(-) diff --git a/Userland/Games/Minesweeper/CustomGameDialog.cpp b/Userland/Games/Minesweeper/CustomGameDialog.cpp index 4e69303747..3e5e24b46a 100644 --- a/Userland/Games/Minesweeper/CustomGameDialog.cpp +++ b/Userland/Games/Minesweeper/CustomGameDialog.cpp @@ -26,7 +26,7 @@ int CustomGameDialog::show(GUI::Window* parent_window, Field& field) if (result != GUI::Dialog::ExecOK) return result; - field.set_field_size(dialog->m_rows_spinbox->value(), dialog->m_columns_spinbox->value(), dialog->m_mines_spinbox->value()); + field.set_field_size(Field::Difficulty::Custom, dialog->m_rows_spinbox->value(), dialog->m_columns_spinbox->value(), dialog->m_mines_spinbox->value()); return GUI::Dialog::ExecOK; } diff --git a/Userland/Games/Minesweeper/Field.cpp b/Userland/Games/Minesweeper/Field.cpp index 7da152e286..7084c2542b 100644 --- a/Userland/Games/Minesweeper/Field.cpp +++ b/Userland/Games/Minesweeper/Field.cpp @@ -140,12 +140,16 @@ Field::Field(GUI::Label& flag_label, GUI::Label& time_label, GUI::Button& face_b int mine_count = Config::read_i32("Minesweeper", "Game", "MineCount", 10); int rows = Config::read_i32("Minesweeper", "Game", "Rows", 9); int columns = Config::read_i32("Minesweeper", "Game", "Columns", 9); + auto difficulty_string = Config::read_string("Minesweeper", "Game", "Difficulty", "beginner"); + auto difficulty = difficulty_from_string(difficulty_string); // Do a quick sanity check to make sure the user hasn't tried anything crazy - if (mine_count > rows * columns || rows <= 0 || columns <= 0 || mine_count <= 0) - set_field_size(9, 9, 10); + if (!difficulty.has_value() || mine_count > rows * columns || rows <= 0 || columns <= 0 || mine_count <= 0) + set_field_difficulty(Difficulty::Beginner); + else if (difficulty.value() == Difficulty::Custom) + set_field_size(Difficulty::Custom, rows, columns, mine_count); else - set_field_size(rows, columns, mine_count); + set_field_difficulty(difficulty.value()); set_single_chording(single_chording); } @@ -481,7 +485,27 @@ void Field::set_chord_preview(Square& square, bool chord_preview) }); } -void Field::set_field_size(size_t rows, size_t columns, size_t mine_count) +void Field::set_field_difficulty(Difficulty difficulty) +{ + switch (difficulty) { + case Difficulty::Beginner: + set_field_size(difficulty, 9, 9, 10); + break; + case Difficulty::Intermediate: + set_field_size(difficulty, 16, 16, 40); + break; + case Difficulty::Expert: + set_field_size(difficulty, 16, 30, 99); + break; + case Difficulty::Madwoman: + set_field_size(difficulty, 32, 60, 350); + break; + default: + VERIFY_NOT_REACHED(); + } +} + +void Field::set_field_size(Difficulty difficulty, size_t rows, size_t columns, size_t mine_count) { if (m_rows == rows && m_columns == columns && m_mine_count == mine_count) return; @@ -489,7 +513,9 @@ void Field::set_field_size(size_t rows, size_t columns, size_t mine_count) Config::write_i32("Minesweeper", "Game", "MineCount", mine_count); Config::write_i32("Minesweeper", "Game", "Rows", rows); Config::write_i32("Minesweeper", "Game", "Columns", columns); + Config::write_string("Minesweeper", "Game", "Difficulty", difficulty_to_string(difficulty)); } + m_difficulty = difficulty; m_rows = rows; m_columns = columns; m_mine_count = mine_count; diff --git a/Userland/Games/Minesweeper/Field.h b/Userland/Games/Minesweeper/Field.h index a550714948..34e1e0ae11 100644 --- a/Userland/Games/Minesweeper/Field.h +++ b/Userland/Games/Minesweeper/Field.h @@ -45,13 +45,62 @@ class Field final : public GUI::Frame { public: virtual ~Field() override; + enum class Difficulty { + Beginner, + Intermediate, + Expert, + Madwoman, + Custom + }; + + StringView difficulty_to_string(Difficulty difficulty) const + { + switch (difficulty) { + case Difficulty::Beginner: + return "beginner"sv; + case Difficulty::Intermediate: + return "intermediate"sv; + case Difficulty::Expert: + return "expert"sv; + case Difficulty::Madwoman: + return "madwoman"sv; + case Difficulty::Custom: + return "custom"sv; + default: + VERIFY_NOT_REACHED(); + } + } + + Optional difficulty_from_string(StringView difficulty_string) const + { + if (difficulty_string.matches("beginner")) + return Difficulty::Beginner; + + if (difficulty_string.equals_ignoring_case("intermediate")) + return Difficulty::Intermediate; + + if (difficulty_string.equals_ignoring_case("expert")) + return Difficulty::Expert; + + if (difficulty_string.equals_ignoring_case("madwoman")) + return Difficulty::Madwoman; + + if (difficulty_string.equals_ignoring_case("custom")) + return Difficulty::Custom; + + return {}; + } + + Difficulty difficulty() const { return m_difficulty; } size_t rows() const { return m_rows; } size_t columns() const { return m_columns; } size_t mine_count() const { return m_mine_count; } int square_size() const { return 15; } bool is_single_chording() const { return m_single_chording; } - void set_field_size(size_t rows, size_t columns, size_t mine_count); + void set_field_difficulty(Difficulty difficulty); + void set_field_size(Difficulty difficulty, size_t rows, size_t columns, size_t mine_count); + void set_single_chording(bool new_val); void reset(); @@ -87,6 +136,7 @@ private: }; void set_face(Face); + Difficulty m_difficulty { Difficulty::Beginner }; size_t m_rows { 0 }; size_t m_columns { 0 }; size_t m_mine_count { 0 }; diff --git a/Userland/Games/Minesweeper/main.cpp b/Userland/Games/Minesweeper/main.cpp index d91186db7e..d8b8237357 100644 --- a/Userland/Games/Minesweeper/main.cpp +++ b/Userland/Games/Minesweeper/main.cpp @@ -125,30 +125,30 @@ int main(int argc, char** argv) difficulty_actions.set_exclusive(true); auto action = GUI::Action::create_checkable("&Beginner", { Mod_Ctrl, Key_B }, [&](auto&) { - field.set_field_size(9, 9, 10); + field.set_field_difficulty(Field::Difficulty::Beginner); }); - action->set_checked(field.rows() == 9 && field.columns() == 9 && field.mine_count() == 10); + action->set_checked(field.difficulty() == Field::Difficulty::Beginner); difficulty_menu.add_action(action); difficulty_actions.add_action(action); action = GUI::Action::create_checkable("&Intermediate", { Mod_Ctrl, Key_I }, [&](auto&) { - field.set_field_size(16, 16, 40); + field.set_field_difficulty(Field::Difficulty::Intermediate); }); - action->set_checked(field.rows() == 16 && field.columns() == 16 && field.mine_count() == 40); + action->set_checked(field.difficulty() == Field::Difficulty::Intermediate); difficulty_menu.add_action(action); difficulty_actions.add_action(action); action = GUI::Action::create_checkable("&Expert", { Mod_Ctrl, Key_E }, [&](auto&) { - field.set_field_size(16, 30, 99); + field.set_field_difficulty(Field::Difficulty::Expert); }); - action->set_checked(field.rows() == 16 && field.columns() == 30 && field.mine_count() == 99); + action->set_checked(field.difficulty() == Field::Difficulty::Expert); difficulty_menu.add_action(action); difficulty_actions.add_action(action); action = GUI::Action::create_checkable("&Madwoman", { Mod_Ctrl, Key_M }, [&](auto&) { - field.set_field_size(32, 60, 350); + field.set_field_difficulty(Field::Difficulty::Madwoman); }); - action->set_checked(field.rows() == 32 && field.columns() == 60 && field.mine_count() == 350); + action->set_checked(field.difficulty() == Field::Difficulty::Madwoman); difficulty_menu.add_action(action); difficulty_actions.add_action(action); @@ -156,6 +156,7 @@ int main(int argc, char** argv) action = GUI::Action::create_checkable("&Custom game...", { Mod_Ctrl, Key_C }, [&](auto&) { CustomGameDialog::show(window, field); }); + action->set_checked(field.difficulty() == Field::Difficulty::Custom); difficulty_menu.add_action(action); difficulty_actions.add_action(action); -- cgit v1.2.3