Add position support
This commit is contained in:
parent
8c6bacd7e4
commit
81cf3edd95
|
@ -41,7 +41,7 @@ void mine_cell_set_configs(MineCell *cell, gboolean cell_has_mine, gboolean cell
|
||||||
cell->cleared = cell_cleared;
|
cell->cleared = cell_cleared;
|
||||||
cell->mines_around = cell_mines_around;
|
cell->mines_around = cell_mines_around;
|
||||||
cell->x = cell_x;
|
cell->x = cell_x;
|
||||||
cell->y = cell->y;
|
cell->y = cell_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
MineCell *mine_cell_new()
|
MineCell *mine_cell_new()
|
||||||
|
|
|
@ -1,20 +1,122 @@
|
||||||
#include "MineSweeper.h"
|
#include "MineSweeper.h"
|
||||||
#include "MineCell.h"
|
#include "MineCell.h"
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// The status of the minesweeper game
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Running,
|
||||||
|
Winned,
|
||||||
|
Ended,
|
||||||
|
Paused
|
||||||
|
} GameStatus;
|
||||||
|
|
||||||
struct _MineSweeper
|
struct _MineSweeper
|
||||||
{
|
{
|
||||||
GtkApplicationWindow parent_instance;
|
GtkApplicationWindow parent_instance;
|
||||||
|
|
||||||
|
// Child widgets
|
||||||
GtkWidget *main_box, *btn_box;
|
GtkWidget *main_box, *btn_box;
|
||||||
GtkWidget *mine_grid;
|
GtkWidget *mine_grid;
|
||||||
GtkWidget *time_label;
|
GtkWidget *time_label;
|
||||||
MineCell *cell[49];
|
MineCell *cell[49];
|
||||||
GtkWidget *btn_start, *btn_show, *btn_exit;
|
GtkWidget *btn_start, *btn_show, *btn_exit;
|
||||||
|
|
||||||
|
// Tags for game status
|
||||||
int time_count;
|
int time_count;
|
||||||
gboolean started;
|
gboolean started;
|
||||||
|
int mines_clear, mine_count;
|
||||||
|
GameStatus game_status;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE(MineSweeper, mine_sweeper, GTK_TYPE_APPLICATION_WINDOW)
|
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)
|
static void mine_sweeper_cells_init(MineSweeper *self, int width, int height)
|
||||||
{
|
{
|
||||||
// The mine sweeper will be 7x7
|
// 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++)
|
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]);
|
GtkWidget *widget = GTK_WIDGET((self->cell)[i * width + j]);
|
||||||
gtk_grid_attach(GTK_GRID(self->mine_grid), widget, j, i, 1, 1);
|
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)
|
static gboolean time_func(gpointer data)
|
||||||
{
|
{
|
||||||
MineSweeper *mine_app = MINE_SWEEPER(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)
|
static void btnstart_clicked(GtkButton *btn, MineSweeper *self)
|
||||||
{
|
{
|
||||||
|
// Reset mine status
|
||||||
|
mine_sweeper_reset(self, 9);
|
||||||
|
|
||||||
// Start game
|
// Start game
|
||||||
|
gtk_widget_set_sensitive(self->mine_grid, TRUE);
|
||||||
self->time_count = 0;
|
self->time_count = 0;
|
||||||
self->started = TRUE;
|
self->started = TRUE;
|
||||||
g_timeout_add(1000, time_func, self);
|
g_timeout_add(1000, time_func, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void btnshow_clicked(GtkButton *btn, MineSweeper *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static void mine_sweeper_init(MineSweeper *self)
|
static void mine_sweeper_init(MineSweeper *self)
|
||||||
{
|
{
|
||||||
// Initalize window
|
// 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_show = gtk_button_new_with_label("Show All");
|
||||||
self->btn_exit = gtk_button_new_with_label("Exit");
|
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_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
|
// Create mine cells
|
||||||
mine_sweeper_cells_init(self, 7, 7);
|
mine_sweeper_cells_init(self, 7, 7);
|
||||||
|
|
Loading…
Reference in New Issue