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语言版——老妈子版讲解

大家好,即三子棋后一款游戏——扫雷,这个游戏就比三子棋可玩性高很多了,相对应的有个算法会比较难想到,但是跟三子棋的游戏框架很像。废话少说,接下来我们就开始分析扫雷如何实现吧。

目录

一、棋盘的初始化

二、棋盘的打印

三、存放地雷。

四、查找雷

递归展开

五、鉴定排雷状况,结束排雷


事先准备和用户交互画面和三子棋是相同的,我就不复制粘贴了,可以去看我的上一篇博客,这里直接说这两步之后的程序。

一、棋盘的初始化

我们这里用使用两个棋盘,一个是我们安放地雷的棋盘,一个是用户用来排雷的棋盘,这样分开设置有利于我们设计游戏

我们要将两个棋盘设置为11*11,但只显示1-10行、列的数据,方便我们排查雷。初始化代码如下:

char mine[ROW][COL];
	char show[ROW][COL];
	//初始化棋盘mine数组全初始化0,shou数组全初始化为*
	inti_board(mine, '0');
	inti_board(show, '*');

我们将初始化函数设置为,传什么就赋值什么,这个还是比较好实现的,11*11的数组全部附上就行了

//数组初始化
void inti_board(char board[ROW][COL], char c)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < ROW; i++)
	{
        for (j = 0; j < COL; j++)
		{
			board[i][j] = c;
		}
	}
}

二、棋盘的打印

我这里打印的棋盘是我设计过的,容易对应坐标,打印其实没什么,主要是个人意愿?

但是这个打印要做到传入show数组则打印用户界面,传入mine数组则打印开发页面

这里我放上我的打印函数,因为这个不是扫雷的重点。

void print_board(char board[ROW][COL])
{
	printf("***********************************************\n\n");
	int i = 0;
	int j = 0;
	for (i = 1; i <= row; i++)
	{
		if (i == 1)
			printf("   ");
      printf("  %d ", i);
	}
	printf("\n");
	printf("    ");
	for (i = 1; i <= row; i++)
	{
		if (i<row)
		printf("----");
		if (i == row)
			printf("---");
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf(" %d ", i);
		for (j = 1; j <=col; j++)
		{
			printf("|");
			printf(" %c ", board[i][j]);
			if (j == col)printf("|");
		}
		printf("\n");
		printf("    ");
		for (j = 1; j <= col; j++)
		{
			if (j<col)
			printf("----");
			if (j == col)
				printf("---");
		}
		printf("\n");
	}
	printf("\n");
	printf("***********************************************\n");
	printf("\n");
}

三、存放地雷。

这个跟三子棋电脑走子是差不多的,也是用rand函数生成10对坐标来插入雷放到mine数组中,也没什么太大的难度

//安置雷
void set_bomb(char board[ROW][COL])
{
	int x;
	int y;
	int count = 10;//count是安放雷的数量
	while (count)
	{
		x = rand() % col;
		y = rand() % row;
		if (x >= 1 && x <= 9 && y >= 1 && y <= 9 && board[x][y] == '0')
		{//位子没有被占用,而且是显示的棋盘内
			count --;
			board[x][y] = '1'; //放1代表是雷
		}
	}
}

四、查找雷

查找雷是我们今天的重点,我们要确定好好方向和流程:

1、用户输入坐标(设置循环判断坐标的合法性)

2、对坐标进行判断

? ? ?2.1检查这个坐标的mine数组是不是雷,是雷就打印一下棋盘然后直接return;游戏结束

? ? ?2.2不是雷,我们进行判断周围是不是雷,并将检查到的雷的数量进行返回,显示在show数组用户输入的位子上(并进行递归展开),游戏继续。

(这里给大家一个小思路,如果想对雷进行标记,可以输入0 0,输入0 0就进入标记页面,再输入要标记坐标,将show数组上对应的坐标进行更改就行了)

?

1.1和2.1还是很简单的,我们重点来实现2.2

排查不是雷坐标周围的雷数

我们将用户输入的坐标传入到排查统计雷的函数中,思路是:

因为我们将雷设置为1,非雷设置为0,所以我们将9个坐标的值全部相加,再减去8个‘0’的值,就可以算出要返回的值了,因为0的ascii码值为48,1的ascii码值为49,我们只要返回48,就是返回’0‘,表示周围一圈也是无雷,返回49,就是返回'1',表示1个雷,以此类推。并可以把返回的值放到show数组对应的坐标上,这样下次显示的时候也就显示出来了。

代码实现如下:

