diff --git a/Games/Minesweeper/Field.cpp b/Games/Minesweeper/Field.cpp index 00161aa8c1..853f1c975f 100644 --- a/Games/Minesweeper/Field.cpp +++ b/Games/Minesweeper/Field.cpp @@ -24,10 +24,16 @@ public: } }; -Field::Field(GButton& face_button, GWidget* parent) +Field::Field(GLabel& flag_label, GLabel& time_label, GButton& face_button, GWidget* parent) : GFrame(parent) , m_face_button(face_button) + , m_flag_label(flag_label) + , m_time_label(time_label) { + m_timer.on_timeout = [this] { + m_time_label.set_text(String::format("%u", ++m_seconds_elapsed)); + }; + m_timer.set_interval(1000); set_frame_thickness(2); set_frame_shape(FrameShape::Container); set_frame_shadow(FrameShadow::Sunken); @@ -88,6 +94,11 @@ void Field::for_each_neighbor_of(const Square& square, Callback callback) void Field::reset() { + m_seconds_elapsed = 0; + m_time_label.set_text("0"); + m_flags_left = m_mine_count; + m_flag_label.set_text(String::format("%u", m_flags_left)); + m_timer.start(); set_greedy_for_hits(false); set_face(Face::Default); srand(time(nullptr)); @@ -189,13 +200,25 @@ void Field::on_square_right_clicked(Square& square) { if (square.is_swept) return; - square.has_flag = !square.has_flag; + if (!square.has_flag && !m_flags_left) + return; + + if (!square.has_flag) { + --m_flags_left; + square.has_flag = true; + } else { + ++m_flags_left; + square.has_flag = false; + } + + m_flag_label.set_text(String::format("%u", m_flags_left)); square.button->set_icon(square.has_flag ? m_flag_bitmap : nullptr); square.button->update(); } void Field::win() { + m_timer.stop(); set_greedy_for_hits(true); set_face(Face::Good); reveal_mines(); @@ -203,6 +226,7 @@ void Field::win() void Field::game_over() { + m_timer.stop(); set_greedy_for_hits(true); set_face(Face::Bad); reveal_mines(); diff --git a/Games/Minesweeper/Field.h b/Games/Minesweeper/Field.h index 3626e611ab..a8d57f9caa 100644 --- a/Games/Minesweeper/Field.h +++ b/Games/Minesweeper/Field.h @@ -1,6 +1,7 @@ #pragma once #include +#include class SquareButton; class GButton; @@ -19,7 +20,7 @@ struct Square { class Field final : public GFrame { public: - Field(GButton& face_button, GWidget* parent); + Field(GLabel& flag_label, GLabel& time_label, GButton& face_button, GWidget* parent); virtual ~Field() override; int rows() const { return m_rows; } @@ -55,5 +56,10 @@ private: RetainPtr m_flag_bitmap; RetainPtr m_number_bitmap[8]; GButton& m_face_button; + GLabel& m_flag_label; + GLabel& m_time_label; + CTimer m_timer; + int m_seconds_elapsed { 0 }; + int m_flags_left { 0 }; Face m_face { Face::Default }; }; diff --git a/Games/Minesweeper/main.cpp b/Games/Minesweeper/main.cpp index 170a4a3700..6d286a07ef 100644 --- a/Games/Minesweeper/main.cpp +++ b/Games/Minesweeper/main.cpp @@ -6,6 +6,7 @@ #include #include #include +#include int main(int argc, char** argv) { @@ -24,8 +25,10 @@ int main(int argc, char** argv) container->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed); container->set_preferred_size({ 0, 36 }); container->set_layout(make(Orientation::Horizontal)); + auto* flag_label = new GLabel(container); auto* face_button = new GButton(container); - auto* field = new Field(*face_button, widget); + auto* time_label = new GLabel(container); + auto* field = new Field(*flag_label, *time_label, *face_button, widget); auto menubar = make();