📄 mines.c
字号:
#include <gtk/gtk.h>/** * ?????? */struct block{ gint count; /* ??????? */ gboolean mine; /* ?????? */ gboolean marked; /* ?????? */ gboolean opened; /* ?????? */ GtkWidget *button;};/** * ???? */static struct block *map; /* ????? */static gint width=10; /* ????? */static gint height=10; /* ????? */static gint mines=20; /* ???? */static GtkWidget *mine_label; /* ??????? */static GtkWidget *time_label; /* ?????? */static gint button_size=16; /* button ?? */static gint opened_count; /* ???????? */static gint marked_count; /* ???????? */static gboolean game_over; /* ??????? */static GtkWidget *window; /* ??? */static gint game_time; /* ???????? *//** * g_timeout_add() ? callback function */gboolean tick(gpointer data){ gchar buf[8]; if(game_over==TRUE) /* ??????? FALSE ???? */ return FALSE; game_time++; /* ??????????? */ g_snprintf(buf, 8, "%d", game_time); gtk_label_set_text(GTK_LABEL(time_label), buf); return TRUE; /* ?? TRUE ???? */}/** * ?????? */void game_reset(){ gint size=width*height; gint i=0; gchar buf[4]; /* ??????? */ opened_count=0; marked_count=0; game_over=FALSE; game_time=0; /* ??????? */ g_snprintf(buf, 4, "%d", MAX(0, mines-marked_count)); gtk_label_set_text(GTK_LABEL(mine_label), buf); /* ??????? */ while(i<mines){ gint index; gint row, col; index=g_random_int_range(0, size); if(map[index].mine==TRUE) /* ???? */ continue; map[index].mine=TRUE; row=index/width; col=index%width; /* ????? count ?? */ if(row>0){/* ?? */ if(col>0) map[index-width-1].count++;/* ?? */ map[index-width].count++;/* ?? */ if(col<width-1) map[index-width+1].count++; }/* ? */ if(col>0) map[index-1].count++;/* ? */ if(col<width-1) map[index+1].count++; if(row<height-1){/* ?? */ if(col>0) map[index+width-1].count++;/* ?? */ map[index+width].count++;/* ?? */ if(col<width-1) map[index+width+1].count++; } i++; } /* ???? */ g_timeout_add(1000, (GSourceFunc)tick, NULL);}/** * ?????? */void gameover(gboolean won){ GtkWidget *dialog; gchar msg[100]; if(game_over==TRUE) return; game_over=TRUE; if(won==TRUE){ /* ????????? */ g_snprintf(msg, 100, "You won! You have cleared" " the game in %3d seconds.", game_time); }else{ /* ????????? */ g_snprintf(msg, 100, "Bad luck. Game over."); } /* ? GtkMessageDialog ???? */ dialog=gtk_message_dialog_new(GTK_WINDOW(window), 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, msg); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog);}/** * ???? (x,y) */void open_block(gint x, gint y){ gint index; GtkWidget *button; index=x+y*width; if(map[index].marked==TRUE) /* ?????????????????? */ return; button=map[index].button; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); /* ?? button ????? */ if(map[index].opened==TRUE) /* ????????????? */ return; map[index].opened=TRUE; /* ??????? */ if(map[index].mine==TRUE){ /* ????? */ gtk_button_set_label(GTK_BUTTON(button), "*"); gameover(FALSE); /* ???????? */ return; } if(map[index].count>0){ /* ?????? */ gchar buf[2]; g_snprintf(buf, 2, "%d", map[index].count); gtk_button_set_label(GTK_BUTTON(button), buf); } opened_count++; /* ??????????? */ if(opened_count+mines==width*height){ gameover(TRUE); /* ????????????? */ return; } if(map[index].count==0){ /* ??????? */ /* ?????? */ if(y>0){ if(x>0) open_block(x-1, y-1); open_block(x, y-1); if(x<width-1) open_block(x+1, y-1); } if(x>0) open_block(x-1, y); if(x<width-1) open_block(x+1, y); if(y<height-1){ if(x>0) open_block(x-1, y+1); open_block(x, y+1); if(x<width-1) open_block(x+1, y+1); } }}/** * ??????? callback function */gboolean on_mouse_click(GtkWidget *widget, GdkEventButton *event, gpointer data){ gint index; gint row, col; gchar buf[4]; if(game_over==TRUE) return TRUE; /* ????? */ index=(gint)data; switch(event->button){ case 1: /* ???? */ /* ? index ??????????? */ row=index/width; col=index%width; /* ???? */ open_block(col, row); break; case 2: /* ???? */ break; case 3: /* ???? */ /* ?????????? */ if(map[index].opened==TRUE) break; /* ????????, ??????? */ if(map[index].marked!=TRUE){ map[index].marked=TRUE; gtk_button_set_label( GTK_BUTTON(widget), "@"); marked_count++; }else{ map[index].marked=FALSE; gtk_button_set_label( GTK_BUTTON(widget), ""); marked_count--; } /* ??????? */ g_snprintf(buf, 4, "%d", MAX(0, mines-marked_count)); gtk_label_set_text(GTK_LABEL(mine_label), buf); } return TRUE;}/** * ???? */int main(int argc, char **argv){ GtkWidget *vbox; GtkWidget *hbox; GtkWidget *label; gint i, j, index; /* initialize GTK library */ gtk_init(&argc, &argv); /* ?????? map ???? */ map=(struct block *)g_malloc0(sizeof(struct block)* width*height); /* build the user interface */ window=gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(G_OBJECT(window), "delete_event", gtk_main_quit, NULL); vbox=gtk_vbox_new(FALSE, 0); /* ?? label ???? hbox */ hbox=gtk_hbox_new(FALSE, 0); label=gtk_label_new("Mines:"); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 4); mine_label=gtk_label_new("0"); gtk_box_pack_start(GTK_BOX(hbox), mine_label, FALSE, FALSE, 2); label=gtk_label_new("Time:"); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 4); time_label=gtk_label_new("0"); gtk_box_pack_start(GTK_BOX(hbox), time_label, FALSE, FALSE, 2); gtk_widget_show_all(hbox); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); /* width x height ? button ??? */ for(i=0, index=0; i<height; i++){ gint j; hbox=gtk_hbox_new(FALSE, 0); for(j=0; j<width; j++){ GtkWidget *button; button=gtk_toggle_button_new(); gtk_widget_set_usize(button, button_size, button_size); g_object_set(G_OBJECT(button), "can-focus", FALSE, NULL); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); gtk_widget_show(button); g_signal_connect(G_OBJECT(button), "button-press-event", G_CALLBACK(on_mouse_click), (gpointer)index); map[index].button=button; index++; } gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); } gtk_container_add(GTK_CONTAINER(window), vbox); gtk_widget_show(vbox); gtk_widget_show(window); game_reset(); gtk_main(); g_free(map); /* ?????????? */ return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -