IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言:扫雷 -> 正文阅读

[C++知识库]C语言:扫雷

? ? ? ?继井字棋之后,扫雷便是跨不过去的坎。个人感觉扫雷比井字棋更加容易(可能是学习井字棋时有了一定基础),两个小游戏的实现代码比较相似,甚至test函数几乎一样。话不多说开始今天扫雷的学习吧。?

目录

1.主函数?

2.test函数

3.game函数(1)

4.1.InitBoard函数用于定义数组

4.2.SetMine函数用于设置雷

4.3.DisplayBoard函数用于打印棋盘的情况

4.4.FindMine函数用于找雷?

4.5.get_mine_count函数计算输入的坐标周围有多少雷

5.game函数(2)?


1.主函数?

?主函数的实现非常简单,这样也有助于我们融合自己写的东西。

int main()
{
	test();
	return 0;
}

2.test函数

test函数的实现和井字棋的test函数几乎一样,若有不清楚的地方可看之前的文章

void test()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏");
			break;
		default:
			printf("选择错误,请重新选择");
			break;
		}
	} while (input);
}

?

3.game函数(1)

假设这个棋盘是9*9的棋盘,为了防止我们在计算边缘的空子,周围一圈有多少雷时月=越界,我们把整个棋盘上下左右各加1,变成ROWS 和COLS

?如上,红色棋盘是显示出来的棋盘,但如果计算蓝色周围的炸弹数时,没有多出来的两行棋盘,那么会出现数组越界的情况。

接下来用一个数组(mine)记录雷、坐标、排雷情况等参数,而另外一个数组(show)用于显示输入的坐标和周边雷的情况。我们在game函数中对其初始化.

#define ROW 9
#define COL 9

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


void game()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

}

为什么这两个数组用的char类型呢,这里先放一张图,可以看到没揭露的坐标是*,而char类型正好满足这个排列。

?

4.1.InitBoard函数用于定义数组

我们先用一个InitBoard函数,在这个函数中我们传送数组名,行和列参数,和定义的符号

传输的行和列是大棋盘的行和列,为了防止越界

InitBoard(mine, ROWS, COLS, '0');

InitBoard(show, ROWS, COLS, '*');

?接收:

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

我们用一个set接收需要定义的值,然后在函数中把它每一个数都初始化成接收的set

4.2.SetMine函数用于设置雷

?传输:传输的行和列是玩家游戏的行和列

SetMine(mine, ROW, COL);

接收: (EASY_COUNT是雷的个数)


#define EASY_COUNT 10

void SetMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;

		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

思路很简单,用时间戳生成的随机数放到二维数组中代表雷,如果这个坐标没有雷('0'),那么就把'0'改成'1',循环往复直到雷的数字为0,便不再进入循环。

?

4.3.DisplayBoard函数用于打印棋盘的情况

传输:传输的行和列是玩家游戏的行和列

DisplayBoard(show, ROW, COL);

接收:

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;

	for (i = 0; i <= col; i++)//i从0开始,在棋盘的最左上角打印出来0正好对应行和列
	{
		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]);//这里用的%c是因为需要打印*出来
		}
		printf("\n");
	}
}

11*11的棋盘全部被定义好了,但打印出来的便是9*9的棋盘

至此,我们的棋盘和雷已经设置好了,只需要排雷即可

4.4.FindMine函数用于找雷?

?传输:可以看到这个函数传输了2个二维数组,行和列。

FindMine(mine, show, ROW, COL);

接收:(引用get_mine_count函数)

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)//当总格子减去雷的数字大于win时进行循环
	{

		printf("请输入要排查的坐标");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)//防止输入的坐标不正确
		{
			if (mine[x][y] == '1')//如果输入的坐标是'1',也就是SetMine中的雷时
			{
				printf("很遗憾你被炸死了\n");
				DisplayBoard(mine, row, col);//打印mine,让玩家可以清楚地看到雷的位置
				break;
			}
			else
			{
				int n = get_mine_count(mine, x, y);
				show[x][y] = n + '0';
//这里额外注意一下,初始化数组的时候我们用的char类型,定义的'1',并不是真正的1,我们需要加上一个48的ASCII值,也就是加上一个'0',就可以完成类型的转换。

				DisplayBoard(show, row, col);
				win++;
			}
		}
		else
		{
			printf("输入坐标非法,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)//排的雷的数量等于非雷格子的时候,就说明排雷成功
	{
		printf("恭喜你,排雷成功");
		DisplayBoard(mine, row, col);
	}
}

4.5.get_mine_count函数计算输入的坐标周围有多少雷

?如图,我们需要算出蓝色子周围的雷的个数。但是在mine数组中,没有雷是0,有雷是1,我们只要简单的算数字就能把雷的个数表示出来。只要最后减去8个'0'就行了。

static int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
return  mine[x - 1][y]     +
		mine[x - 1][y - 1] +
		mine[x]    [y - 1] +
		mine[x + 1][y - 1] +
		mine[x + 1][y]     +
		mine[x + 1][y + 1] +
		mine[x]    [y + 1] +
		mine[x - 1][y + 1] - 
        8 * '0';
}//该代码仅供美观,真实代码与该代码有出入

同时用一个static,保持return的值一只存在。

5.game函数(2)?

void game()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	InitBoard(mine, ROWS, COLS, '0');

	InitBoard(show, ROWS, COLS, '*');

	SetMine(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);

	FindMine(mine, show, ROW, COL);
}

至此,一个简易的扫雷就完成了。运用的思想并不复杂,仔细理解每一个函数的作用,注意细节,C语言实现的扫雷也并不困难。觉得难就多花些时间,一点一点进步吧。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-22 12:09:27  更:2021-11-22 12:09:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:07:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码