From 81cf3edd9598d6fe7b3f8e1732d0d66db0852367 Mon Sep 17 00:00:00 2001 From: daleclack Date: Wed, 21 Feb 2024 17:30:40 +0800 Subject: [PATCH] Add position support --- Gtk4/gtk158_minesweeper4/src/MineCell.cpp | 2 +- Gtk4/gtk158_minesweeper4/src/MineSweeper.cpp | 123 +++++++++++++++++-- 2 files changed, 117 insertions(+), 8 deletions(-) diff --git a/Gtk4/gtk158_minesweeper4/src/MineCell.cpp b/Gtk4/gtk158_minesweeper4/src/MineCell.cpp index 627fa31..42dead9 100644 --- a/Gtk4/gtk158_minesweeper4/src/MineCell.cpp +++ b/Gtk4/gtk158_minesweeper4/src/MineCell.cpp @@ -41,7 +41,7 @@ void mine_cell_set_configs(MineCell *cell, gboolean cell_has_mine, gboolean cell cell->cleared = cell_cleared; cell->mines_around = cell_mines_around; cell->x = cell_x; - cell->y = cell->y; + cell->y = cell_y; } MineCell *mine_cell_new() diff --git a/Gtk4/gtk158_minesweeper4/src/MineSweeper.cpp b/Gtk4/gtk158_minesweeper4/src/MineSweeper.cpp index 21a9cb1..4130b4a 100644 --- a/Gtk4/gtk158_minesweeper4/src/MineSweeper.cpp +++ b/Gtk4/gtk158_minesweeper4/src/MineSweeper.cpp @@ -1,20 +1,122 @@ #include "MineSweeper.h" #include "MineCell.h" +#include +#include + +// The status of the minesweeper game +typedef enum +{ + Running, + Winned, + Ended, + Paused +} GameStatus; struct _MineSweeper { GtkApplicationWindow parent_instance; + + // Child widgets GtkWidget *main_box, *btn_box; GtkWidget *mine_grid; GtkWidget *time_label; MineCell *cell[49]; GtkWidget *btn_start, *btn_show, *btn_exit; + + // Tags for game status int time_count; gboolean started; + int mines_clear, mine_count; + GameStatus game_status; }; G_DEFINE_TYPE(MineSweeper, mine_sweeper, GTK_TYPE_APPLICATION_WINDOW) +static void mine_sweeper_lost(MineSweeper *self, int explode_index) +{ + for (int i = 0; i < 49; i++) + { + } + gtk_widget_set_sensitive(self->mine_grid, FALSE); +} + +static void find_mines(int i, int j, MineCell **cell) +{ + gboolean has_mine, cleared; + int mines_around, x, y; + int index1, index2; + int mines = 0; + // The Search cell should not over the grids + for (index1 = MAX(0, i - 1); index1 < MIN(i + 1, 6) + 1; index1++) + { + for (index2 = MAX(0, j - 1); index2 < MIN(j + 1, 6) + 1; index2++) + { + mine_cell_get_configs(cell[index1 * 7 + index2], has_mine, cleared, mines_around, x, y); + if (has_mine) + { + // cell[i * 7 + j].mines_around++; + mines++; + } + } + } + + // Update config of mine cell + mine_cell_get_configs(cell[i * 7 + j], has_mine, cleared, mines_around, x, y); + mine_cell_set_configs(cell[i * 7 + j], has_mine, cleared, mines, x, y); +} + +static void mine_sweeper_reset(MineSweeper *self, int mines) +{ + gboolean has_mine, cleared; + int mines_around, x, y; + // Reset mines status + self->mines_clear = 0; + self->mine_count = 0; + + // Reset cell icons + MineCell **cells = self->cell; + for (int i = 0; i < 7; i++) + { + for (int j = 0; j < 7; j++) + { + gtk_button_set_icon_name(GTK_BUTTON(cells[i * 7 + j]), ""); + mine_cell_set_configs(cells[i * 7 + j], FALSE, FALSE, 0, j, i); + } + } + + // Add mines + while (self->mine_count < mines) + { + int i = g_random_int_range(0, 49); + mine_cell_get_configs(cells[i], has_mine, cleared, mines_around, x, y); + if (!has_mine) + { + mine_cell_set_configs(cells[i], TRUE, FALSE, 0, x, y); + self->mine_count++; + } + } + + // Calculate mines around a cell + // Calculate the mines around a cell + for (int i = 0; i < 7; i++) + { + for (int j = 0; j < 7; j++) + { + find_mines(i, j, cells); + } + } +} + +static void mine_cell_clicked(MineCell *cell, MineSweeper *self) +{ + gboolean has_mine, cleared; + int mines_around, x, y; + + // Take all properties + mine_cell_get_configs(cell, has_mine, cleared, mines_around, x, y); + g_print("(%d,%d) %d %d %d\n", x, y, has_mine, cleared, mines_around); +} + static void mine_sweeper_cells_init(MineSweeper *self, int width, int height) { // The mine sweeper will be 7x7 @@ -22,7 +124,9 @@ static void mine_sweeper_cells_init(MineSweeper *self, int width, int height) { for (int j = 0; j < height; j++) { - (self->cell)[i * width + j] = mine_cell_new(); + MineCell *cell = mine_cell_new(); + (self->cell)[i * width + j] = cell; + g_signal_connect(cell, "clicked", G_CALLBACK(mine_cell_clicked), self); } } @@ -33,16 +137,11 @@ static void mine_sweeper_cells_init(MineSweeper *self, int width, int height) { GtkWidget *widget = GTK_WIDGET((self->cell)[i * width + j]); gtk_grid_attach(GTK_GRID(self->mine_grid), widget, j, i, 1, 1); + mine_cell_set_configs((self->cell)[i * width + j], FALSE, FALSE, 0, j, i); } } } -static void mine_sweeper_reset(MineSweeper *self) -{ - // Reset mines status - -} - static gboolean time_func(gpointer data) { MineSweeper *mine_app = MINE_SWEEPER(data); @@ -55,12 +154,20 @@ static gboolean time_func(gpointer data) static void btnstart_clicked(GtkButton *btn, MineSweeper *self) { + // Reset mine status + mine_sweeper_reset(self, 9); + // Start game + gtk_widget_set_sensitive(self->mine_grid, TRUE); self->time_count = 0; self->started = TRUE; g_timeout_add(1000, time_func, self); } +static void btnshow_clicked(GtkButton *btn, MineSweeper *self) +{ +} + static void mine_sweeper_init(MineSweeper *self) { // Initalize window @@ -75,6 +182,8 @@ static void mine_sweeper_init(MineSweeper *self) self->btn_show = gtk_button_new_with_label("Show All"); self->btn_exit = gtk_button_new_with_label("Exit"); g_signal_connect(self->btn_start, "clicked", G_CALLBACK(btnstart_clicked), self); + g_signal_connect(self->btn_show, "clicked", G_CALLBACK(btnshow_clicked), self); + g_signal_connect_swapped(self->btn_exit, "clicked", G_CALLBACK(gtk_window_close), self); // Create mine cells mine_sweeper_cells_init(self, 7, 7);