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

📄 landmine.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Landmine, the game.
 * Written for mini-X by David I. Bell.
 */

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#if UNIX | DOS_DJGPP
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#endif
#define MWINCLUDECOLORS
#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 */

#ifdef __ECOS
/* 240x320 screen values*/
#define	BOARDGAP	2		/* millimeter gap around board */
#define	RIGHTGAP	2		/* mm gap between board, right side */
#define	BUTTONGAP	5		/* mm gap between buttons */
#define	STATUSGAP	10		/* mm gap between buttons and status */

#define	BUTTONWIDTH	80		/* width of buttons (pixels) */
#define	BUTTONHEIGHT	25		/* height of buttons (pixels) */
#define	RIGHTSIDE	90		/* pixels to guarantee for right side */
#define	BOARDBORDER	2		/* border size around board */
#else
#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 */
#endif

/*
 * 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	GR_SIZE		COLS, ROWS;

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	handleevent();
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	movetopos();
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();

int
main(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 = 10;	/* desired size of board */
	GR_COUNT	newmines = 25;	/* desired number of mines */
	GR_WM_PROPERTIES props;

	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);
	}

	GrReqShmCmds(655360); /* Test by Morten Rolland for shm support */

	GrGetScreenInfo(&si);
	GrGetFontInfo(0, &fi);
	charheight = fi.height;

	/*
	 * Create the main window which will contain all the others.
	 */
#if 0
COLS = si.cols - 40;
#else
COLS = si.cols;
#endif
ROWS = si.rows - 80;
	mainwid = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0, COLS, ROWS,
		0, BLACK, WHITE);
 
	/* set title */
	props.flags = GR_WM_FLAGS_TITLE | GR_WM_FLAGS_PROPS;
	props.props = GR_WM_PROPS_APPFRAME | GR_WM_PROPS_CAPTION;
	props.title = "Land Mine";
	GrSetWMProperties(mainwid, &props);

	/*
	 * 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 = COLS - RIGHTSIDE - (si.xdpcm * RIGHTGAP / 10) - BOARDBORDER * 2;
	height = (((long) width) * si.ydpcm) / si.xdpcm;

⌨️ 快捷键说明

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