【C语言】扫雷----详解(扩展版)

news2024/12/29 10:33:00

🍁 博客主页:江池俊的博客_CSDN博客

🍁 如果觉得博主的文章还不错的话,请点赞👍收藏🌟 三连支持一下博主💞

✉️每一次努力都是一次进步,每一次尝试都是一次机会。无论遇到什么困难,都要坚定地向       前迈进。相信自己,并相信自己的潜力,您注定会取得非凡的成就!

🔥编译环境:Visual Studio 2022

目录

一、游戏介绍

游戏规则: 

游戏玩法:

二、游戏实现思路 

三、创建文件

1.test.c文件 

😆(menu)菜单函数的实现

😆game函数的实现

😆main函数的实现

2.game.c文件

😊书写初始化棋盘函数

😊书写打印棋盘信息的函数

😊书写设置雷的函数(是雷则为‘1’)

😊书写统计周围雷个数的函数

😊书写展开一片非雷区域的函数

😊书写计算非雷和非标记的位置个数

😊书写排查雷的函数

 3.game.h文件

😄需要使用的头文件

😄定义棋盘行列

😄定义雷的个数

😄初始化棋盘

😄打印棋盘

😄布置雷

😄排查雷

四、总代码 

(一)game.h文件

(二)game.c文件 

(三)test.c文件

五、效果展示


前言

本篇文章主要是讲解用C语言实现扫雷游戏,与三子棋的实现思路类似,可以参考我前面的两篇文章《三子棋》http://t.csdn.cn/oQQhS  《猜数字游戏》 http://t.csdn.cn/njZHu

下面我们回归正题,让我来详细讲解如何实现扫雷游戏。

这里我们以9*9的网格为例。

一、游戏介绍

扫雷是一款经典的单人益智游戏,目标是在一个由方格组成的区域中找到并标记出所有的地雷,同时避免触雷。下面是扫雷游戏的网页链接,你可以通过玩下方的游戏加深自己对游戏的逻辑和原理的理解。

扫雷游戏网页版 - Minesweeper

 5752a50bb6954d6f8fbe985d177d1c27.png   a8f8785734d640ad906c3fd72f1817de.png  402e368914154b67a1647f8558903392.png 

上面依次是游戏进行、失败和胜利的界面 。

游戏规则: 

1.游戏开始时,整个区域被分割成一系列方格,其中一些方格中隐藏有地雷。

2.方格可以是未被揭开的状态,也可以是已被揭开或标记过的状态。

3.点击一个方格可以揭开它,如果该方格中没有地雷,则会显示数字,表示周围8个方格中地     雷的数量。

4.如果揭开的方格没有地雷数量,则会自动会揭开周围相邻的空方格。

5.如果揭开的方格中有地雷,游戏结束,玩家失败。

游戏玩法:

 1.目标是找到并标记出所有的地雷,而不触雷。

 2.揭开方格时,根据方格周围的地雷数量,判断周围的方格是否安全。数字表示周围有多少颗地雷。

 3.如果您确定某个方格中有地雷,可以标记该方格为雷。这有助于您记住哪些方格是地雷,也可以帮助您避免不小心触雷。

 4.使用推理和逻辑来判断哪些方格一定是地雷,哪些方格一定是安全的。通过标记地雷并推断周围的数字,逐渐揭开更多的方格,直到找到所有的地雷。

二、游戏实现思路 

1.创建游戏棋盘:使用二维数组表示游戏棋盘,每个格子可以是开放状态、地雷或者标记状态。

2.随机布雷:使用随机数生成地雷的位置,并在对应位置上设置地雷。

3.计算周围地雷数量:遍历游戏棋盘,对于每个非地雷格子,统计周围八个格子中地雷的数量。

4.游戏循环:进入游戏循环,每次循环包括以下步骤:
   a. 显示游戏棋盘。
   b. 接收用户输入,包括选择要打开的格子或标记地雷。
   c. 根据用户选择更新游戏棋盘状态。
   d. 检查游戏是否胜利或失败。

