diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-04-13 15:51:29 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-04-13 15:51:29 +0200 |
commit | 28cf9a41fea1e4b930695f351cc0e096ab0e3177 (patch) | |
tree | 264338bea72e38cd3a0c94cfc514941b683119ee /Games/Minesweeper/Field.cpp | |
parent | 198a1a6877d0183403a0394989607618a8d41832 (diff) | |
download | serenity-28cf9a41fea1e4b930695f351cc0e096ab0e3177.zip |
Minesweeper: Make it possible to win the game. :^)
Diffstat (limited to 'Games/Minesweeper/Field.cpp')
-rw-r--r-- | Games/Minesweeper/Field.cpp | 54 |
1 files changed, 49 insertions, 5 deletions
diff --git a/Games/Minesweeper/Field.cpp b/Games/Minesweeper/Field.cpp index 92714174d4..25deb47b03 100644 --- a/Games/Minesweeper/Field.cpp +++ b/Games/Minesweeper/Field.cpp @@ -24,8 +24,9 @@ public: } }; -Field::Field(GWidget* parent) +Field::Field(GButton& face_button, GWidget* parent) : GFrame(parent) + , m_face_button(face_button) { set_frame_thickness(2); set_frame_shape(FrameShape::Container); @@ -38,12 +39,30 @@ Field::Field(GWidget* parent) set_fill_with_background_color(true); set_background_color(Color::LightGray); reset(); + + m_face_button.on_click = [this] (auto&) { reset(); }; + set_face(Face::Default); } Field::~Field() { } +void Field::set_face(Face face) +{ + switch (face) { + case Face::Default: + m_face_button.set_icon(GraphicsBitmap::load_from_file("/res/icons/minesweeper/face-default.png")); + break; + case Face::Good: + m_face_button.set_icon(GraphicsBitmap::load_from_file("/res/icons/minesweeper/face-good.png")); + break; + case Face::Bad: + m_face_button.set_icon(GraphicsBitmap::load_from_file("/res/icons/minesweeper/face-bad.png")); + break; + } +} + template<typename Callback> void Field::for_each_neighbor_of(const Square& square, Callback callback) { @@ -70,12 +89,16 @@ void Field::for_each_neighbor_of(const Square& square, Callback callback) void Field::reset() { set_greedy_for_hits(false); + set_face(Face::Default); srand(time(nullptr)); m_squares.resize(rows() * columns()); HashTable<int> mines; - for (int i = 0; i < m_mine_count; ++i) - mines.set(rand() % (rows() * columns())); + while (mines.size() != m_mine_count) { + int location = rand() % (rows() * columns()); + if (!mines.contains(location)) + mines.set(location); + } int i = 0; for (int r = 0; r < rows(); ++r) { @@ -123,6 +146,8 @@ void Field::reset() } } + m_unswept_empties = rows() * columns() - m_mine_count; + update(); } @@ -141,15 +166,21 @@ void Field::on_square_clicked(Square& square) return; if (square.has_flag) return; + update(); square.is_swept = true; square.button->set_visible(false); square.label->set_visible(true); if (square.has_mine) { square.label->set_fill_with_background_color(true); game_over(); - } else if (square.number == 0) { - flood_fill(square); + } else { + --m_unswept_empties; + if (square.number == 0) + flood_fill(square); } + + if (!m_unswept_empties) + win(); } void Field::on_square_right_clicked(Square& square) @@ -161,9 +192,22 @@ void Field::on_square_right_clicked(Square& square) square.button->update(); } +void Field::win() +{ + set_greedy_for_hits(true); + set_face(Face::Good); + reveal_mines(); +} + void Field::game_over() { set_greedy_for_hits(true); + set_face(Face::Bad); + reveal_mines(); +} + +void Field::reveal_mines() +{ for (int r = 0; r < rows(); ++r) { for (int c = 0; c < columns(); ++c) { auto& square = this->square(r, c); |