C语言–扫雷小游戏(含递归展开)

1. 游戏设计

     game.h-----函数的声明

     game.c-----函数的定义

     test.c--------函数的测试

2. 游戏设计思路

     创建数组

     数组初始化

     打印棋盘

     布置雷

     排查雷

     运行结果

3. 完整代码


扫雷具体解析在代码的注释中,如有错误,请大家指正,谢谢~

创建数组

#define ROW 9         //行   用define定义扫雷的行 方便以后可以修改
#define COL 9         //列   用define定义扫雷的列 方便以后可以修改

#define ROWS ROW+2      //行   +2是为了用于排查雷,方便排查处在周围一圈的坐标
#define COLS COL+2      //列   +2是为了用于排查雷,方便排查处在周围一圈的坐标
char mine[ROWS][COLS] = { 0 };         //mine数组为布置雷的数组(这个数组我们不能让玩家看见,除非玩家已经输了)
char show[ROWS][COLS] = { 0 };         //show数组为布置雷的数组(这个数组是给玩家看的,需要玩家一个一个去排查)

数组初始化

InitBoard(mine, ROWS, COLS, '0');       //初始化 布置雷的棋盘    游戏设置雷为'1',非雷为'0',初始化先将mine数组初始为全'0'。
InitBoard(show, ROWS, COLS, '*');       //初始化 排查雷的棋盘    设置未排查的坐标为'*',初始化先将show数组初始化为全'*'。
void InitBoard(char board[ROWS][COLS], int rows, int cols, char ret)   //初始化棋盘
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = ret;
		}
	}
}

打印棋盘

/*DisplayBoard(mine, ROW, COL); */      //打印 布置雷的棋盘   (我们无需打印mine数组,这里只是为了检查棋盘初始化是否正确)
DisplayBoard(show, ROW, COL);          //打印  排查雷的棋盘    (游戏开始,需打印show数组,这个数组是让玩家去排查的数组)

void DisplayBoard(char board[ROWS][COLS], int row, int col)   //打印棋盘
{
	int i = 0;
	int j = 0; 
	for (i = 0; i<=col; i++)      // 为了方便玩家更快找到坐标 可以打印列号
	{
		printf("%d ",i);
	}
	printf("n");
	for (i = 1; i <=row; i++)
	{
		printf("%d ", i);        //打印行号
		for (j = 1; j <=col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("n");
	}
}

​

布置雷

#define EASY_COUNT 3     //设置雷数 用define定义方便以后可以修改
SetMine(mine, ROW, COL);               //在mine里面布置雷  
void SetMine(char mine[ROWS][COLS], int row, int col)    //布置雷
{
	int count = EASY_COUNT;
	int x = 0;
	int y = 0;
	while (count)
	{
		x = rand() % row + 1;    //产生1--9 坐标
		y = rand() % col + 1;    //产生1--9坐标
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}
//DisplayBoard(mine, ROW, COL);         //(我们不用打印mine数组,这个数组是用来存放雷的,这里打印只是为了检查布置雷是否正确)

排查雷

FindMine(mine,show, ROW, COL);          // 排雷     
static int get_mine_count(char mine[ROWS][COLS], int x, int y)    //计算所输入坐标周围8个坐标的雷数
{                                                                  //用static修饰使它只能在本文件中使用(也可不用)
	return mine[x + 1][y - 1] +                                   //为后面的FindMine函数做准备
		mine[x][y - 1] + 
		mine[x - 1][y - 1] +
		mine[x - 1][y] + 
		mine[x + 1][y] +
		mine[x - 1][y + 1] + 
		mine[x][y + 1]+ mine[x + 1][y + 1] - 8 * '0';
}
static int Check(char show[ROWS][COLS], int row, int col)      //遍历整个棋盘 
{                                                              //若未排的位置个数与雷数相等,则排雷成功
	int i = 0;
	int j = 0;
	int win = 0;
	for (i = 1; i <= row; i++)
	{
		for (j = 1; j <= col; j++)
		{
			if (show[i][j] == '*')
			{
				win++;                                       //计算未排的位置并返回,与雷数作比较(为下面的FineMine函数做准备)
			}
		}
	}
	return win;                                            
}
void board(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)   //拓展周围是不是雷区
{
	int count = 0;
	if (x == 0 || y == 0 || x == ROWS - 1 || y == COLS - 1)  //判断该坐标是否越界
	{
		return;
	}
	if (show[x][y] != '*')                                  //判断该坐标是否已经排查
	{
		return;
	}
	count = get_mine_count(mine, x, y);                
	if (count > 0)        
	{                        
		show[x][y] = count + '0';              //若该坐标未排除,且周围8个坐标有雷,则通过get_mine_count函数计算返回计算值
		return;
	}
	else if (count == 0)                   //若该坐标周围8个坐标都没有雷,则标志该坐标为'0',且沿着这8个坐标的方向进行递归,遇到雷就停下来。
	{
		show[x][y] = '0';
		board(mine, show, x - 1, y);
		board(mine, show, x - 1, y - 1);
		board(mine, show, x, y - 1);
		board(mine, show, x + 1, y - 1);
		board(mine, show, x + 1, y);
		board(mine, show, x + 1, y + 1);
		board(mine, show, x, y + 1);
		board(mine, show, x - 1, y + 1);
	}
}
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)  //排雷
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win<row*col-EASY_COUNT)      //循环条件不能写为1,否则将会漏掉玩家全部排查成功的可能。
	{
		printf("请输入坐标>:");
		scanf("%d%d", &x, &y);
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("猜到雷,游戏结束n");
				DisplayBoard(mine, row, col);          //玩家输了,展示布置雷的数组,让玩家输的明白
				break;
			}
			else
			{
				board(mine,show,x,y);                    //调用board函数
				DisplayBoard(show, row, col);           //玩家排完一次雷,要打印排查雷的结果(show数组)
				
			}
			win = Check(show, row, col);              //调用Check函数
			if (win == EASY_COUNT)
			{
				break;
			}
		}
		else
		{
			printf("输入的坐标非法,请重新输入n");
		}
	}
	if (win == EASY_COUNT)                                 //若未排的位置个数与雷数相等,则排雷成功
	{
		printf("恭喜你排雷成功n");
		DisplayBoard(mine, row, col);
	}
}

运行结果

完整代码

扫雷(含递归展开)完整代码

       

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>