5.判断游戏是否胜利:检查游戏棋盘中所有非地雷格子是否被正确打开。

6.判断游戏是否失败:当玩家选择打开一个格子时,如果该格子是地雷,则游戏失败。

7.标记地雷:当玩家选择标记一个格子时,在游戏棋盘中该格子的状态为已标记。

8.打开格子:当玩家选择打开一个格子时,根据该格子的状态进行相应操作:
   a. 如果该格子已经被标记,则忽略。
   b. 如果该格子是地雷,则游戏失败。
   c. 如果该格子是数字格子,则显示该数字。
   d. 如果该格子是空白格子,则继续打开周围的空白格子直到遇到数字格子。(使用递归思想)

10.继续游戏或退出:在游戏胜利或失败后,询问玩家是否继续游戏。

三、创建文件

由于该游戏的实现需要大量的代码,为了提高代码的可读性已经方便后续写代码时的自我检查,这里我们创建三个文件来实现该游戏,我们依次将三个文件命名为game.h \ game.c \ test.c。

🌴game.h文件用来定义游戏棋盘的行列,以及包含该过程中需要用到的头文件和声明各种函数。

🌴game.c文件最为重要,它主要是来写实现各种游戏功能的函数,即初始化棋盘,打印棋盘信息,设置棋盘雷的位置,统计雷的个数,展开无雷的一片区域,判断游戏输赢以及标记雷的位置。

🌴test.c文件则是为了打印游戏菜单和实现game游戏函数。

1.test.c文件 

😆(menu)菜单函数的实现

void menu()
{
	printf("\t\t\t\t\t\t\t\t\t\t\t\n");
	printf("*********************\n");
	printf("*****  1. play  *****\n");
	printf("*****  0. exit  *****\n");
	printf("*********************\n");
}

打印结果: 

😆game函数的实现

主要功能如下:

1.创建并初始化棋盘

2.设置雷的位置(使用rand函数)

3.打印棋盘信息

4.排查雷:a.展开一片非雷区域

                  b.显示周围雷的个数

                  c.判断游戏输赢

void game()
{
	char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息
	char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息
	//初始化数组的内容为指定内容
	//mine数组在没有布置雷的时候,都是‘0’
	InitBoard(mine, ROWS, COLS,'0');
	//show数组在没有排查雷的时候都是‘*’
	InitBoard(show, ROWS, COLS, '*'); 


	//设置雷
	Setmine(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);
	//DisplayBoard(mine, ROW, COL);
	//排查雷
	FindMine(mine, show, ROW, COL);

}

这里我们需要创建两个数组作为棋盘,但是棋盘比实际的要大一圈,这是因为在对边上的格子进行排查时,往往不满八个格子,对9*9之外的格子访问时会越界,这时我们需要手动创建它周围的格子使得它能够成功访问,这样的话创建的数组棋盘就从9*9变成了11*11。

当访问棋盘右上角的格子时,右上角黄色方框中的格子就是排查时要访问的格子

这里我们要设置两个棋盘,其中一个棋盘(名字为mine)存放雷的信息,另一个棋盘(名字为show)存放排查雷的信息,这里我们初始化mine棋盘为字符‘0’,show棋盘为字符‘*’。

打印结果:

😆main函数的实现

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:system("cls"); game();
			break;
		case 0:printf("退出游戏\n");
			break;
		default:printf("选择错误,请重新输入!\n");
			break;
		}
	} while (input);
	return 0;
}

这里我们通过do while循环和switch语句来实现游戏的持续进行和对不同输入的选择,输入1,进入游戏,输入0,退出游戏,输入其他时,输出“选择错误,请重新输入!”。

打印结果:

2.game.c文件

😊书写初始化棋盘函数

//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set)
{
	int i = 0;
	int j = 0;
	for(i=0;i<rows;i++)
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
}

因为有两个棋盘,所以我们需要一个字符型变量(char)set 来设置棋盘初始化的值,如果是mine棋盘,则 set = ‘0’;如果是show棋盘,则 set = ‘*’ 。

😊书写打印棋盘信息的函数

//打印棋盘信息
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("------扫雷游戏------\n");
	printf("════════════════════\n");//美化棋盘
	for (j = 0; j <= col; j++)
	{
		printf("%d|", j);
	}
	printf("\n-|══════════════════");//美化棋盘
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d|", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c|", board[i][j]);
		}
		printf("\n");
	}
	printf("════════════════════\n");//美化棋盘
	printf("------扫雷游戏------\n\n");
}

打印结果: 

😊书写设置雷的函数(是雷则为‘1’)

//设置雷的函数
void Setmine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	//行1-9  列1-9
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;
		}
	}
}

下面我会针对遇到的问题进行解答👀

👀如何随机设置雷的位置? 

使用srand()来随机设置雷的坐标

//test.c
srand((unsigned int)time(NULL));//设置随机数的生成起点

 👀如何控制雷的坐标位置合理

int x = rand() % row + 1;//生成1-9的随机数
int y = rand() % col + 1;//生成1-9的随机数

利用rand() 函数取row或col的模再+1来得到1-9的随机数,这样就可以控制雷的位置在棋盘上。

😊书写统计周围雷个数的函数

//统计周围雷数的函数
int get_mine_count(char board[ROWS][COLS], int row, int col,int x,int y)
{
	int count = 0;
	for(int i=-1;i<=1;i++)
		for (int j = -1; j <= 1; j++)
		{
			if (board[x + i][y + j] == '1')
				count++;
		}
	return count;

	/*return (board[x - 1][y] +
		board[x - 1][y - 1] +
		board[x][y - 1] +
		board[x + 1][y - 1] +
		board[x + 1][y] +
		board[x + 1][y + 1] +
		board[x][y + 1] +
		board[x - 1][y + 1] - 8 * '0');*/
}

当排查的位置为x,y时,根据上图可知周围八个格子的坐标,计算周围雷的个数,当这八个位置每有一个雷时我们就加一。

😊书写展开一片非雷区域的函数

//递归,展开一片区域的函数
void OpenArea(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col,int x, int y)
{
	int count = get_mine_count(mine,ROW,COL, x, y);
	if (count == 0) 
	{
		show[x][y] = ' ';
		for (int i = x - 1; i <= x + 1; i++) 
		{
			for (int j = y - 1; j <= y + 1; j++) 
			{
				if (show[i][j] == '*' && x >= 1 && x <= row && y >= 1 && y <= col) 
				{
					OpenArea(mine, show,ROW,COL, i, j);
				}
			}
		}
	}
	else 
	{
		show[x][y] = count + '0';
	}
}

 因为需要对存储雷位置的棋盘和显示棋盘信息的棋盘进行操作,所以形参中需要两个棋盘。

当周围没有雷时,将此位置的show棋盘上显示为 ‘  ’ (空格),同时对周围八个坐标位置的格子进行判断,如果这些坐标(合理)在9*9的棋盘上,则再次对他们进行同样的判断,此时就需要利用递归的思想(即再次调用展开一片非雷区域的函数);当周围有雷,这时就需要统计雷的个数,并将雷的个数显示在show棋盘上。

注意:

因为show棋盘上存储的是字符(char),而统计的数是整型,所以我们需要将整型转换为字符型(即让数字加上字符‘0’)。

😊书写计算非雷和非标记的位置个数

//计算非雷和非标记的位置个数
int get_win(char board[ROWS][COLS], int row, int col)
{
	int win = 0;
	for(int i=1;i<=row;i++)
		for (int j = 1; j <= col; j++)
		{
			if (board[i][j]!='*'&&board[i][j]!='!')
				win++;
		}
	return win;
}

该函数作用是为了判断游戏输赢。 

😊书写排查雷的函数

