aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/games/minesweeper/Minesweeper.cpp126
-rw-r--r--src/games/minesweeper/Minesweeper.hpp21
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;
};