int count_mine(char mine[ROW][COL], int x, int y)
{
	int sum = 0;
	for (int i = -1; i <= 1; i++)
		for (int j = -1; j <= 1; j++)
			sum += mine[x - i][y - j];
	return sum - 8 * 48;
}

递归展开

一圈都不是雷

这时我们就要思考,如果周围一圈全不是雷,那是不是应该要展开一片呢,我们可以怎么设定这个一圈都展开的递归公式呢?

先来看看这个递归应该如何设计:

?return的地方都是需要用if判断的,而这些子坐标是什么意思呢,接下来看一下的这个图,这8个子坐标就代表着母坐标向8个方向展开。

其实就是他周围的8个小方块啦,坐标也是很好写的,代码如下:

//递归展开
void spread_board(char mine[ROW][COL], char show[ROW][COL], int x, int y)
{		//排查一圈,发现有雷,将show上的位子设为雷的个数
	int i = count_mine(mine, x, y);
	if (i != '0')
	{
		show[x][y] = i;
		return;
	}
	//排查一圈,找到起点空格,停止.
	if (show[x][y] == ' ')
	{
		return;
	}
	//超出边界
	if (x <= 0 || x > row || y <= 0 || y > col)
		return;
	//排查一圈,发现没有雷,将show对应的位子设为空格
	show[x][y] = ' ';
	/*print_board(show);*/
	spread_board(mine, show, x + 1, y);
	spread_board(mine, show, x + 1, y - 1);
	spread_board(mine, show, x + 1, y + 1);
	spread_board(mine, show, x, y - 1);
	spread_board(mine, show, x, y + 1);
	spread_board(mine, show, x - 1, y - 1);
	spread_board(mine, show, x - 1, y + 1);
	spread_board(mine, show, x - 1, y);
}

接下来是输入排雷函数的代码:

//查找雷
void lookup_bomb(char show[ROW][COL], char mine[ROW][COL])
{
	int x;
	int y;
	char count=0;
	while (1)
	{
		printf("请输入排查的坐标或标记:\n");
        scanf("%d %d", &x, &y);
		while (1)
		{
        if (x == y && x == 0)
		{
			printf("请输入坐标来标记:\n");
			scanf("%d %d", &x, &y);
			show[x][y] = '@';
			print_board(show);
			printf("请输入排查的坐标或标记:\n");
			scanf("%d %d", &x, &y);
		}
		if (0 != y && x != 0)
			break; 
		}
		
		 if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
		 {
			 if (mine[x][y] == '1')
			 {
				 system("cls");
				 printf("sorry,您被炸死了\n雷的分布如下:\n");
				 print_board(mine);
				 sign = 2;
				 return;
			 }
			 else
			 {
				 //查找该坐标周围的有多少雷
				 count = count_mine(mine, x, y);
				 if (count == '0')
				 {//统计周围没有雷,开始递归展开					 
					 spread_board(mine,show, x, y);
				 }
				 if (count != '0')
				 show[x][y] = count;
				 break ;
			 }

		 }
		 else
		 {
           printf("输入有误,请重新输入:\n");
		 }
			 
	}
}

五、鉴定排雷状况,结束排雷

最后就剩下一个收尾工作了,我的想法和大家的不同,我是检查show数组上星号(*)和标记号(@)的总和是不是等于10个来停止的。因为,玩家要是将shou数组上81个符号检查到10个,而且一直没踩雷跳出,就是玩家排到了最后的10个,就可以安全退出恭喜玩家了。而我又设置了一个全局变量sign,在玩家踩雷后就将sign改为0,这样game函数中如果判断sign为0,直接就中断了游戏,用户踩雷了。这就是我的想法排雷结束思路,当然我的想法不是最好的,甚至可能有BUG,大家可以对我的代码采取适当的借鉴。,代码如下:

//检查游戏结束
int inspect_game(char show[ROW][COL])
{
	int i = 0;
	int j = 0;
	int count=0;
	for (i=1;i<=row;i++)
		for (j = 1; j <= col; j++)
		{
			if (show[i][j] == '*'||show[i][j]=='@')
			{
				count++;
			}
		}
	if (count <= 10)
		return 1;
	return 0;
}

这样,扫雷游戏游戏就设计完了,会发现游戏间总体思路是大同小异的,扫雷也就递归展开那块有点难想到,但是多练习一下游戏设计,也有利于理清编程思路,增强编程能力。

下一篇博客我会放下3个文件的全部代码。

最后,看到这里,留个赞呗~~

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-25 10:24:21  更:2022-01-25 10:25:05 
 
开发: 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 8:31:11-

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