//排雷的函数
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	 //1.输入排查的坐标
     //2.检查该坐标处是不是雷
	 //(1) 是雷   - 很遗憾,你被炸死了 - 游戏结束
	 //(2) 不是雷 - 统计坐标周围有几个雷 - 存储排查雷的信息到show数组,游戏继续
	int x = 0;
	int y = 0;
	int win = 0;
	int select = 0;

	while (win < row * col - EASY_COUNT)
	{
		printf("请选择:1.排查雷 2.标记雷\t");
		scanf("%d", &select);
		if (select == 1) 
		{
			printf("请输入要排查雷的坐标:>");
			scanf("%d %d", &x, &y);
			//判断坐标合法性
			if (x >= 1 && x <= row && y >= 1 && y <= col) 
			{
				if (show[x][y] == '*')
				{
					if (mine[x][y] == '1')
					{
						printf("\n\n很遗憾,你被炸死了!\n");
						printf("雷的分布情况,其中('1'表示雷):\n");
						DisplayBoard(mine, ROW, COL);
						break;
					}
					else
					{
						OpenArea(mine, show,ROW,COL, x, y);
						//显示排查出的信息
						DisplayBoard(show, ROW, COL);
						//计算已经排出的非雷位置的个数
						win = get_win(show, ROW, COL);
						//win++;
					}
				}
				else
				{
					printf("该位置已被排查过,请重新输入!\n");
				}
			}
			else
			{
				printf("坐标不合法,请重新输入!\n");
			}
		}
		else if (select == 2)
		{
			printf("请输入要标记的坐标:>");
			scanf("%d %d", &x, &y);
			//判断坐标合法性
			if (x >= 1 && x <= row && y >= 1 && y <= col) 
			{
				if (show[x][y] == '*')
				{
					show[x][y] = '!';
					DisplayBoard(show, ROW, COL);
				}
				else if(show[x][y]=='!')
				{
					printf("该位置已被标记,请重新选择!\n");
				}
				else
				{
					printf("该位置不能标记,请重新选择!\n");
				}
			}
			else 
			{
				printf("坐标不合法,请重新输入!\n");
			}
		}
		else 
		{
			printf("输入有误,请重新输入!\n");
		}
		
		printf("win=%d\n", win);
	}
	if (win == row * col - EASY_COUNT) 
	{
		printf("\n恭喜你,排雷成功!\n");
		printf("雷的分布情况,其中('1'表示雷):\n");
		DisplayBoard(mine, ROW, COL);
	}
}

//基础功能+拓展功能
//1.标记功能(用'!')
//2.展开一片区域的功能(使用递归)      
//*当排查下x,y坐标时:(1)该坐标不是雷  (2)该坐标周围没有雷  (3)该坐标没有被排查过

👀如何排查雷? 

基本思路:

                1.输入排查的坐标
                2.检查该坐标处是不是雷
                  ❌ 是雷   - 很遗憾,你被炸死了 - 游戏结束
                  ✔️不是雷 - 统计坐标周围有几个雷 - 存储排查雷的信息到show数组,游戏继续

     		printf("请输入要排查雷的坐标:>");
			scanf("%d %d", &x, &y);
			//判断坐标合法性
			if (x >= 1 && x <= row && y >= 1 && y <= col) 
			{
				if (show[x][y] == '*')
				{
					if (mine[x][y] == '1')
					{
						printf("\n\n很遗憾,你被炸死了!\n");
						printf("雷的分布情况,其中('1'表示雷):\n");
						DisplayBoard(mine, ROW, COL);
						break;
					}
					else
					{
						OpenArea(mine, show,ROW,COL, x, y);
						//显示排查出的信息
						DisplayBoard(show, ROW, COL);
						//计算已经排出的非雷位置的个数
						win = get_win(show, ROW, COL);
						//win++;
					}
				}
				else
				{
					printf("该位置已被排查过,请重新输入!\n");
				}
			}
			else
			{
				printf("坐标不合法,请重新输入!\n");
			}
		

👀如何标记雷? 

因为排查雷和标记雷是两个不同的过程,所以这时我们需要通过使用if-else语句来选择排查雷还是标记雷,标记雷的位置用‘ !’来表示。

