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语言扩展排雷(扫雷)


前言

几段话,让你用递归解决C语言扩展排雷,熟悉我的人都知道,我是一个善于将过程写的很详细的精通人性的男“讲师”。
在这里插入图片描述

今天给大家整个递归扩展排雷!


一、递归是什么?

程序调用自身的编程技巧称为递归。递归做为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
递归的主要思考方式就在于把大事化小(自己调用自己)

要编写一个函数要确定递归的两个条件

1. 递归结束的条件
2. 递归的调用的公式

二、如何使用递归将周围无雷的棋子排除?

1.递归和扫雷的关系

递归在扫雷中可以解决扩展排雷的问题,当用户排除掉一个棋子,该棋子周围没有雷,则展开,再从该九宫格依次排查,周围是否有雷,无雷则继续展开,有雷则输出周围有几颗雷。我们不必去考虑递归到底执行了几次,最主要的目的就是将问题简化。
当周围有雷,该坐标排查结束,继续排查其他坐标,递归的终止条件即为当排查坐标不为字符’0’(这里我定义为0,代表坐标不是雷)或该坐标被排查过(为*字符)则递归终止。

那么当排查坐标为字符’0’且该坐标未被排查过,递归继续执行。

if (mine[i][j] == '0' && showboard[i][j] == '*')
{
	extendmine(mine, showboard, i, j);//递归函数
}

如果该条件成立,则执行递归。

这里函数中的i和j来不断递归等价于x和y。并求出该坐标周围九宫格范围内的雷数。

我们可以将这个递归函数的实现分为两个步骤:
1. 求出这个坐标周围的雷数,如果为0,则将其变为空白。
2. 排查在该坐标九宫格范围内的其他坐标。(这里我用了循环,也可以使用很多个if语句来实现)

2.代码实现

代码如下(示例):

void extendmine(char mine[ROWS][COLS], char showboard[ROWS][COLS], int x, int y)
{
	int n = 0;
	n = howmanymine(mine, x, y);
	if (n == 0)
	{
		showboard[x][y] = ' ';//如果周围没有雷,将中心赋值为空格
		int i = 0;
		int j = 0;
		for (i = x - 1; i <= x + 1 && i >= 0 && i <= ROW; i++)
		{
			for (j = y - 1; j <= y + 1 && j >= 0 && j <= COL; j++)
			{
				if (i == x && j == y)//跳出(x,y)的位置
				{
					continue;
				}
				if (mine[i][j] == '0' && showboard[i][j] == '*')//坐标自身不是雷且还是初始化字符,进入递归再次扩展排雷
				{
					extendmine(mine, showboard, i, j);//递归函数
				}
			}
		}
	}
	else
		showboard[x][y] = n + '0';//如果附近有雷,展示雷的个数
}

那么扫雷游戏中较难的部分——如何使用递归扩展排雷就可以解决了。
实现效果如下
在这里插入图片描述


附录

主程序.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void menu()
{
	printf("********************************\n");
	printf("*************1.paly*************\n");
	printf("*************2.exit*************\n");
	printf("********************************\n");
}
void game()
{
	char mine[ROWS][COLS] = { 0 };//布置雷的信息
	char showboard[ROWS][COLS] = { 0 };//排查出雷的信息
	init(mine, ROWS, COLS, '0');//初始化函数
	init(showboard, ROWS, COLS, '*');
	setmine(mine, ROW, COL);
	display(mine, ROW, COL);
	display(showboard, ROW, COL);
	playgame(mine,showboard,ROW, COL);
}
int main()
{
	int input = 0;
	srand((unsigned)time(NULL));
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
		}
	} while (input!=2);
}
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//初始化棋盘
void init(char showboard[ROWS][COLS], int rows, int cols,char c)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			showboard[i][j] = c;
		}
	}
}

//放置地雷

void setmine(char mine[ROWS][COLS], int row, int col)
{
	int x, y = 0;
	int count = easy_game;
	while (count)
	{
		x = rand() % row + 1;
		y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}
//打印棋盘
void display(char showboard[ROWS][COLS], int row, int col)
{
	int i = 0;
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		int j = 0;
		for (j = 1; j <= col; j++)
		{
			printf("%c ",showboard[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}


//求出该坐标周围有多少雷
int howmanymine(char mine[ROWS][COLS], int x, int y)
{
	int i, j = 0;
	int count = 0;
	for (i = x - 1; i <= x + 1; i++)//x-1<=i<=x+1
	{
		for (j = y - 1; j <= y + 1; j++)//y-1<=i<=y+1
		{
			count += mine[i][j];
		}
	}
	count = count - mine[x][y] - 8 * '0';//转换为字符数字
	return count;
}

//空白扩展
void extendmine(char mine[ROWS][COLS], char showboard[ROWS][COLS], int x, int y)
{
	int n = 0;
	n = howmanymine(mine, x, y);
	if (n == 0)
	{
		showboard[x][y] = ' ';//如果周围没有雷,将中心赋值为空格
		int i = 0;
		int j = 0;
		for (i = x - 1; i <= x + 1 && i >= 0 && i <= ROW; i++)
		{
			for (j = y - 1; j <= y + 1 && j >= 0 && j <= COL; j++)
			{
				if (i == x && j == y)//跳出(x,y)的位置
				{
					continue;
				}
				if (mine[i][j] == '0' && showboard[i][j] == '*')//坐标自身不是雷且还是初始化字符,进入递归再次扩展排雷
				{
					extendmine(mine, showboard, i, j);//递归函数
				}
			}
		}
	}
	else
		showboard[x][y] = n + '0';//如果附近有雷,展示雷的个数
}
//判断是否获胜
int is_win(char showboard[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	int count = 0;
	for (i = 1; i <= row; i++)
	{
		for (j = 1; j <= col; j++)
		{
			if (showboard[i][j] == '*')
			{
				count++;
			}
		}
	}
	return count;
}

//主体程序
void playgame(char mine[ROWS][COLS], char showboard[ROWS][COLS], int row, int col)
{
	int x, y = 0;
	int n = 0;//判断循环是否继续
	while (1)
	{
		printf("请输入你要排雷的坐标");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("你被炸死了,游戏结束!\n");
				display(mine, row, col);
				break;
			}
			else
			{
				int count = howmanymine(mine, x, y);
				showboard[x][y] = count + '0';
				extendmine(mine, showboard, x, y);
				display(showboard, row, col);
				n = is_win(showboard, row, col);
				if (n == easy_game)
				{
					printf("恭喜你排雷成功!");
					display(mine, row, col);
					break;
				}
			}
		}
		else
		{
			printf("输入错误,请重新输入");
		}
	}
}
game.h
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS ROW+2
#define easy_game 9
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
void init(char mine[ROWS][COLS], int rows, int cols,char c);
void setmine(char mine[ROWS][COLS], int row, int col);
void display(char showboard[ROWS][COLS], int row, int col);
void playgame(char mine[ROWS][COLS],char showboard[ROWS][COLS],int row, int col);

在这里插入图片描述

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

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