c语言实现扫雷(详细讲解)

news2024/11/29 8:52:56

本篇介绍,讲解如何使用c语言实现扫雷小游戏.
金句分享:

✨✨✨爱你所爱,行你所行✨✨✨

目录

  • 前言:
  • 一、游戏设计思路介绍:
    • 效果展示
  • 二、游戏的分步讲解
    • 2.1、主函数测试区(test.c)基本构成
    • 2.2、游戏中函数实现区(game.c) (重点)
      • 2.21、雷盘的创建与初始化函数
      • 2.22、雷盘的打印函数
      • 2.23、模式选择函数
      • 2.24、布置雷函数
      • 2.25、排查雷函数
      • 2.26、统计坐标周围雷的个数函数
      • 2.27、自动递归排雷函数
      • 2.28、判断输赢
  • 三、游戏总代码
    • 主函数测试区(test.c) :
    • 函数实现区(game.c)
    • 函数声明区(game.h):

前言:

游戏规则:
我们随便点一个格子,方格即被打开并显示出方格中的数字,方格中数字则表示其周围的8个方格隐藏雷的数目.根据数字,排查出所有的雷即为游戏成功,当点击到有雷的格子时,会被炸死,游戏失败.

一、游戏设计思路介绍:

  1. 设置游戏的菜单(自由设计):
  2. 游戏函数的创建:
  3. 创建雷盘
  4. 初始化雷盘
  5. 打印雷盘
  6. 模式选择:(用于确定雷的个数)
  7. 布置雷
  8. 排查雷
  9. 自动递归循环排雷
  10. 判断输赢

效果展示

二、游戏的分步讲解

2.1、主函数测试区(test.c)基本构成

主函数测试区的作用是.设计菜单,和game函数的调用.
菜单可自由设计,牛牛就不过多介绍了.
主要介绍一下,game函数的实现:
通过调用各函数来实现游戏的总体结构,具体函数的实现放在game.c文件中.主要作用是完成游戏的总体框架.合理的调用相应的函数.

void game()
{
	//创建雷盘
	char secret[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	//初始化雷盘
	initboard(secret, ROWS, COLS,'0');//初始化答案的雷盘
	initboard(show, ROWS, COLS,'*');//初始化玩家的雷盘

	//打印雷盘
	//printboard(secret, ROW, COL);//打印给自己看的答案雷盘
	printboard(show, ROW, COL);//打印给玩家的雷盘

	//布置雷
	int num = c_pattern();//模式选择函数
	setmine(secret, ROW, COL,num);//
	//printboard(secret, ROW, COL);//打印给自己看的答案雷盘

	//排查雷
	findmine(secret, show, ROW, COL,num);//排查雷
	
}

2.2、游戏中函数实现区(game.c) (重点)

2.21、雷盘的创建与初始化函数

如果只有一个雷盘,那么该雷盘既要保存雷的信息,又不能显示给玩家看雷的位置.这边不能很好的进行初始化雷盘.所以我们需要创建两个雷盘:
1.“秘密雷盘”:布置雷的雷盘(只给牛牛自己看的)
2.“展示雷盘”:玩家所看到的雷盘

问题:1
了解扫雷规则的小伙伴知道,当我们输入一个坐标的时候,该坐标就会显示出统计的周围八个坐标雷的个数.所以在创建雷盘的时候会遇到一个问题,玩家在排查雷盘的边角坐标时,周围八个坐标的位置很有可能会越界.
解决方法:
我们可以创建一个更大的数组,比如,当我们需要9×9的数组时,我们创建一个11×11的数组.这样就可以防止越界访问,

越界情况: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _解决方法:

雷盘的创建:

ROWS是一个宏定义的值,在函数声明区中定义.暂时可以理解为数值11.

	//创建雷盘
	char secret[ROWS][COLS] = { 0 };//秘密雷盘
	char show[ROWS][COLS] = { 0 };//展示雷盘

雷盘的初始化:
雷盘创建好之后,我们怎样为棋盘进行合理的初始化呢?

"秘密雷盘"的初始化:
我们用’字符1’表示雷的坐标
字符’0’表示不是雷的坐标.
至于为什么用字符’0’和字符’1’,后面会妙用.

"‘展示雷盘"的初始化:
为了有神秘感,又不能让玩家看见雷的坐标,我们可以全部初始化为’ * '(字符星号).

	initboard(secret, ROWS, COLS,'0');//初始化答案的雷盘
	initboard(show, ROWS, COLS,'*');//初始化玩家的雷盘
//初始化雷盘函数的实现
void initboard(char board[ROWS][COLS], int rows, int cols, char ret)
{
	//ret表示全部初始化的字符,由调用该函数时传递,方便实现代码的复用
	int i = 0,  j = 0;
	for (i = 0; i < rows; i++)
	{	
		for (j = 0; j < cols; j++)
		{
			board[i][j] = ret;
		}
	}
}

2.22、雷盘的打印函数

以9×9大小的雷盘为例子.
重点在于,函数接收的数组大小为11×11,但是我们只需要使用其中中间的9×9雷盘,所以在打印雷盘时,打印坐标的起始值为1而并非0,刚好又符号玩家的坐标需要(非程序员认为是从1开始).
简易雷盘的打印:

void printboard(char board[ROWS][COLS], int row, int col)
{
	printf("------扫雷游戏------\n");
	int i = 0, j = 0;
	for (i = 0; i <= row;i++)//打印列标
	{
		printf("%2d", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%2d", i);
		for (j = 1; j <= col; j++)
		{
			printf("%2c",board[i][j]);
		}
		printf("\n");//打印一行后换行
	}
	printf("------扫雷游戏------\n");
	printf("\n");
}

效果图:

美观雷盘的打印:
与前面三子棋打印方法类似.
牛牛都留好注释了,没看懂备注的,可以点这里,有分步骤教学讲解:

三子棋棋盘打印

//美观雷盘:
void printboard(char board[ROWS][COLS], int row, int col)//打印棋盘//建议参照棋盘的外观查看代码
{
	printf("-----------------扫雷游戏-------------\n");
	int i = 0, j = 0;
	printf(" ");//打印空格是为了对齐(因为下面的行号占用位置)
	//打印显示在第一行的列标
	for (i = 1; i <= row; i++)
	{
		printf("%3d ", i);//因为一个数据行的格子占3个位置,所以我们这里用%3d占用三个位置的空间
	}
	printf("\n");//打印列标后换行。
	printf("  +");//先打印一个+,可以观察棋盘外观,将棋盘外观拆分打印。//为了对齐加了一个空格,因为分割行前面没有行号占用位置,只能补空格。
	for (i = 0; i < row; i++)//打印第一行的分割线
	{
		printf("---+");
	}
	printf("\n");//每次打印一行就要换行
	//开始打印数据行
	for (i = 1; i <= row; i++)
	{
		printf("%2d", i );//打印数据行前面的行号,%2d是因为当行数>9的时候,两位数会占用两个位置,影响对齐。(细节)
		printf("|");//和上面一样,先打印一个 | ,可以观察棋盘外观,将数据行拆分打印。
		for (j = 1; j <= col; j++)//打印一行中间的棋子和其它分割线
		{
			printf(" %c |", board[i][j]);//这里打印的是“空格”“棋子”“空格”“|”
		}
		printf("\n");//每次打印一行就要换行
		//打印剩余的分割行
		printf("  +");//先打印一个+,可以观察棋盘外观,将棋盘外观拆分打印。//为了对齐加了一个空格
		for (j = 0; j < col; j++)//打印一行外观的分割线
		{
			printf("---+");//每次打印一行就要换行
		}
		printf("\n");
	}
	printf("-----------------扫雷游戏-------------\n");
}

效果图:

2.23、模式选择函数

为了让玩家可以控制难度,牛牛设置了一个难度选择函数,根据玩家的选择来设置相应的雷的数量.

此函数重点在于,要使用getchar()函数将缓存区的清除,否则影响下面的难度选择的输入.(牛牛当时疏忽了,找了好久才找到原因,缓存区有一个换行符被直接读取给了scanf(“%c”, &pattern);😭😭😭)

//模式选择函数的实现(返回设置雷的个数):
int c_pattern()
{
	int num = 0;//表示布置雷的数量
again://玩家选择模式错误时返回到此处
	printf("欢迎玩家进入游戏:\n");
	printf("请新选择难度:(num代表雷的数量)\n");
	printf("A.简单模式:num=5	B.中等模式:num=15	C.困难模式:num=30	D.自定义难度(自由输入雷的个数)\n ");
	char pattern = 0;
	getchar();//清楚缓存区
	scanf("%c", &pattern);//玩家模式选择
	switch (pattern)
	{
	case 'A':
	case 'a':
		printf("简单模式:num=5\n");
		num = 5;
		return num;
	case 'B':
	case 'b':
		printf("中等模式:num=10\n");
		num = 15;
		return num;
	case 'C':
	case 'c':
		printf("困难模式:num=15\n");
		num = 30;
		return num;
	case 'D':
	case 'd':
		printf("自定义难度:");
		printf("请输入布置雷的个数:\n");
		getchar();//清楚缓存区
		int intput = 0;
		scanf("%d", &intput);//用户自定义的雷的个数
		num = intput;
		return num;
	default:
		printf("不好意思,牛牛还没有开发此模式,请重新选择:\n\n");
		goto again;//让玩家重新选择
		break;
	}
}

2.24、布置雷函数

布置雷的逻辑与三子棋的电脑落子逻辑上是一样的.
通过生成两个随机数,将其作为坐标,修改(秘密棋盘)该坐标的值为’1’(表示雷).

//布置雷盘函数实现
void setmine(char board[ROWS][COLS], int row, int col,int num)
{
	int x = 0, y = 0;
	int count = 0;
	for (count = 0; count < num; )
	{
		x = 1 + rand() % row;
		y = 1 + rand() % col;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count++;//每次布置好一个雷之后,才会计数
		}
	}
}

2.25、排查雷函数

让玩家输入要排查雷的坐标,先判断坐标的合法性,是否越界.
如果坐标合法,统计该坐标周围八个坐标有多少个雷.
如果该坐标周围没有雷,就将该坐标设置为空格,并递归排查周围八个坐标的值.
如果该坐标是雷,则游戏结束.
每次排查一个坐标后,判断玩家是否取得胜利.

//排查雷函数的实现
void findmine(char secret[ROWS][COLS], char show[ROWS][COLS], int row, int col,int num)
{
	int x = 0, y = 0;
	int win = 0;//表示被排查的雷的个数
	while (win < (row * col -num))
	{
		printf("请输入排查雷的坐标:\n格式为:行号 列标\n");
		scanf("%d%d", &x, &y);
		if (show[x][y] != '*')//被排查过的坐标不是*
		{
			printf("该坐标已经被排查过了.请重新输入:");
			continue;
		}
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (secret[x][y] == '1')//如果是1就代表是雷,游戏结束
			{
				printf("很遗憾,你失败了\n");
				printf("请看答案:\n");
				printboard(secret, ROW, COL);//失败后,给玩家看答案雷盘
				printf("很遗憾,你失败了\n上面是答案:\n");
				break;
			}
			else//此坐标不是雷
			{
				
				digui(secret, show, ROW, COL,x,y,&win);//自动递归排雷函数
				win=is_win(show, ROW, COL);
				printboard(show, ROW, COL);//打印给玩家的雷盘
			}
		}
		else
		{

			printf("坐标非法,请重新输入:\n");
		}
	}
	if (win == (row * col - num))//行号*列标表示总共的坐标数-已经被排查的坐标数
	{
		printf("恭喜你排雷成功\n");
		printf("牛牛为你点赞!!!\n");
	}
}