//printf("请选择:1.排查雷 2.标记雷\t");
//scanf("%d", &select);
else if (select == 2)
		{
			printf("请输入要标记的坐标:>");
			scanf("%d %d", &x, &y);
			//判断坐标合法性
			if (x >= 1 && x <= row && y >= 1 && y <= col) 
			{
				if (show[x][y] == '*')
				{
					show[x][y] = '!';
					DisplayBoard(show, ROW, COL);
				}
				else if(show[x][y]=='!')
				{
					printf("该位置已被标记,请重新选择!\n");
				}
				else
				{
					printf("该位置不能标记,请重新选择!\n");
				}
			}
			else 
			{
				printf("坐标不合法,请重新输入!\n");
			}
		}
		else 
		{
			printf("输入有误,请重新输入!\n");
		}
		
		//printf("win=%d\n", win);
	}

👀 如何判断输赢?

if (win == row * col - EASY_COUNT) 
	{
		printf("\n恭喜你,排雷成功!\n");
		printf("雷的分布情况,其中('1'表示雷):\n");
		DisplayBoard(mine, ROW, COL);
	}

当show棋盘上非雷位置和非标记位置个数mine棋盘上‘0’的个数(即非雷个数)相等时,打印“恭喜你,排雷成功!”,并打印mine棋盘的雷的分布情况。若不等于则继续进行排雷或标记雷的步骤。

打印结果: 

 

 3.game.h文件

😄需要使用的头文件

#include<stdio.h>
#include<stdlib.h>
#include<time.h>;

😄定义棋盘行列

#define ROW 9
#define COL 9

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

打印棋盘信息时,使用9*9的棋盘,在进行初始化,设置雷,排查雷,标记雷等操作时使用11*11的棋盘。

😄定义雷的个数

#define EASY_COUNT 10

😄初始化棋盘

//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set);

😄打印棋盘

//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);

😄布置雷

//布置雷
void Setmine(char board[ROWS][COLS],int row,int col);

😄排查雷

//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS],int row,int col);

四、总代码 

注意:此代码分为三个部分的代码

(一)game.h文件

#include<stdio.h>
#include<stdlib.h>
#include<time.h>;

#define ROW 9
#define COL 9

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

#define EASY_COUNT 10
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set);
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//布置雷
void Setmine(char board[ROWS][COLS],int row,int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS],int row,int col);

(二)game.c文件 

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set)
{
	int i = 0;
	int j = 0;
	for(i=0;i<rows;i++)
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
}
//打印棋盘信息
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("------扫雷游戏------\n");
	printf("════════════════════\n");//美化棋盘
	for (j = 0; j <= col; j++)
	{
		printf("%d|", j);
	}
	printf("\n-|══════════════════");//美化棋盘
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d|", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c|", board[i][j]);
		}
		printf("\n");
	}
	printf("════════════════════\n");//美化棋盘
	printf("------扫雷游戏------\n\n");
}
//设置雷的函数
void Setmine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	//行1-9  列1-9
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;
		}
	}
}
//统计周围雷数的函数
int get_mine_count(char board[ROWS][COLS], int row, int col,int x,int y)
{
	int count = 0;
	for(int i=-1;i<=1;i++)
		for (int j = -1; j <= 1; j++)
		{
			if (board[x + i][y + j] == '1')
				count++;
		}
	return count;

	/*return (board[x - 1][y] +
		board[x - 1][y - 1] +
		board[x][y - 1] +
		board[x + 1][y - 1] +
		board[x + 1][y] +
		board[x + 1][y + 1] +
		board[x][y + 1] +
		board[x - 1][y + 1] - 8 * '0');*/
}

//递归,展开一片区域的函数
void OpenArea(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col,int x, int y)
{
	int count = get_mine_count(mine,ROW,COL, x, y);
	if (count == 0) 
	{
		show[x][y] = ' ';
		for (int i = x - 1; i <= x + 1; i++) 
		{
			for (int j = y - 1; j <= y + 1; j++) 
			{
				if (show[i][j] == '*' && x >= 1 && x <= row && y >= 1 && y <= col) 
				{
					OpenArea(mine, show,ROW,COL, i, j);
				}
			}
		}
	}
	else 
	{
		show[x][y] = count + '0';
	}
}

