⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mines.c

📁 linux gtk+基础编程源代码
💻 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 + -