2.26、统计坐标周围雷的个数函数

由于是存放的都是字符,所以计算结果-8×’0’,得到数值.

//统计坐标周围雷的数量
int countmine(char secret[ROWS][COLS], int x, int y)
{
	int ret = secret[x - 1][y - 1]+ secret[x - 1][y] + secret[x - 1][y + 1] 
		+ secret[x][y - 1] + secret[x][y + 1]
		+ secret[x + 1][y - 1] + secret[x + 1][y] + secret[x + 1][y + 1] - 8 * '0';
	return ret;
}

2.27、自动递归排雷函数

如果一次只能排查一个坐标,那这游戏是不是太难了?
我们可以通过递归的方式,从这个坐标的周围八个坐标展开,进行排雷.
当然使用递归的时候一定要记住,要有限制条件,否则就会死循环调用,直到栈空间耗尽.
这里,我们执行递归的条件是:
1.周围没有雷,否则显示雷的个数,不进入递归.
2.此坐标并没有被排查过(状态是:’ * ').

//自动递归排雷函数
digui(char secret[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y)
{
	
	if (x >= 1 && x <= row && y >= 1 && y <= col)//防止递归的时候坐标越界
	{
		int count = countmine(secret, x, y);//计算该坐标周围有几个雷
		if (count == 0)//如果周围八个坐标没有雷
		{
			show[x][y] = ' ';//周围没有雷的坐标变为空格
			int i = 0, j = 0;
			for (i = x - 1; i <= x +1; i++)//得到周围八个坐标
			{
				for (j = y - 1; j <= y+1 ; j++)
				{
					if (show[i][j] == '*' && (i != x || j != y))//防止重新递归show[x][y]坐标
					{
						digui(secret, show, ROW, COL, i, j);
					}
					
				}
			}
		}
		else//如果周围有雷
		{
			show[x][y] = count + '0';
		}
	}
}

2.28、判断输赢

玩家每次输入一个坐标,进行递归排雷之后,统计目前有多少坐标已经被排查了.
计算个数后,返回值.
if (win == (row * col - num))//行号*列标表示总共的坐标数-已经被排查的坐标数=雷的数量
则玩家胜利通关.

//计算已经被排查过的位置
int is_win(char show[ROWS][COLS],int row,int col)
{
	int count1 = 0;//已经被排查的坐标个数
	int i = 0, j = 0;
	for (i = 1; i <= row; i++)
	{
		for (j = 1; j <= col; j++)
		{
			if (show[i][j] != '*')//只要不是*,表示该坐标已经被排查了.
			{
				count1++;
			}
		}
	}
	return count1;
}

好了,以上是牛牛对用c语言扫雷的理解,有不足之处,欢迎评论区指出,当然如果有不理解的小伙伴也可以私信提问哦,牛牛会一 一解答的.
小伙伴们的点赞就是给牛牛最大的支持,能不能给牛牛来一个一键三连呢?谢谢支持。

最后附上总代码.

三、游戏总代码

主函数测试区(test.c) :

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
	printf("*******************************************************************\n");
	printf("************                     *                    *************\n");
	printf("******************               *                *****************\n");
	printf("************************         *          ***********************\n");
	printf("*******************************  *   ******************************\n");
	printf("********    1.玩游戏         *        2.退出游戏          *********\n");
	printf("*******************************  *   ******************************\n");
	printf("************************         *          ***********************\n");
	printf("******************               *                *****************\n");
	printf("************                     *                     ************\n");
	printf("*******************************************************************\n");
	printf("请选择:\n");
}
void game()
{
	

	//创建雷盘
	char secret[ROWS][COLS] = { 0 };//秘密雷盘
	char show[ROWS][COLS] = { 0 };//展示雷盘

	//初始化雷盘
	initboard(secret, ROWS, COLS,'0');//初始化答案的雷盘
	initboard(show, ROWS, COLS,'*');//初始化玩家的雷盘

	//打印雷盘
	//printboard(secret, ROW, COL);//打印给自己看的答案雷盘
	printboard(show, ROW, COL);//打印给玩家的雷盘

	//布置雷
	int num = c_pattern();//模式选择函数
	setmine(secret, ROW, COL,num);//布置雷函数
	//printboard(secret, ROW, COL);//打印给自己看的答案雷盘

	//排查雷
	findmine(secret, show, ROW, COL,num);//排查雷
	
}
int main()
{
	int n = 0;//记录玩家在菜单中的选择
	srand((unsigned int)time(NULL));//与前面介绍的猜数字游戏一样,改变种子值来使得rand函数每次生成不同的随机数列。
	do
	{
		menu();
		scanf("%d", &n);//让玩家在菜单中选择
		switch (n)
		{
		case 1://代表玩游戏
			game();
			printf("再来一局吗?\n");
			printf("1.再来一局   2. 没意思不玩了\n");
			int again = 0;//存放玩家是否再玩的结果。
			scanf("%d", &again);
			if (again == 1)
			{
				break;
			}
			else
				n = 2;//令n=2循环结束
			break;
		case 2:
			printf("退出游戏");
			break;
		default:
			system("cls");
			printf("没有这个选项哦。请重新选择:\n\n");//玩家不小心输错了
			getchar();//清楚缓存区
			continue;
		}
	} while (n - 2);//当玩家选择2时,代表不玩了
}

函数实现区(game.c)

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"


//初始化雷盘函数的实现
void initboard(char board[ROWS][COLS], int rows, int cols, char ret)
{
	int i = 0,  j = 0;
	for (i = 0; i < rows; i++)
	{	
		for (j = 0; j < cols; j++)
		{
			board[i][j] = ret;
		}
	}
}

//打印雷盘函数的实现
//美观雷盘:
void printboard(char board[ROWS][COLS], int row, int col)//打印棋盘//建议参照棋盘的外观查看代码
{
	printf("-----------------扫雷游戏-------------\n");
	int i = 0, j = 0;
	printf(" ");//打印空格是为了对齐(因为下面的行号占用位置)
	//打印显示在第一行的列标
	for (i = 1; i <= row; i++)
	{
		printf("%3d ", i);//因为一个数据行的格子占3个位置,所以我们这里用%3d占用三个位置的空间
	}
	printf("\n");//打印列标后换行。
	printf("  +");//先打印一个+,可以观察棋盘外观,将棋盘外观拆分打印。//为了对齐加了一个空格,因为分割行前面没有行号占用位置,只能补空格。
	for (i = 0; i < row; i++)//打印第一行的分割线
	{
		printf("---+");//上图讲解了拆分过程。
	}
	printf("\n");//每次打印一行就要换行
	//开始打印数据行
	for (i = 1; i <= row; i++)
	{
		printf("%2d", i );//打印数据行前面的行号,%2d是因为当行数>9的时候,两位数会占用两个位置,影响对齐。(细节)
		printf("|");//和上面一样,先打印一个 | ,可以观察棋盘外观,将数据行拆分打印。
		for (j = 1; j <= col; j++)//打印一行中间的棋子和其它分割线
		{
			printf(" %c |", board[i][j]);//这里打印的是“空格”“棋子”“空格”“|”
		}
		printf("\n");//每次打印一行就要换行
		//打印剩余的分割行
		printf("  +");//先打印一个+,可以观察棋盘外观,将棋盘外观拆分打印。//为了对齐加了一个空格
		for (j = 0; j < col; j++)//打印一行外观的分割线
		{
			printf("---+");//每次打印一行就要换行
		}
		printf("\n");
	}
	printf("-----------------扫雷游戏-------------\n");
}
//简易雷盘:
//void printboard(char board[ROWS][COLS], int row, int col)
//{
//	printf("------扫雷游戏------\n");
//	int i = 0, j = 0;
//	for (i = 0; i <= row;i++)//打印列标
//	{
//		printf("%2d", i);
//	}
//	printf("\n");
//	for (i = 1; i <= row; i++)
//	{
//		printf("%2d", i);
//		for (j = 1; j <= col; j++)
//		{
//			printf("%2c",board[i][j]);
//		}
//		printf("\n");//打印一行后换行
//	}
//	printf("------扫雷游戏------\n");
//	printf("\n");
//}

//模式选择函数的实现(返回设置雷的个数):
int c_pattern()
{
	int num = 0;
again://玩家选择模式错误时返回到此处
	printf("欢迎玩家进入游戏:\n");
	printf("请新选择难度:(num代表雷的数量)\n");
	printf("A.简单模式:num=5	B.中等模式:num=15	C.困难模式:num=30	D.自定义难度(自由输入雷的个数)\n ");
	char pattern = 0;
	getchar();//清楚缓存区
	scanf("%c", &pattern);//玩家模式选择
	switch (pattern)
	{
	case 'A':
	case 'a':
		printf("简单模式:num=5\n");
		num = 5;
		return num;
	case 'B':
	case 'b':
		printf("中等模式:num=10\n");
		num = 15;
		return num;
	case 'C':
	case 'c':
		printf("困难模式:num=15\n");
		num = 30;
		return num;
	case 'D':
	case 'd':
		printf("自定义难度:");
		printf("请输入布置雷的个数:\n");
		getchar();//清楚缓存区
		int intput = 0;
		scanf("%d", &intput);//用户自定义的雷的个数
		num = intput;
		return num;
	default:
		printf("不好意思,牛牛还没有开发此模式,请重新选择:\n\n");
		goto again;//让玩家重新选择
		break;
	}
}

//布置雷盘函数实现
void setmine(char board[ROWS][COLS], int row, int col,int num)
{
	int x = 0, y = 0;
	int count = 0;
	for (count = 0; count < num; )
	{
		x = 1 + rand() % row;
		y = 1 + rand() % col;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count++;//每次布置好一个雷之后,才会计数
		}
	}
}


//统计坐标周围雷的数量
int countmine(char secret[ROWS][COLS], int x, int y)
{
	int ret = secret[x - 1][y - 1]+ secret[x - 1][y] + secret[x - 1][y + 1] 
		+ secret[x][y - 1] + secret[x][y + 1]
		+ secret[x + 1][y - 1] + secret[x + 1][y] + secret[x + 1][y + 1] - 8 * '0';
	return ret;
}

//自动递归排雷函数
digui(char secret[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y)
{
	
	if (x >= 1 && x <= row && y >= 1 && y <= col)//防止递归的时候坐标越界
	{
		int count = countmine(secret, x, y);//计算该坐标周围有几个雷
		if (count == 0)//如果周围八个坐标没有雷
		{
			show[x][y] = ' ';//周围没有雷的坐标变为空格
			int i = 0, j = 0;
			for (i = x - 1; i <= x +1; i++)//观察周围八个坐标he
			{
				for (j = y - 1; j <= y+1 ; j++)
				{
					if (show[i][j] == '*' && (i != x || j != y))//防止重新递归show[x][y]坐标
					{
						digui(secret, show, ROW, COL, i, j);
					}
					
				}
			}
		}
		else//如果周围有雷
		{
			show[x][y] = count + '0';
		}
	}
}

//计算已经被排查过的位置
int is_win(char show[ROWS][COLS],int row,int col)
{
	int count1 = 0;//已经被排查的坐标个数
	int i = 0, j = 0;
	for (i = 1; i <= row; i++)
	{
		for (j = 1; j <= col; j++)
		{
			if (show[i][j] != '*')//只要不是*,表示该坐标已经被排查了.
			{
				count1++;
			}
		}
	}
	return count1;
}
//排查雷函数的实现
void findmine(char secret[ROWS][COLS], char show[ROWS][COLS], int row, int col,int num)
{
	int x = 0, y = 0;
	int win = 0;//表示被排查的雷的个数
	while (win < (row * col -num))
	{
		printf("请输入排查雷的坐标:\n格式为:行号 列标\n");
		scanf("%d%d", &x, &y);
		if (show[x][y] != '*')//被排查过的坐标不是*
		{
			printf("该坐标已经被排查过了.请重新输入:");
			continue;
		}
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (secret[x][y] == '1')//如果是1就代表是雷,游戏结束
			{
				printf("很遗憾,你失败了\n");
				printf("请看答案:\n");
				printboard(secret, ROW, COL);//失败后,给玩家看答案雷盘
				printf("很遗憾,你失败了\n上面是答案:\n");
				break;
			}
			else//此坐标不是雷
			{
				
				digui(secret, show, ROW, COL,x,y,&win);//自动递归排雷函数
				win=is_win(show, ROW, COL);
				printboard(show, ROW, COL);//打印给玩家的雷盘
			}
		}
		else
		{

			printf("坐标非法,请重新输入:\n");
		}
	}
	if (win == (row * col - num))
	{
		printf("恭喜你排雷成功\n");
		printf("牛牛为你点赞!!!\n");
	}
}

函数声明区(game.h):

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>//清屏函数的头文件
#include <time.h>//srand函数的头文件

#define ROW 12//方便修改棋盘大小
#define COL 12

#define ROWS ROW+2
#define COLS COL+2


//声明初始化雷盘函数
void initboard(char board[ROWS][COLS], int rows, int cols, char ret);

//声明打印雷盘函数
void printboard(char board[ROWS][COLS],int row, int col);

//声明布置雷函数
void setmine(char board[ROWS][COLS], int row,int col,int num);

//声明排查雷的函数
void findmine(char secret[ROWS][COLS], char show[ROWS][COLS], int row,int col,int num);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/166231.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

centos8 Ambari-2.7.6.3+HDP-3.3.1离线安装详细教程(附安装包)

自2021年1月31日开始,所有Cloudera软件都需要有效的订阅,且订阅费昂贵。此外,CDH6和HDP3将是CDH和HDP的最后企业版本,原有企业版用户无法继续获取新的功能和性能提升。至2022年3月份,CDH/HDP全部停止服务(EoS),用户没办法获取售后支持。由于生产环境系统升级到centos8,…

linux 中 PCIE 中断映射机制

PCIE 中断映射机制 1、 PCIE 中有三种中断方式&#xff0c; MSI&#xff0c;MSI-X 和INTx PCIe总线继承了PCI总线的所有中断特性&#xff08;包括INTx和MSI/MSI-X&#xff09;&#xff0c;以兼容早期的一些PCI应用层软件。 PCI总线最早采用的中断机制是INTx&#xff0c;这是…

基于Flink+kafka实时告警

引出问题 项目使用告警系统的逻辑是将实时数据保存到本地数据库再使用定时任务做判断&#xff0c;然后产生告警数据。这种方式存在告警的延时实在是太高了。数据从产生到保存&#xff0c;从保存到判断都会存在时间差&#xff0c;按照保存数据定时5分钟一次&#xff0c;定时任务…

智慧水务能效管理平台在污水处理厂电气节能中的应用

摘要&#xff1a;污水处理属于高能耗行业&#xff0c;会消耗大量的电能、燃料和药剂等&#xff0c;高能耗不仅会提升污水处理成本&#xff0c;还会加剧能源危机。所以&#xff0c;本文首先探究了污水处理厂耗能的原因&#xff0c;分析了污水处理与节能降耗的关系&#xff0c;然…

MyBatis-Plus数据安全保护(加密解密)

项目创建POM依赖 <dependency><!--MyBatis-Plus 企业级模块--><groupId>com.baomidou</groupId><artifactId>mybatis-mate-starter</artifactId><version>1.2.8</version> </dependency> <!-- https://mvnrepository…

git commit 命令详解

文章目录前言1. git commit 介绍2. git commit 使用3. git commit -m4. git commit -am5. git commit --amend6. commit 多行提交信息7. commit 背后到底发生了什么前言 CSDN 只用来做博客主站文章的转载 博客主站&#xff1a;https://www.itqaq.com 下面地址路径可能会发生变…