// 计算非雷和非标记的位置个数
int get_win(char board[ROWS][COLS], int row, int col)
{
	int win = 0;
	for(int i=1;i<=row;i++)
		for (int j = 1; j <= col; j++)
		{
			if (board[i][j]!='*'&&board[i][j]!='!')
				win++;
		}
	return win;
}

//排雷的函数
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	 //1.输入排查的坐标
     //2.检查该坐标处是不是雷
	 //(1) 是雷   - 很遗憾,你被炸死了 - 游戏结束
	 //(2) 不是雷 - 统计坐标周围有几个雷 - 存储排查雷的信息到show数组,游戏继续
	int x = 0;
	int y = 0;
	int win = 0;
	int select = 0;

	while (win < row * col - EASY_COUNT)
	{
		printf("请选择:1.排查雷 2.标记雷\t");
		scanf("%d", &select);
		if (select == 1) 
		{
			printf("请输入要排查雷的坐标:>");
			scanf("%d %d", &x, &y);
			//判断坐标合法性
			if (x >= 1 && x <= row && y >= 1 && y <= col) 
			{
				if (show[x][y] == '*')
				{
					if (mine[x][y] == '1')
					{
						printf("\n\n很遗憾,你被炸死了!\n");
						printf("雷的分布情况,其中('1'表示雷):\n");
						DisplayBoard(mine, ROW, COL);
						break;
					}
					else
					{
						OpenArea(mine, show,ROW,COL, x, y);
						//显示排查出的信息
						DisplayBoard(show, ROW, COL);
						//计算已经排出的非雷位置的个数
						win = get_win(show, ROW, COL);
						//win++;
					}
				}
				else
				{
					printf("该位置已被排查过,请重新输入!\n");
				}
			}
			else
			{
				printf("坐标不合法,请重新输入!\n");
			}
		}
		else if (select == 2)
		{
			printf("请输入要标记的坐标:>");
			scanf("%d %d", &x, &y);
			//判断坐标合法性
			if (x >= 1 && x <= row && y >= 1 && y <= col) 
			{
				if (show[x][y] == '*')
				{
					show[x][y] = '!';
					DisplayBoard(show, ROW, COL);
				}
				else if(show[x][y]=='!')
				{
					printf("该位置已被标记,请重新选择!\n");
				}
				else
				{
					printf("该位置不能标记,请重新选择!\n");
				}
			}
			else 
			{
				printf("坐标不合法,请重新输入!\n");
			}
		}
		else 
		{
			printf("输入有误,请重新输入!\n");
		}
		
		//printf("win=%d\n", win);
	}
	if (win == row * col - EASY_COUNT) 
	{
		printf("\n恭喜你,排雷成功!\n");
		printf("雷的分布情况,其中('1'表示雷):\n");
		DisplayBoard(mine, ROW, COL);
	}
}

//基础功能+拓展功能
//1.标记功能(用'!')
//2.展开一片区域的功能(使用递归)      
//*当排查下x,y坐标时:(1)该坐标不是雷  (2)该坐标周围没有雷  (3)该坐标没有被排查过

(三)test.c文件

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"

void menu()
{
	printf("\t\t\t\t\t\t\t\t\t\t\t\n");
	printf("*********************\n");
	printf("*****  1. play  *****\n");
	printf("*****  0. exit  *****\n");
	printf("*********************\n");
}

void game()
{
	char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息
	char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息
	//初始化数组的内容为指定内容
	//mine数组在没有布置雷的时候,都是‘0’
	InitBoard(mine, ROWS, COLS,'0');
	//show数组在没有排查雷的时候都是‘*’
	InitBoard(show, ROWS, COLS, '*'); 


	//设置雷
	Setmine(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);
	//DisplayBoard(mine, ROW, COL);
	//排查雷
	FindMine(mine, show, ROW, COL);

}


int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:system("cls"); game();
			break;
		case 0:printf("退出游戏\n");
			break;
		default:printf("选择错误,请重新输入!\n");
			break;
		}
	} while (input);
	return 0;
}

五、效果展示

扫雷游戏展示

扫雷游戏展示

🔥好了, 今天的内容就分享到这里了。愿这篇博客能够为您带来新的思考和启示。感谢您的耐心阅读和支持。无论在人生的道路上遇到怎样的困难和挑战,记住相信自己的力量,努力前行。期待与您共同探索更多精彩的内容。再次感谢!

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

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

相关文章

SpringBoot 使用前缀树实现敏感词过滤

文章目录 前缀树介绍节点初始化前缀树添加敏感词删除敏感词敏感词过滤代码实现 前缀树介绍 前缀树&#xff08;Trie&#xff09;&#xff0c;也称为字典树或前缀字典树&#xff0c;是一种特殊的多叉树数据结构。它用于高效地存储和检索字符串集合。以下是前缀树的常见数据结构…

verilog实现led闪烁

文章目录 verilog实现led闪烁一、介绍二、代码三、仿真代码四、仿真结果五、总结 verilog实现led闪烁 一、介绍 使用verilog实现代码&#xff0c;实现led闪烁&#xff0c;每间隔200ms进行切换led灯 二、代码 module led (input wire clk,input wire rstn,output wire[3:0] …

深入解析向量数据库:定义、原理和应用的全面指南

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

C++智能指针(3/3)

目录 上一节内容 share_ptr用法 share_ptr指针可以用于上一节所说的错误 例子&#xff08;类定义&#xff09; 主函数代码 执行的结果 解释说明 share_ptr 相关构造 空的share指针可以指向其他相同类型的变量来进行托管 可以shared_ptr< T > sp2(new T())也可以s…

RocketMQ高阶使用

RocketMQ高阶使用 1. 流程 2. 探讨功能点 RocketMQ的顺序消息消息投递策略消息保障 3. 顺序消息 3.1 顺序类型 3.1.1 无序消息 无序消息也指普通的消息&#xff0c;Producer 只管发送消息&#xff0c;Consumer 只管接收消息&#xff0c;至于消息和消息之间的顺序并没有保证…

macOS搭建C++开发环境CLion

首先我是一个java开发者&#xff0c;最近对C产生点兴趣。想开发点C程序玩一玩。 下载IDE 本人是java开发者&#xff0c;习惯使用IDEA了。所以也下载jetbrains的C开发工具:clion 下载地址&#xff1a; https://www.jetbrains.com/clion/download/#sectionmac Hello world Fi…

利用ArcGIS Pro制作三维效果图

1、新建工程 打开Arcgispro,新建工程,这里我们要用到的模板为全局场景。 2、添加数据 这里添加的数据需要有一个字段内容是数值的,这个字段也是接下来要进行拉伸的字段。 3、高度拉伸 数据添加进来后,如下图所示,这时图层处于2D图层里。 这时我们点中该图层,回到菜单栏…

微服务系列文章 之SpringBoot之定时任务详解

序言 使用SpringBoot创建定时任务非常简单&#xff0c;目前主要有以下三种创建方式&#xff1a; 一、基于注解(Scheduled)二、基于接口&#xff08;SchedulingConfigurer&#xff09; 前者相信大家都很熟悉&#xff0c;但是实际使用中我们往往想从数据库中读取指定时间来动态…

天眼使用指南--分析平台

#天眼分析平台 提供全面的溯源分析能力&#xff0c;涵盖图中模块。负责存储日志&#xff0c;分为三类&#xff0c;告警日志 告警日志&#xff1a;来自探针和沙箱的告警&#xff0c;探针的告警可以记录双向完整对话&#xff0c;如果网络流量中没有恶意信息&#xff0c;就会储存…

windows Server 2008 R2服务器IIS环境启用TLS 1.2

windows Server 2008 R2服务器IIS环境启用TLS 1.2&#xff0c;配置TLS1.2 分为2步, 添加TLS配置和禁用老的SSL版本&#xff0c;提供两种方法, 选择其中一种就行了&#xff0c;手动设置 打开注册表&#xff0c;运行regedit&#xff0c;找到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentCo…

【hadoop】在linux上设置Hadoop的环境变量

设置Hadoop的环境变量 解压压缩包编辑环境变量激活环境变量 解压压缩包 使用下面命令对hadoop的压缩包进行解压 tar -zxvf hadoop-2.7.3.tar.gz -C ~/training/编辑环境变量 在linux中&#xff0c;~/.bash_profile文件是设置环境变量的文件&#xff0c;我们使用vi进行编辑。…

Verdi之波形展示nWave

6.nWave 6.1 添加波形文件 1.打开nWave界面&#xff0c;具体操作如下&#xff1a; 2.正式添加波形&#xff0c;使用快捷键G或者点击以下图标&#xff0c;选择需要的信号。 也可以在 n Trace中选中信号后&#xff0c;鼠标中键拖拽&#xff0c;或者ctrlw进行添加&#xff1b; 6…

Dreamweaver批量替换所有超链接替换成#

需求&#xff1a;想要将页面所有链接地址替换为#。 方法一 CTRLF打开“查找和替换”&#xff0c;勾选“使用正则表达式” 查找 href"([\s\S]*?)" 替换为 href"#" 副作用&#xff1a;样式表链接地址也会被替换为#&#xff0c;需提前备份。 方法二 也可以查…

CAN总线(二)CAN协议的帧格式(一文看懂CAN的报文结构)

如果只是使用CAN进行CAN通讯,可以粗略看下以下内容,主要了解下数据字段,但了解一下其他内容有助于使用CAN通讯。 一、CAN总线协议规范 CAN报文有两种不同的格式:标准格式和扩展格式,前者的标志符长度是11位,而后者的标志符长度可达29位。 CAN协议的2.0A版本规定CAN控制…

Git -> 创建第一个本地repo

创建一个本地仓库及提交文件 打开Git Bash执行以下命令 // 切换至d盘 cd d: // 新建文件夹 mkdir my_first_local_repo // 切换至新建文件夹 cd my_first_local_repo假设my_first_local_repo文件夹下有以下文件 初始化git仓库 // 在当前文件夹初始化git仓库 git init.gi…

【stable diffusion】保姆级入门课程-Stable diffusion(SD)介绍与安装

目录 0.学前准备 1.什么是AI绘画 2.当前主流的AI绘画工具 3.什么是SD(stable diffusion) 4.SD能做什么 1.文生图 2.图生图 3.AI换模特&#xff0c;背景 5.使用stable diffusion配置要求 6.环境配置与安装 需要注意的地方&#xff1a; 扩展知识&#xff1a; 1.pyth…

Linux学习之环境变量配置文件

配置文件的执行先后顺序如下&#xff1a; /etc/profile $HOME/.bash_profile $HOME/.bashrc /etc/bashrc vim /etc/profile&#xff0c;把echo "/etc/profile"写到第一行&#xff0c;head -n 1 /etc/profile看一下/etc/profile里边第一行内容。 vim $HOME/.bash_pr…

工作:三菱PLC之CC-Link IE Field Network通讯知识及应用

工作&#xff1a;三菱PLC之CC-Link IE Field Network通讯知识及应用 一、理论 1. 简介连接 CC-LINK-IE通讯分别有 CC-Link IE TSN&#xff0c;CC-Link IE Control Network&#xff0c;CC-Link IE Field Network&#xff0c;CC-Link IE Field Network Basic几种形式&#xff…

38译码器

文章目录 38译码器一、38译码器介绍二、项目代码三、仿真代码四、仿真结果 五、总结 38译码器 一、38译码器介绍 38译码器是一种常用的逻辑电路元件&#xff0c;用于将一个3位二进制输入编码转换成8个输出信号之一。它具有多个输入引脚和多个输出引脚。 通常&#xff0c;38译…

Linux下Lua和C++交互

前言 lua&#xff08;wiki 中文 官方社区&#xff1a;lua-users&#xff09;是一门开源、简明、可扩展且高效的弱类型解释型脚本语言。 由于其实现遵循C标准&#xff0c;它几乎能在所有的平台&#xff08;windows、linux、MacOS、Android、iOS、PlayStation、XBox、wii等&…