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

📄 landmine.c

📁 linux的图形界面程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Landmine, the game. * Written for mini-X by David I. Bell. */#include <stdio.h>#include <stdarg.h>#include <stdlib.h>#if UNIX#include <fcntl.h>#include <unistd.h>#include <time.h>#endif#include "nano-X.h"#define	MINSIZE		3		/* minimum size of board */#define MAXSIZE		30		/* maximum size of board */#define SIZE		15		/* default size of playing board */#define	MINEPERCENT	15		/* default percentage of mines */#define	SAVEFILE	"landmine.save"	/* default save file name */#define MAGIC		649351261	/* magic number in save files */#define	MAXPARAMS	1000		/* maximum different game parameters */#define FULLSIZE	(MAXSIZE + 2)	/* board size including borders */#define	BOARDGAP	10		/* millimeter gap around board */#define	RIGHTGAP	15		/* mm gap between board, right side */#define	BUTTONGAP	20		/* mm gap between buttons */#define	STATUSGAP	35		/* mm gap between buttons and status */#define	BUTTONWIDTH	80		/* width of buttons (pixels) */#define	BUTTONHEIGHT	25		/* height of buttons (pixels) */#define	RIGHTSIDE	150		/* pixels to guarantee for right side */#define	BOARDBORDER	2		/* border size around board *//* * Print the number of steps taken. * This is used twice, and is a macro to guarantee that * the two printouts match. */#define	PRINTSTEPS	printline(2, "Steps: %3d\n", steps)/* * Typedefs local to this program. */typedef	unsigned short	CELL;	/* cell value */typedef	int		POS;	/* cell position *//* * For defining bitmaps easily. */#define	X	((unsigned) 1)#define	_	((unsigned) 0)#define	BITS(a,b,c,d,e,f,g,h,i) \	(((((((((a*2+b)*2+c)*2+d)*2+e)*2+f)*2+g)*2+h)*2+i) << 7)static	GR_BITMAP	twolegs_fg[] = {	/* two legs foreground */	BITS(_,_,_,_,_,_,_,_,_),	BITS(_,_,_,X,X,X,_,_,_),	BITS(_,_,_,X,X,X,_,_,_),	BITS(_,_,_,X,X,X,_,_,_),	BITS(_,_,_,_,X,_,_,_,_),	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,X,_,X,_,X,_,X,_),	BITS(_,X,_,X,X,X,_,X,_),	BITS(_,_,_,X,_,X,_,_,_),	BITS(_,_,_,X,_,X,_,_,_),	BITS(_,_,X,X,_,X,X,_,_),	BITS(_,_,_,_,_,_,_,_,_)};static	GR_BITMAP	twolegs_bg[] = {	/* two legs background */	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,X,X,X,X,X,X,X,_),	BITS(X,X,X,X,X,X,X,X,X),	BITS(X,X,X,X,_,X,X,X,X),	BITS(X,X,X,X,X,X,X,X,X),	BITS(X,X,X,X,X,X,X,X,X),	BITS(_,X,X,X,X,X,X,X,_),	BITS(_,X,X,X,X,X,X,X,_),	BITS(_,X,X,X,X,X,X,X,_)};static	GR_BITMAP	oneleg_fg[] = {		/* one leg foreground */	BITS(_,_,_,_,_,_,_,_,_),	BITS(_,_,_,X,X,X,_,_,_),	BITS(_,_,_,X,X,X,_,_,_),	BITS(_,_,_,X,X,X,_,_,_),	BITS(_,_,_,_,X,_,_,_,_),	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,X,_,X,_,X,_,X,_),	BITS(_,_,_,X,X,X,_,X,_),	BITS(_,_,_,_,_,X,_,_,_),	BITS(_,_,_,_,_,X,_,_,_),	BITS(_,_,_,_,_,X,X,_,_),	BITS(_,_,_,_,_,_,_,_,_),};static	GR_BITMAP	oneleg_bg[] = {		/* one leg background */	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,X,X,X,X,X,X,X,_),	BITS(X,X,X,X,X,X,X,X,X),	BITS(X,X,X,X,_,X,X,X,X),	BITS(X,X,X,X,X,X,X,X,X),	BITS(_,_,X,X,X,X,X,X,X),	BITS(_,_,_,_,X,X,X,X,_),	BITS(_,_,_,_,X,X,X,X,_),	BITS(_,_,_,_,X,X,X,X,_)};static	GR_BITMAP	noleg_fg[] = {		/* no legs foreground */	BITS(_,_,_,_,_,_,_,_,_),	BITS(_,_,_,X,X,X,_,_,_),	BITS(_,_,_,X,X,X,_,_,_),	BITS(_,_,_,X,X,X,_,_,_),	BITS(_,_,_,_,X,_,_,_,_),	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,X,_,X,_,X,_,X,_),	BITS(_,_,_,X,X,X,_,_,_),	BITS(_,_,_,_,_,_,_,_,_),	BITS(_,_,_,_,_,_,_,_,_),	BITS(_,_,_,_,_,_,_,_,_),	BITS(_,_,_,_,_,_,_,_,_),};static	GR_BITMAP	noleg_bg[] = {		/* no legs background */	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,X,X,X,X,X,X,X,_),	BITS(X,X,X,X,X,X,X,X,X),	BITS(X,X,X,X,_,X,X,X,X),	BITS(X,X,X,X,X,X,X,X,X),	BITS(_,_,X,X,X,X,X,_,_),	BITS(_,_,_,_,_,_,_,_,_),	BITS(_,_,_,_,_,_,_,_,_),	BITS(_,_,_,_,_,_,_,_,_)};/* * Components of a cell. */#define F_EMPTY		' '		/* default value for empty square */#define F_REMEMBER	'*'		/* character to remember mine */#define F_WRONG		'X'		/* character to remember wrong guess */#define F_DISPLAY	0xff		/* character to be displayed here */#define F_MINE		0x100		/* TRUE if a mine is here */#define F_EDGE		0x200		/* TRUE if this is edge of the world */#define F_OLD		0x400		/* TRUE if been at this square before */#define F_REACH		0x800		/* TRUE if can reach this square */#define F_FLAGS		0xff00		/* all flags *//* * The status of the game. * This structure is read and written from the save file. */static	struct status {			/* status of games */	long	s_magic;		/* magic number */	short	s_playing;		/* TRUE if playing a game */	short	s_size;			/* current size of board */	short	s_mines;		/* current number of mines on board */	short	s_legs;			/* number of legs left */	short	s_steps;		/* number of steps taken this game */	short	s_index;		/* current game parameter index */	short	s_sizeparam[MAXPARAMS];	/* table of size parameters */	short	s_mineparam[MAXPARAMS];	/* table of mine parameters */	long	s_games0[MAXPARAMS];	/* games finished with no legs */	long	s_games1[MAXPARAMS];	/* games finished with one leg */	long	s_games2[MAXPARAMS];	/* games finished with two legs */	long	s_steps0[MAXPARAMS];	/* steps taken in no leg games */	long	s_steps1[MAXPARAMS];	/* steps taken in one leg games */	long	s_steps2[MAXPARAMS];	/* steps taken in two leg games */	CELL	s_board[FULLSIZE*FULLSIZE];	/* board layout */} st;/* * Definitions to make structure references easy. */#define magic		st.s_magic#define	playing		st.s_playing#define size		st.s_size#define mines		st.s_mines#define legs		st.s_legs#define	steps		st.s_steps#define	index		st.s_index#define	sizeparam	st.s_sizeparam#define	mineparam	st.s_mineparam#define games0		st.s_games0#define games1		st.s_games1#define games2		st.s_games2#define	steps0		st.s_steps0#define	steps1		st.s_steps1#define	steps2		st.s_steps2#define board		st.s_board#define boardpos(row, col)	(((row) * FULLSIZE) + (col))#define ismine(cell)		((cell) & F_MINE)#define isedge(cell)		((cell) & F_EDGE)#define isold(cell)		((cell) & F_OLD)#define isseen(cell)		(((cell) & F_DISPLAY) == F_REMEMBER)#define isknown(cell)		(((cell) & F_DISPLAY) != F_EMPTY)#define displaychar(cell)	((cell) & F_DISPLAY)#define badsquare(n)		(((n) <= 0) || ((n) > size))/* * Offsets for accessing adjacent cells. */static	POS	steptable[8] = {	FULLSIZE, -FULLSIZE, 1, -1, FULLSIZE-1,	FULLSIZE+1, -FULLSIZE-1, -FULLSIZE+1};static	GR_WINDOW_ID	mainwid;	/* main window id */static	GR_WINDOW_ID	boardwid;	/* board window id */static	GR_WINDOW_ID	statwid;	/* status display window id */static	GR_WINDOW_ID	quitwid;	/* window id for quit button */static	GR_WINDOW_ID	savewid;	/* window id for save button */static	GR_WINDOW_ID	newgamewid;	/* window id for new game button */static	GR_GC_ID	boardgc;	/* graphics context for board */static	GR_GC_ID	cleargc;	/* GC for clearing cell of board */static	GR_GC_ID	redgc;		/* GC for drawing red */static	GR_GC_ID	greengc;	/* GC for drawing green */static	GR_GC_ID	blackgc;	/* GC for drawing black */static	GR_GC_ID	delaygc;	/* GC for delaying */static	GR_GC_ID	statgc;		/* GC for status window */static	GR_GC_ID	buttongc;	/* GC for drawing buttons */static	GR_GC_ID	xorgc;		/* GC for inverting things */static	GR_SIZE		xp;		/* pixels for x direction per square */static	GR_SIZE		yp;		/* pixels for y direction per square */static	GR_SIZE		statwidth;	/* width of window drawing text in */static	GR_SIZE		statheight;	/* height of window drawing text in */static	GR_SIZE		charheight;	/* height of characters */static	GR_COORD	charxpos;	/* current X position for characters */static	GR_COORD	charypos;	/* current Y position for characters */static	GR_SCREEN_INFO	si;		/* window information */static	GR_FONT_INFO	fi;		/* font information */static	char	*savefile;		/* filename for saving game *//* * Procedures. */static	void	printline(GR_COORD, char *, ...);static	void	newline();static	void	delay();static	void	dokey();static	void	readevent();static	void	doexposure();static	void	dobutton();static	void	drawbomb();static	void	drawstatus();static	void	drawbutton();static	void	drawboard();static	void	drawcell();static	void	cellcenter();static	void	clearcell();static	void	newgame();static	void	moveto();static	void	setcursor();static	void	togglecell();static	void	gameover();static	void	readgame();static	void	findindex();static	POS	findcell();static	GR_BOOL	checkpath();static	GR_BOOL	writegame();intmain(argc,argv)	int argc;	char **argv;{	GR_COORD	x;	GR_COORD	y;	GR_SIZE		width;	GR_SIZE		height;	GR_COORD	rightx;		/* x coordinate for right half stuff */	GR_BOOL		setsize;	/* TRUE if size of board is set */	GR_BOOL		setmines;	/* TRUE if number of mines is set */	GR_SIZE		newsize = 0;	/* desired size of board */	GR_COUNT	newmines = 0;	/* desired number of mines */	setmines = GR_FALSE;	setsize = GR_FALSE;	argc--;	argv++;	while ((argc > 0) && (**argv == '-')) {		switch (argv[0][1]) {			case 'm':				if (argc <= 0) {					fprintf(stderr, "Missing mine count\n");					exit(1);				}				argc--;				argv++;				newmines = atoi(*argv);				setmines = GR_TRUE;				break;			case 's':				if (argc <= 0) {					fprintf(stderr, "Missing size\n");					exit(1);				}				argc--;				argv++;				newsize = atoi(*argv);				setsize = GR_TRUE;				break;			default:				fprintf(stderr, "Unknown option \"-%c\"\n",					argv[0][1]);				exit(1);		}		argc--;		argv++;	}	if (argc > 0)		savefile = *argv;	srand(time(0));	readgame(savefile);	if (setsize) {		if ((newsize < MINSIZE) || (newsize > MAXSIZE)) {			fprintf(stderr, "Illegal board size\n");			exit(1);		}		if (newsize != size) {			if (steps && playing) {				fprintf(stderr,					"Cannot change size while game is in progress\n");				exit(1);			}			playing = GR_FALSE;			size = newsize;			if (!playing)				mines = (size * size * MINEPERCENT) / 100;		}	}	if (setmines) {		if ((newmines <= 0) || ((newmines > (size * size) / 2))) {			fprintf(stderr, "Illegal number of mines\n");			exit(1);		}		if (newmines != mines) {			if (steps && playing) {				fprintf(stderr,					"Cannot change mines while game is in progress\n");				exit(1);			}			playing = GR_FALSE;			mines = newmines;		}	}	findindex();	/*	 * Parameters of the game have been verified.	 * Now open the graphics and play the game.	 */	if (GrOpen() < 0) {		fprintf(stderr, "Cannot open graphics\n");		exit(1);	}	GrGetScreenInfo(&si);	GrGetFontInfo(0, &fi);	charheight = fi.height;	/*	 * Create the main window which will contain all the others.	 */	mainwid = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0, si.cols, si.rows,		0, BLACK, WHITE);	/*	 * Create the board window which lies at the left side.	 * Make the board square, and as large as possible while still	 * leaving room to the right side for statistics and buttons.	 */	width = si.cols - RIGHTSIDE - (si.xdpcm * RIGHTGAP / 10) - BOARDBORDER * 2;	height = (((long) width) * si.ydpcm) / si.xdpcm;	if (height > si.rows /* - y * 2*/) {		height = si.rows - BOARDBORDER * 2;		width = (((long) height) * si.xdpcm) / si.ydpcm;	}	xp = width / size;	yp = height / size;	width = xp * size - 1;	height = yp * size - 1;	x = BOARDBORDER;	y = (si.rows - height) / 2;	rightx = x + width + (si.xdpcm * RIGHTGAP / 10);	boardwid = GrNewWindow(mainwid, x, y, width, height, BOARDBORDER,		BLUE, WHITE);	/*	 * Create the buttons.	 */	x = rightx;	y = (si.ydpcm * BOARDGAP / 10);	quitwid = GrNewWindow(mainwid, x, y, BUTTONWIDTH, BUTTONHEIGHT,		1, RED, WHITE);	y += (si.ydpcm * BUTTONGAP / 10);	savewid = GrNewWindow(mainwid, x, y, BUTTONWIDTH, BUTTONHEIGHT,		1, GREEN, WHITE);	y += (si.ydpcm * BUTTONGAP / 10);	newgamewid = GrNewWindow(mainwid, x, y, BUTTONWIDTH, BUTTONHEIGHT,		1, GREEN, WHITE);	/*	 * Create the statistics window.	 */	x = rightx;	y += (si.ydpcm * STATUSGAP / 10);	width = si.cols - x;	height = si.rows - y;	statwid = GrNewWindow(mainwid, x, y, width, height, 0,		0, 0);	statwidth = width;	statheight = height;	/*	 * Create the GC for drawing the board.	 */	boardgc = GrNewGC();	cleargc = GrNewGC();	delaygc = GrNewGC();	redgc = GrNewGC();	greengc = GrNewGC();	statgc = GrNewGC();	blackgc = GrNewGC();	buttongc = GrNewGC();	xorgc = GrNewGC();	GrSetGCBackground(boardgc, BLUE);	GrSetGCForeground(cleargc, BLUE);	GrSetGCForeground(redgc, RED);	GrSetGCForeground(greengc, GREEN);	GrSetGCForeground(statgc, GRAY);	GrSetGCForeground(delaygc, BLACK);	GrSetGCForeground(blackgc, BLACK);	GrSetGCMode(delaygc, GR_MODE_XOR);	GrSetGCMode(xorgc, GR_MODE_XOR);	GrSetGCUseBackground(boardgc, GR_FALSE);	GrSetGCUseBackground(buttongc, GR_FALSE);	GrSelectEvents(boardwid, GR_EVENT_MASK_EXPOSURE |		GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_KEY_DOWN);	GrSelectEvents(statwid, GR_EVENT_MASK_EXPOSURE);	GrSelectEvents(quitwid, GR_EVENT_MASK_EXPOSURE |		GR_EVENT_MASK_BUTTON_DOWN);	GrSelectEvents(newgamewid, GR_EVENT_MASK_EXPOSURE |		GR_EVENT_MASK_BUTTON_DOWN);	GrSelectEvents(savewid, GR_EVENT_MASK_EXPOSURE |		GR_EVENT_MASK_BUTTON_DOWN);	setcursor();	GrMapWindow(mainwid);	GrMapWindow(boardwid);	GrMapWindow(statwid);	GrMapWindow(quitwid);	GrMapWindow(savewid);	GrMapWindow(newgamewid);	if (!playing)		newgame();	while (GR_TRUE)		readevent();}/* * Read the next event and handle it. */static voidreadevent(){	GR_EVENT	event;	GrGetNextEvent(&event);	switch (event.type) {		case GR_EVENT_TYPE_BUTTON_DOWN:			dobutton(&event.button);			break;		case GR_EVENT_TYPE_EXPOSURE:			doexposure(&event.exposure);			break;		case GR_EVENT_TYPE_KEY_DOWN:			dokey(&event.keystroke);			break;	}}/* * Handle exposure events. */static voiddoexposure(ep)	GR_EVENT_EXPOSURE	*ep;{	if (ep->wid == boardwid) {		drawboard();		return;	}	if (ep->wid == statwid) {		drawstatus();		return;	}	if (ep->wid == quitwid) {		drawbutton(quitwid, "QUIT");		return;	}	if (ep->wid == savewid) {		drawbutton(savewid, "SAVE GAME");		return;	}	if (ep->wid == newgamewid) {		drawbutton(newgamewid, "NEW GAME");		return;	}}/* * Here when we get a button down event. */static voiddobutton(bp)	GR_EVENT_BUTTON		*bp;{	if (bp->wid == boardwid) {		moveto(findcell(bp->x, bp->y));		return;	}	if (bp->wid == quitwid) {		GrFillRect(quitwid, xorgc, 0, 0, BUTTONWIDTH, BUTTONHEIGHT);		GrFlush();		if (savefile)			writegame(savefile);		GrClose();		exit(0);	}	if (bp->wid == savewid) {		GrFillRect(savewid, xorgc, 0, 0, BUTTONWIDTH, BUTTONHEIGHT);		GrFlush();		if (savefile == NULL)			savefile = SAVEFILE;		if (writegame(savefile))			write(1, "\007", 1);		else			delay();		GrFillRect(savewid, xorgc, 0, 0, BUTTONWIDTH, BUTTONHEIGHT);	}	if (bp->wid == newgamewid) {		GrFillRect(newgamewid, xorgc, 0, 0, BUTTONWIDTH, BUTTONHEIGHT);		GrFlush();		/*if (playing)			write(1, "\007", 1);		else {*/			newgame();			delay();		/*}*/		GrFillRect(newgamewid, xorgc, 0, 0, BUTTONWIDTH, BUTTONHEIGHT);	}}/* * Here when we get a keypress in a window. */static voiddokey(kp)	GR_EVENT_KEYSTROKE	*kp;{	if ((kp->wid != boardwid) || !playing)		return;	switch (kp->ch) {		case ' ':			/* remember or forget mine */			togglecell(findcell(kp->x, kp->y));			break;	}}/* * Redraw the board. */static voiddrawboard(){	GR_COORD	row;	GR_COORD	col;	for (row = 1; row < size; row++) {		GrLine(boardwid, boardgc, 0, row * yp - 1, size * xp - 1,			row * yp - 1);		GrLine(boardwid, boardgc, row * xp - 1, 0,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -