C语言学习—扫雷游戏:递归实现范围展开
·
目录
一、简易扫雷游戏的实现
二、递归展开
1、思路
在可输入的坐标范围内,输入坐标若不是地雷,则计算该地雷附近的地雷,若附近有地雷,则在该坐标输出地雷个数,若附近无地雷,则在该坐标输出空格,并在以该坐标为中心9x9的范围且字符为 "X" 的坐标进行递归展开
2、实现
1)获取雷数
//获取雷数
int ls(char Nsz[Nhang][Nlie], int x, int y)
{
int n = 0;//存放该坐标附近地雷个数
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
n += (Nsz[x + i][y + j] - '0');
}
}
}
2)递归展开
//递归展开
void dg(char Nsz[Nhang][Nlie],char Sz[Nhang][Nlie], int x, int y)
{
//限制递归条件
if ((x > 0 && x < Nhang) && (y > 0 && y < Nlie))
{
int k = ls(Nsz, x, y);//获取雷数
//如果周围无地雷,则递归展开
if (k == 0)
{
Sz[x][y] = ' ';//无地雷输入空格
for (int i = x - 1; i <= x + 1; i++)
{
for (int j = y - 1; j <= y + 1; j++)
{
//限制递归条件
if (Sz[i][j] == 'X')
{
dg(Nsz, Sz, i, j);
}
}
}
}
else//如果周围有地雷,则输入数字
{
Sz[x][y] = k +'0';
}
}
}
3)效果


