diff options
| author | fschildt <florian.schildt@protonmail.com> | 2025-10-18 11:33:30 +0200 |
|---|---|---|
| committer | fschildt <florian.schildt@protonmail.com> | 2025-10-18 11:38:45 +0200 |
| commit | 935f1971bee684c6c9baded2564a550351cc5582 (patch) | |
| tree | e4650d9b39b108be52638f6b45681b42dfc72b15 | |
| parent | 7935895480b74fb9fe02e5f26a82265a72604d77 (diff) | |
| -rw-r--r-- | src/games/minesweeper/Minesweeper.cpp | 126 | ||||
| -rw-r--r-- | src/games/minesweeper/Minesweeper.hpp | 21 |
2 files changed, 91 insertions, 56 deletions
diff --git a/src/games/minesweeper/Minesweeper.cpp b/src/games/minesweeper/Minesweeper.cpp index a091491..5a37a04 100644 --- a/src/games/minesweeper/Minesweeper.cpp +++ b/src/games/minesweeper/Minesweeper.cpp @@ -12,7 +12,6 @@ // - Show current time spent // - Show current flags/mines left // - Permit uncovering of flagged cell -// - Game Over: Winning Condition (maybe: total_cells - uncovered_cells == mine_count) // - Game Over: Show Highscore for selected difficulty @@ -31,62 +30,60 @@ static constexpr Color s_mine_count_colors[8] = { Minesweeper::Minesweeper() : m_font{s_dejavu_sans_filepath, 22} { + float cell_size = 1.2f * std::min(m_world_height / s_max_grid_height, m_world_width / s_max_grid_width); + float cell_size_without_border = 0.8f * cell_size; + + m_cell_outer_size = {cell_size, cell_size}; + m_cell_inner_size = {cell_size_without_border, cell_size_without_border}; } void Minesweeper::Reset(Difficulty difficulty) { - int32_t mine_count; + m_cells_uncovered = 0; if (difficulty == beginner) { m_grid_width = 8; m_grid_height = 8; - mine_count = 10; + m_mine_count = 10; } else if(difficulty == intermediate) { m_grid_width = 16; m_grid_height = 16; - mine_count = 40; + m_mine_count = 40; } else { m_grid_width = 30; m_grid_height = 16; - mine_count = 99; + m_mine_count = 99; } + assert(m_grid_width <= s_max_grid_width); + assert(m_grid_height <= s_max_grid_height); - float cell_size = 1.2f * std::min(m_world_height / max_map_height, m_world_width / max_map_width); - float cell_size_without_border = 0.8f * cell_size; - - V2F32 grid_size = { - (float)m_grid_width * cell_size, - (float)m_grid_height * cell_size - }; + float grid_draw_width = (float)m_grid_width * m_cell_outer_size.x; + float grid_draw_height = (float)m_grid_height * m_cell_outer_size.y; m_grid_pos = { - (m_world_width - grid_size.x) / 2, - (m_world_height - grid_size.y) / 2, + (m_world_width - grid_draw_width) / 2, + (m_world_height - grid_draw_height) / 2, }; - m_cell_outer_size = {cell_size, cell_size}; - m_cell_inner_size = {cell_size_without_border, cell_size_without_border}; - memset(m_is_covered_bitmap, 0xff, sizeof(m_is_covered_bitmap)); memset(m_is_flagged_bitmap, 0 , sizeof(m_is_flagged_bitmap)); - InitIsMineBitmap(mine_count); + InitIsMineBitmap(); InitAdjacentMineCounters(); } void -Minesweeper::InitIsMineBitmap(int32_t mine_count) +Minesweeper::InitIsMineBitmap() { - assert(mine_count < m_grid_width * m_grid_height); - + assert(m_mine_count < m_grid_width * m_grid_height); memset(m_is_mine_bitmap, 0 , sizeof(m_is_mine_bitmap)); std::mt19937 rng((std::random_device()())); std::uniform_int_distribution<int32_t> dist(0, m_grid_width * m_grid_height - 1); - + int32_t mine_count = m_mine_count; while (mine_count) { int32_t random_pos = dist(rng); int32_t y = random_pos / m_grid_width; @@ -127,6 +124,13 @@ Minesweeper::InitAdjacentMineCounters() } bool +Minesweeper::IsWon() +{ + bool is_won = m_grid_width*m_grid_height - m_cells_uncovered == m_mine_count; + return is_won; +} + +bool Minesweeper::Update(std::vector<SDL_Event>& events) { g_renderer.SetCameraSize(4.0f, 3.0f); @@ -159,7 +163,7 @@ Minesweeper::Update(std::vector<SDL_Event>& events) } else if (m_game_status == game_over) { DrawBoard(); - DrawDefaultGameOverMenu(); + DrawGameOverMenu(); } return true; @@ -211,7 +215,9 @@ Minesweeper::ProcessEventDuringResume(SDL_Event &event) break; } - if (event.button.button == 1) { + uint8_t left_click = 1; + uint8_t right_click = 3; + if (event.button.button == left_click) { if (IsCovered(x, y)) { if (IsMine(x, y)) { m_is_covered_bitmap[y] &= ~(1 << x); @@ -220,10 +226,13 @@ Minesweeper::ProcessEventDuringResume(SDL_Event &event) } else { Uncover(x, y); + if (IsWon()) { + m_game_status = game_over; + } } } } - else if (event.button.button == 3) { + else if (event.button.button == right_click) { if (IsCovered(x, y)) { ToggleFlag(x ,y); } @@ -245,6 +254,8 @@ Minesweeper::Uncover(int32_t x, int32_t y) if (!IsCovered(x, y)) return; m_is_covered_bitmap[y] &= ~(1 << x); + m_cells_uncovered += 1; + if (IsFlagged(x, y)) { ToggleFlag(x, y); } @@ -318,29 +329,6 @@ Minesweeper::ScreenPosToViewPos(V2F32 screen_pos) } void -Minesweeper::DrawStartMenu() -{ - ImGui::Begin("MinesweeperStart"); - if (ImGui::RadioButton("beginner", m_difficulty == beginner ? true : false)) { - m_difficulty = beginner; - } - if (ImGui::RadioButton("intermediate", m_difficulty == intermediate ? true : false)) { - m_difficulty = intermediate; - } - if (ImGui::RadioButton("expert", m_difficulty == expert ? true : false)) { - m_difficulty = expert; - } - if (ImGui::Button("Start")) { - Reset(m_difficulty); - m_game_status = game_resuming; - } - if (ImGui::Button("Exit")) { - m_game_status = game_exit; - } - ImGui::End(); -} - -void Minesweeper::DrawBoard() { Color covered_cell_color {0.6f, 0.6f, 0.6f}; @@ -424,3 +412,45 @@ Minesweeper::DrawBoard() } } +void +Minesweeper::DrawStartMenu() +{ + ImGui::Begin("MinesweeperStart"); + if (ImGui::RadioButton("beginner", m_difficulty == beginner ? true : false)) { + m_difficulty = beginner; + } + if (ImGui::RadioButton("intermediate", m_difficulty == intermediate ? true : false)) { + m_difficulty = intermediate; + } + if (ImGui::RadioButton("expert", m_difficulty == expert ? true : false)) { + m_difficulty = expert; + } + if (ImGui::Button("Start")) { + Reset(m_difficulty); + m_game_status = game_resuming; + } + if (ImGui::Button("Exit")) { + m_game_status = game_exit; + } + ImGui::End(); +} + +void +Minesweeper::DrawGameOverMenu() +{ + ImGui::Begin("MinesweeperGameOverMenu", nullptr, s_imgui_window_flags_menu); + if (IsWon()) { + ImGui::Text("You won!"); + } + else { + ImGui::Text("You Lost."); + } + if (ImGui::Button("Play Again")) { + m_game_status = game_starting; + } + if (ImGui::Button("Exit")) { + m_game_status = game_exit; + } + ImGui::End(); +} + diff --git a/src/games/minesweeper/Minesweeper.hpp b/src/games/minesweeper/Minesweeper.hpp index fbdcb30..1db77ff 100644 --- a/src/games/minesweeper/Minesweeper.hpp +++ b/src/games/minesweeper/Minesweeper.hpp @@ -25,8 +25,9 @@ private: void ProcessEventDuringResume(SDL_Event& event); void Reset(Difficulty Difficulty); - void InitIsMineBitmap(int32_t mine_count); + void InitIsMineBitmap(); void InitAdjacentMineCounters(); + bool IsWon(); void UncoverMines(); void Uncover(int32_t x, int32_t y); @@ -43,28 +44,32 @@ private: private: void DrawBoard(); void DrawStartMenu(); + void DrawGameOverMenu(); private: - static constexpr int32_t max_map_height = 32; - static constexpr int32_t max_map_width = 32; + static constexpr int32_t s_max_grid_height = 32; + static constexpr int32_t s_max_grid_width = 32; private: Difficulty m_difficulty = beginner; + int32_t m_cells_uncovered; + int32_t m_mine_count; float m_world_width = 4.0f; float m_world_height = 3.0f; int32_t m_grid_width; - int32_t m_grid_height; V2F32 m_grid_pos; + int32_t m_grid_height; + V2F32 m_grid_pos; V2F32 m_cell_outer_size; V2F32 m_cell_inner_size; - uint32_t m_is_covered_bitmap[max_map_height] {}; - uint32_t m_is_flagged_bitmap[max_map_height] {}; - uint32_t m_is_mine_bitmap[max_map_height] {}; - int32_t m_adjacent_mine_counts[max_map_width * max_map_height] {}; + uint32_t m_is_covered_bitmap[s_max_grid_height] {}; + uint32_t m_is_flagged_bitmap[s_max_grid_height] {}; + uint32_t m_is_mine_bitmap[s_max_grid_height] {}; + int32_t m_adjacent_mine_counts[s_max_grid_width * s_max_grid_height] {}; Font m_font; }; |
