Skip to content

Commit

Permalink
feat: support for placing flags by right-click
Browse files Browse the repository at this point in the history
  • Loading branch information
ChiahongHong committed Feb 19, 2022
1 parent 0d04940 commit d2d7b3d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 30 deletions.
72 changes: 45 additions & 27 deletions Minesweeper/cMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@
cMain::cMain() : wxFrame(nullptr, wxID_ANY, "Minesweeper", wxDefaultPosition, wxSize(800, 600))
{
btn = new wxButton * [width * height];
mines = new bool [width * height];
wxGridSizer *grid = new wxGridSizer(width, height, 0, 0);

n = new int[width * height];

wxFont font(22, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false);

for (int x = 0; x < width; x++) {
Expand All @@ -30,8 +29,10 @@ cMain::cMain() : wxFrame(nullptr, wxID_ANY, "Minesweeper", wxDefaultPosition, wx
btn[y * width + x]->SetFont(font);
grid->Add(btn[y * width + x], 1, wxEXPAND | wxALL);

btn[y * width + x]->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &cMain::onButtonClicked, this);
n[y * width + x] = 0;
btn[y * width + x]->Bind(wxEVT_BUTTON, &cMain::onButtonClicked, this);
btn[y * width + x]->Bind(wxEVT_RIGHT_DOWN, &cMain::onButtonRightClicked, this);
btn[y * width + x]->Bind(wxEVT_RIGHT_DCLICK, &cMain::onButtonRightClicked, this);
mines[y * width + x] = false;
}
}
this->Center();
Expand All @@ -49,42 +50,59 @@ void cMain::onButtonClicked(wxCommandEvent& event)
int x = (event.GetId() - 10000) % width;
int y = (event.GetId() - 10000) / width;

if (firstClick) {
generateMines(x, y);
firstClick = false;
}
if (btn[y * width + x]->GetLabel() != wxT("\u25B2")) {
if (firstClick) {
generateMines(x, y);
firstClick = false;
}

btn[y * width + x]->Enable(false);
btn[y * width + x]->Enable(false);

if (n[y * width + x] == -1) {
showMines();
wxMessageBox(wxT("Game Over!"), wxT("Minesweeper"));
resetGame();
} else {
expand(x, y);

if (isWin()) {
wxMessageBox(wxT("You Win!"), wxT("Minesweeper"));
if (mines[y * width + x]) {
showMines();
wxMessageBox(wxT("Game Over!"), wxT("Minesweeper"));
resetGame();
} else {
expand(x, y);

if (isWin()) {
wxMessageBox(wxT("You Win!"), wxT("Minesweeper"));
resetGame();
}
}
}

event.Skip();
}

void cMain::onButtonRightClicked(wxMouseEvent& event)
{
int x = (event.GetId() - 10000) % width;
int y = (event.GetId() - 10000) / width;

if (btn[y * width + x]->GetLabel() == wxT("\u25B2")) {
btn[y * width + x]->SetLabel("");
} else {
btn[y * width + x]->SetLabel(wxT("\u25B2"));
}

event.Skip();
}

void cMain::expand(int x, int y) {
int mine_count = 0;
for (int i = -1; i < 2; i++) {
for (int j = -1; j < 2; j++) {
if (x + i >= 0 && x + i < width && y + j >= 0 && y + j < height) {
if (n[(y + j) * width + (x + i)] == -1) {
if (mines[(y + j) * width + (x + i)]) {
mine_count++;
}
}
}
}

btn[y * width + x]->Enable(false);
btn[y * width + x]->SetLabel("");

if (mine_count) {
btn[y * width + x]->SetLabel(std::to_string(mine_count));
Expand All @@ -103,23 +121,23 @@ void cMain::expand(int x, int y) {
}

void cMain::generateMines(int &x, int &y) {
int mines = this->mines;
int nums = this->nums;
srand(time(0));
while (mines) {
while (nums) {
int rx = rand() % width;
int ry = rand() % height;

if (n[ry * width + rx] == 0 && rx != x && ry != y) {
n[ry * width + rx] = -1;
mines--;
if (!mines[ry * width + rx] && rx != x && ry != y) {
mines[ry * width + rx] = true;
nums--;
}
}
}

void cMain::showMines() {
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (n[y * width + x] == -1) {
if (mines[y * width + x]) {
btn[y * width + x]->SetLabel(wxT("X"));
btn[y * width + x]->Enable(false);
}
Expand All @@ -131,7 +149,7 @@ void cMain::resetGame() {
firstClick = true;
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
n[y * width + x] = 0;
mines[y * width + x] = false;
btn[y * width + x]->SetLabel("");
btn[y * width + x]->Enable(true);
}
Expand All @@ -141,7 +159,7 @@ void cMain::resetGame() {
bool cMain::isWin() {
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (btn[y * width + x]->IsEnabled() && n[y * width + x] == 0) {
if (btn[y * width + x]->IsEnabled() && !mines[y * width + x]) {
return false;
}
}
Expand Down
7 changes: 4 additions & 3 deletions Minesweeper/cMain.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,17 @@ class cMain : public wxFrame
~cMain();
void generateMines(int &x, int &y);
void onButtonClicked(wxCommandEvent &event);
void onButtonRightClicked(wxMouseEvent &event);
void expand(int x, int y);
void showMines();
void resetGame();
bool isWin();

private:
const int mines = 15;
bool *mines = nullptr;
bool firstClick = true;
const int nums = 15;
const int width = 10;
const int height = 10;
wxButton **btn;
int *n = nullptr;
bool firstClick = true;
};

0 comments on commit d2d7b3d

Please sign in to comment.