三、游戏结束的判定
1、计算棋盘中未展开格子
//遍历数组,计算数组中还剩多少个X
int xn(char Sz[Nhang][Nlie])
{
int n = 0;
for (int i = 1; i <= Hang; i++)
{
for (int j = 1; j <= Lie; j++)
{
if (Sz[i][j] == 'X')
n++;
}
}
return n;
}
2、结束游戏
踩雷或未展开格子等于雷数结束游戏
//输入坐标、判断并输出
int x = 0, y = 0, n = 0;
while (n != DL)//通过计算棋盘上还剩多少个‘X’来决定是否继续循环
{
printf("请输入坐标(x,y):");
scanf("%d %d", &x, &y);
if ((x > 0 && x <= Hang) && (y > 0 && y <= Lie) && Nqp[x][y] != '1')
{
system("cls");//清屏
dg(Nqp,Sqp,x,y);//递归展开
print(Sqp);//打印棋盘
n = xn(Sqp);//计算棋盘上还剩多少个‘X’
}
else if((x > 0 && x <= Hang) && Nqp[x][y] == '1')//踩雷
{
printf("你死了。。。。。。\n游戏结束!!!\n");
return;
}
else
{
printf("输入错误,请重新输入!!!\n");
}
}
printf("排雷成功!!!\n游戏结束\n");
四、总代码
1、game.h:声明函数
#define Nhang Hang+2//内置行
#define Nlie Lie+2//内置列
#define DL 10//存放地雷的个数
#include<stdlib.h>
#include<time.h>
#include<stdio.h>
#include<Windows.h>
//打印菜单
void Dycd(void);
//初始化数组
void Csh(char Nsz[Nhang][Nlie], int nhang, int nlie, char zf);
//打印棋盘
void print(char Sz[Nhang][Nlie]);
//随机存放地雷
void Cfdl(char Sz[Nhang][Nlie]);
//获取雷数
int ls(char Nsz[Nhang][Nlie], int x, int y);
//遍历数组,计算数组中还剩多少个X
int xn(char Sz[Nhang][Nlie]);
//递归展开
void dg(char Nsz[Nhang][Nlie], char Sz[Nhang][Nlie], int x, int y);
2、 game.cpp:存放自定义函数
#include"game.h"
//打印菜单
void Dycd()
{
printf("|============================|\n");
printf("|--------1.开始游戏----------|\n");
printf("|--------0.退出游戏----------|\n");
printf("|============================|\n");
}
//初始化棋盘
void Csh(char Sz[Nhang][Nlie],int nhang,int nlie, char zf)
{
for (int x = 0; x < nhang; x++)
{
for (int y = 0; y < nlie; y++)
{
Sz[x][y] = zf;
}
}
}
//打印棋盘
void print(char Sz[Nhang][Nlie])
{
printf("========================================\n");
printf("=================扫雷===================\n");
printf("========================================\n");
for (int i = 0; i <= Hang; i++)
{
printf(" %d |", i);
}
printf("\n===|===|===|===|===|===|===|===|===|===|\n");
for (int x = 1; x <= Hang; x++)
{
printf(" %d |", x);
for (int y = 1; y <= Lie;y++)
{
printf(" %c |", Sz[x][y]);
}
printf("\n===|---|---|---|---|---|---|---|---|---|\n");
}
}
//随机存放地雷
void Cfdl(char Sz[Nhang][Nlie])
{
int n = DL;
while (n)
{
//生成地雷的随机坐标
int x = rand() % Hang + 1;
int y = rand() % Lie + 1;
//将地雷存放在内置棋盘里,并判断生成的随机坐标是否重合
if (Sz[x][y] != '1')
{
Sz[x][y] = '1';
n--;
}
}
}
//获取雷数
int ls(char Nsz[Nhang][Nlie], int x, int y)
{
int n = 0;//存放该坐标附近地雷个数
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
n += (Nsz[x + i][y + j] - '0');
}
}
return n;
}
//遍历数组,计算数组中还剩多少个X
int xn(char Sz[Nhang][Nlie])
{
int n = 0;
for (int i = 1; i <= Hang; i++)
{
for (int j = 1; j <= Lie; j++)
{
if (Sz[i][j] == 'X')
n++;
}
}
return n;
}
//递归展开
void dg(char Nsz[Nhang][Nlie],char Sz[Nhang][Nlie], int x, int y)
{
//限制递归条件
if ((x > 0 && x < Nhang) && (y > 0 && y < Nlie))
{
int k = ls(Nsz, x, y);//获取雷数
//如果周围无地雷,则递归展开
if (k == 0)
{
Sz[x][y] = ' ';//无地雷输入空格
for (int i = x - 1; i <= x + 1; i++)
{
for (int j = y - 1; j <= y + 1; j++)
{
//限制递归条件
if (Sz[i][j] == 'X')
{
dg(Nsz, Sz, i, j);
}
}
}
}
else//如果周围有地雷,则输入数字
{
Sz[x][y] = k +'0';
}
}
}
3、扫雷.cpp:实现游戏
#include"game.h"
//扫雷游戏
void game()
{
//初始化随机数生成器
srand((unsigned int)time(NULL));
//内置棋盘
char Nqp[Nhang][Nlie] = { 0 };
//存放内置棋盘信息并输出的棋盘
char Sqp[Nhang][Nlie] = { 0 };
//初始化棋盘
Csh(Nqp, Nhang, Nlie, '0');
Csh(Sqp, Nhang, Nlie, 'X');
//打印初始化棋盘
//print(Nqp);
print(Sqp);
//存放地雷
Cfdl(Nqp);
//print(Nqp);
//输入坐标、判断并输出
int x = 0, y = 0, n = 0;
while (n != DL)//通过计算棋盘上还剩多少个‘X’来决定是否继续循环
{
printf("请输入坐标(x,y):");
scanf("%d %d", &x, &y);
if ((x > 0 && x <= Hang) && (y > 0 && y <= Lie) && Nqp[x][y] != '1')
{
system("cls");//清屏
dg(Nqp,Sqp,x,y);
print(Sqp);
n = xn(Sqp);
}
else if((x > 0 && x <= Hang) && Nqp[x][y] == '1')
{
printf("你死了。。。。。。\n游戏结束!!!\n");
return;
}
else
{
printf("输入错误,请重新输入!!!\n");
}
}
printf("排雷成功!!!\n游戏结束\n");
}
int main()
{
int n = 0;
do
{
Dycd();
printf("请选择:");
scanf("%d", &n);
switch (n)
{
case 0:
printf("退出游戏!!!\n");
break;
case 1:
printf("游戏开始!!!\n");
game();
break;
default:
printf("输入错误,请重新选择!!!\n");
break;
}
} while (n);
return 0;
}
更多推荐
https://blog.csdn.net/weixin_47298551/article/details/137977727?spm=1001.2014.3001.5501

所有评论(0)