Java---中间件---Redis的常见命令和客户端使用

Redis的常见命令和客户端使用1.初识Redis1.1.认识NoSQL1.1.1.结构化与非结构化1.1.2.关联和非关联1.1.3.查询方式1.1.4.事务1.1.5.总结1.2.认识Redis1.3.安装Redis1.3.1.依赖库1.3.2.上传安装包并解压1.3.3.启动1.3.4.默认启动1.3.5.指定配置启动1.3.6.开机自启1.4.Redis桌面客…

VulnHub2018_DeRPnStiNK靶机总结

VulnHub2018_DeRPnStiNK靶机渗透总结 靶机下载地址: https://download.vulnhub.com/derpnstink/VulnHub2018_DeRPnStiNK.ova https://www.dropbox.com/s/8jqor3tuc3jhe1w/VulnHub2018_DeRPnStiNK.ova?dl0 打开靶机,使用nmap扫描出靶机的ip和开放的所有端口 可以看到,靶机开放…

从零开始学习Linux

Linux Linux内核版本&#xff1a;Linux内核运维开发小组&#xff0c;源码在不开源 Linux发行版本&#xff1a;由各大互联网/软件公司定制&#xff0c;开源 一个内核版本是有多种多样的发行版本 Ubuntu&#xff1a;以强大的桌面应用为主&#xff0c;吸收不少Windows用户&…

Docker部署jeecgboot微服务使用记录

docker安装和基础命令 docker安装 docker安装详细步骤 Docker命令 #进入容器 sudo docker exec -it 775c7c9ee1e1 /bin/bash # docker中 启动所有的容器命令 docker start $(docker ps -a | awk { print $1} | tail -n 2) # docker中 关闭所有的容器命令 docker stop $(doc…

(黑马C++)L09 C++类型转换 异常 输入输出流

一、C类型转换 类型转换&#xff08;cast&#xff09;是将一种数据类型转换成另一种数据类型&#xff0c;一般情况下要尽量少的去使用类型转换&#xff0c;除非解决非常特殊的问题。 &#xff08;1&#xff09;静态转换&#xff08;static_cast&#xff09; static_cast使用…

联合证券|内外利好共振 今年A股可更乐观一点

在经历了开年首周的快速拉升后&#xff0c;上星期A股商场全体高位盘整。职业板块从普涨转为快速轮动&#xff0c;前期领涨的新能源及大消费主线均出现了必定程度的回撤&#xff0c;由金融、信创板块接力“领跑”。 展望后市&#xff0c;指数在盘整后能否持续上攻&#xff1f;外…

解决前后端分离Vue项目部署到服务器后出现的302重定向问题

解决前后端分离Vue项目部署到服务器后出现的302重定向问题问题描述问题原因定位问题解决方案校验修改效果相关阅读写在最后问题描述 最近发现自己开发的vue前后端分离项目因为使用了spring security 安全框架&#xff0c;即使在登录认证成功之后再调用一些正常的接口总是会莫名…

Xilinx 7系列FPGA之Spartan-7产品简介

以最低的成本获得无与伦比的性能和功耗效率如果您对功耗或性能的要求与成本要求一样严苛&#xff0c;那么请使用 Spartan -7 FPGA。该系列采用 TSMC&#xff08;台积电&#xff09; 的 28nm HPL 工艺制造&#xff0c;将小尺寸架构的Xilinx 7 系列FPGA 的广泛功能和符合 RoHS 标…

结构体专题详解

目录 &#x1f94e;什么是结构体&#xff1f; ⚾结构体的声明 &#x1f3c0;简单结构体的声明 &#x1f3d0;结构体的特殊声明 &#x1f3c8;结构体嵌套问题 &#x1f3c9;结构体的自引用 &#x1f3b3;结构体的内存大小 &#x1f94c;结构体的内存对齐 ⛳内存对齐的优点 ⚽还…

SAP 服务器参数文件详细解析

一、SAP参数的说明 SAP参数的学习需要了解SAP参数的作用、参数的启动顺序、参数的配置&#xff1b; 1、参数的启动顺序 a) 启动Start profileb) 启动default profilec) 启动instance profile 2、参数的位置 a) 启动参数Start profile的位置&#xff1a;/usr/sap//SYS/prof…

计讯物联数字乡村解决方案赋能乡村振兴

项目背景 数字乡村是乡村振兴的战略方向&#xff0c;是推动农村现代化的重要途径。当前&#xff0c;数字乡村建设正在加速推进&#xff0c;打造乡村数字治理新模式&#xff0c;提升乡村的数字化水平&#xff0c;进一步推动乡村振兴进入高质量发展新赛道。计讯物联作为数字乡村…

机器学习的几个公式

今天看了几个公式的推演过程&#xff0c;有些推演过程还不是很明白&#xff0c;再着担心自己后面会忘记&#xff0c;特来此记下笔记。python 是由自己特定的公式符号的&#xff0c;但推演过程需要掌握&#xff0c;其实过程不过程不是重点&#xff0c;只要是要记得公式的含义&am…

SocketCAN 命名空间 VCAN VXCAN CANGW 举例

文章目录NAMESPACESocketCAN最新 can-utils 安装VCAN 举例VXCAN 举例CANGW 举例参考NAMESPACE namespaces, 命名空间, 将全局系统资源包装在抽象中, 使命名空间中的进程看起来拥有自己全局资源的独立实例. 命名空间的一个用途是实现容器. Linux 命名空间类型及隔离物(Isolate…

译文 | Kubernetes 1.26:PodDisruptionBudget 守护不健康 Pod 时所用的驱逐策略

对于 Kubernetes 集群而言&#xff0c;想要确保日常干扰不影响应用的可用性&#xff0c;不是一个简单的任务。上月发布的 Kubernetes v1.26 增加了一个新的特性&#xff1a;允许针对 PodDisruptionBudget (PDB) 指定不健康 Pod 驱逐策略&#xff0c;这有助于在节点执行管理操作…