扫雷(升级版)附全代码

2024-05-04 22:36
文章标签 代码 扫雷 升级版 附全

本文主要是介绍扫雷(升级版)附全代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

     上次我写了简单版本的扫雷(建议看一下扫雷【C语言】-CSDN博客),但是有些功能并没有实现。比如:

  1. 没有如果排查位置不是雷,可以展开周围的功能。
  2. 没有标记的功能。

     在这篇中这些功能都会被实现。

文章目录

展开

标记

适配

扫雷全代码

game.h

game.c

test.c


展开

     展开是用递归解决的。

     当传入一个非雷坐标时,检查周围8个格子包括它。在让xing数组的该位置等于First_difference函数的返回值。如果函数的返回值存在0那么就再次调用展开函数。如果不存在则不调用。

在完成该函数中有几个要注意的条件。

  1. 检查坐标是否在有效范围内。
  2. 不要把*后的雷给替换。
  3. 不要出现死递归(当i==x,j==y时可能会出现)。
//展开
void unfold(char digital[lines][columns], char xing[lines][columns], int x, int y)
{for(int i = x - 1; i <= x + 1; i++){for (int j = y - 1; j <= y + 1; j++){if ((i <= line && i >= 1) && (j <= column && j >= 1))//检查是否是有效范围{char r = First_difference(digital, i, j);//检查周围雷数if (digital[i][j] != '!')//防止把*后是雷给替换{if (r == 0 && xing[i][j] != '0')//是0继续排查周围且防止出现死递归{xing[i][j] = r + 48;//+48变成字符数字unfold(digital, xing, i, j);//递归}else{xing[i][j] = r + 48;}	}}}}
}

标记

     标记就比较简单了。

     要先判断是否要标记,在Minesweeping函数的else中加入下面这段代码。

char b = 0;
printf("是否要标记(Y/N):");
getchar();//用来消除缓冲区中的'\n',防止b的输入发生问题。 
scanf("%c", &b);
mark(xing, b);

     这里我的标记是用' + '作为标记字符。取消标记的代码和标记的代码一样,只不过取消标记是把' + '变成' * '。

//标记
int key = 0;//这里key是全局变量
void mark(char xing[lines][columns], int n)
{char s = 0;int i = 0;int j = 0;//标记if (n == 89 || n == 121)//Y,y都行{key++;printf("请选择你要标记的坐标:");getchar();scanf("%d %d", &i, &j);xing[i][j] = '+';}//取消标记if (key > 0 && key--)//确保标记次数和取消标记次数统一{printf("是否要取消标记d(Y/N):");getchar();scanf("%c", &s);if (s == 89 || s == 121){printf("请选择你要取消标记的坐标:");getchar();scanf("%d %d", &i, &j);xing[i][j] = '*';}}
}

适配

     新添加函数后原来的Minesweeping函数就会有一些不合理的地方需要改。不过在此之前展开函数需要改改。在标记一个位置后展开的过程中可能会把标记给替换。怎么改呢?

     其实只要在检查周围雷数后加上 xing[i][j] != ' + ' 即可。

//展开
void unfold(char digital[lines][columns], char xing[lines][columns], int x, int y)
{for(int i = x - 1; i <= x + 1; i++){for (int j = y - 1; j <= y + 1; j++){if ((i <= line && i >= 1) && (j <= column && j >= 1)){char r = First_difference(digital, i, j);if (xing[i][j] != '+')//新加的{if (digital[i][j] != '!'){if (r == 0 && xing[i][j] != '0'){xing[i][j] = r + 48;unfold(digital, xing, i, j);}else{xing[i][j] = r + 48;}}}}}}
}

     现在我们就改改Minesweeping函数。以前的循环结束条件不能用了,直接写一个死循环因为我们并不知道什么时候循环结束。失败以前的可以用,那该怎么判断成功呢?

     其实只要遍历一遍xing数组看看有几个' * '和' + '。如果它们等于雷数就跳出。

//排查雷
void Minesweeping(char digital[lines][columns], char xing[lines][columns], int Line, int Column)
{int x = 0;int y = 0;while (1){printf("请选择你要排查的坐标:");scanf("%d %d", &x, &y);if (digital[x][y] == '!'){printf("很遗憾你死了,雷分布如下。注:!是雷\n");Print(digital, line, column);break;}else{char b = 0;unfold(digital, xing, x, y);printf("是否要标记(Y/N):");getchar();scanf("%c", &b);mark(xing, b);Print(xing, line, column);}//判断成功条件int num = 0;for (int m = 1; m <= Line; m++){for (int n = 1; n <= Column; n++){if (xing[m][n] == '*' || xing[m][n] == '+'){num++;}}}if (thunder == num){printf("恭喜你通过了!!!\n");break;}}	
}

扫雷全代码

game.h

#include <stdio.h>
#include <stdlib.h>
#include <time.h>//行
#define line 9
//列
#define column 9#define lines line + 2
#define columns column + 2//雷
#define thunder 10//初始化棋盘
void Initialize(char function[lines][columns], int Lines , int Columns, char n);		//打印棋盘
void Print(char function[lines][columns], int Line, int Column);//埋雷
void Bury(char function[lines][columns], int Line, int Column);//周围雷数
char First_difference(char digital[lines][columns], int x, int y);//展开
void unfold(char digital[lines][columns], char xing[lines][columns], int x, int y);//标记
void mark(char xing[lines][columns], int n);//排查雷
void Minesweeping(char digital[lines][columns], char xing[lines][columns], int Line, int Column);

game.c

#include "game.h"//初始化棋盘
void Initialize(char function[lines][columns], int Lines, int Columns, char n)
{for (int i = 0; i < Lines; i++){for (int j = 0; j < Columns; j++){function[i][j] = n;}}}//打印棋盘
void Print(char function[lines][columns], int Line, int Column)
{printf("--------扫雷-------\n");int b = 1;for (int k = 0; k <= Line; k++){printf("%d ", k);}printf("\n");for (int i = 1; i <= Line ; i++){printf("%d ", b);for (int j = 1; j <= Column ; j++){printf("%c ", function[i][j]);}b++;printf("\n");}
}//埋雷
void Bury(char function[lines][columns], int Line, int Column)
{int num = thunder;while (num){int x = rand() % line + 1;int y = rand() % column + 1;if (function[x][y] == '"'){function[x][y] = '!';num--;}}
}//周围雷数
char First_difference(char digital[lines][columns], int x, int y)
{return (digital[x - 1][y - 1] + digital[x - 1][y] + digital[x - 1][y + 1] + digital[x][y - 1] + digital[x][y + 1] + digital[x + 1][y - 1] + digital[x + 1][y] + digital[x + 1][y + 1] - 34 * 8) * -1;
}//展开
void unfold(char digital[lines][columns], char xing[lines][columns], int x, int y)
{for(int i = x - 1; i <= x + 1; i++){for (int j = y - 1; j <= y + 1; j++){if ((i <= line && i >= 1) && (j <= column && j >= 1)){char r = First_difference(digital, i, j);if (xing[i][j] != '+'){if (digital[i][j] != '!'){if (r == 0 && xing[i][j] != '0'){xing[i][j] = r + 48;unfold(digital, xing, i, j);}else{xing[i][j] = r + 48;}}}}}}
}//标记
int key = 0;
void mark(char xing[lines][columns], int n)
{char s = 0;int i = 0;int j = 0;if (n == 89 || n == 121){key++;printf("请选择你要标记的坐标:");getchar();scanf("%d %d", &i, &j);xing[i][j] = '+';}if (key > 0 && key--){printf("是否要取消标记d(Y/N):");getchar();scanf("%c", &s);if (s == 89 || s == 121){printf("请选择你要取消标记的坐标:");getchar();scanf("%d %d", &i, &j);xing[i][j] = '*';}}
}//排查雷
void Minesweeping(char digital[lines][columns], char xing[lines][columns], int Line, int Column)
{int x = 0;int y = 0;while (1){printf("请选择你要排查的坐标:");scanf("%d %d", &x, &y);if (digital[x][y] == '!'){printf("\n");printf("很遗憾你死了,雷分布如下。注:!是雷\n");Print(digital, line, column);break;}else{char b = 0;unfold(digital, xing, x, y);printf("是否要标记(Y/N):");getchar();scanf("%c", &b);mark(xing, b);Print(xing, line, column);}int num = 0;for (int m = 1; m <= Line; m++){for (int n = 1; n <= Column; n++){if (xing[m][n] == '*'){num++;}}}if (thunder == num){printf("恭喜你通过了!!!\n");break;}}	
}

test.c

#include "game.h"void test()
{//创建数组char xing[lines][columns] = { 0 };char digital[lines][columns] = { 0 };//初始化Initialize(digital, lines, columns, '"');Initialize(xing, lines, columns, '*');//埋雷Bury(digital, line, column);//打印Print(xing, line, column);//排雷Minesweeping(digital, xing, line, column);
}int main()
{srand((unsigned int)time(NULL));test();return 0;
}

     以上就是主要本篇内容,如果有什么不懂的可以私信我,如果有什么错误请你指出。

这篇关于扫雷(升级版)附全代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/960238

相关文章

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

hihocoder1114 小Hi小Ho的惊天大作战:扫雷·一

1114 : 小Hi小Ho的惊天大作战:扫雷·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 故事背景:密室、监视器与充满危机的广场 “我们还是循序渐进,先来考虑这样一个简单化问题:”小Hi思索片刻,道:“在一个大小为2*N的广场,其中第一行里的某一些格子里可能会有至多一个地雷,而第二行的格子里全都为数字,表示第一行中距离与这个格子不超过2的格子里总共有多少个

D4代码AC集

贪心问题解决的步骤: (局部贪心能导致全局贪心)    1.确定贪心策略    2.验证贪心策略是否正确 排队接水 #include<bits/stdc++.h>using namespace std;int main(){int w,n,a[32000];cin>>w>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);int i=1

html css jquery选项卡 代码练习小项目

在学习 html 和 css jquery 结合使用的时候 做好是能尝试做一些简单的小功能,来提高自己的 逻辑能力,熟悉代码的编写语法 下面分享一段代码 使用html css jquery选项卡 代码练习 <div class="box"><dl class="tab"><dd class="active">手机</dd><dd>家电</dd><dd>服装</dd><dd>数码</dd><dd

生信代码入门:从零开始掌握生物信息学编程技能

少走弯路,高效分析;了解生信云,访问 【生信圆桌x生信专用云服务器】 : www.tebteb.cc 介绍 生物信息学是一个高度跨学科的领域,结合了生物学、计算机科学和统计学。随着高通量测序技术的发展,海量的生物数据需要通过编程来进行处理和分析。因此,掌握生信编程技能,成为每一个生物信息学研究者的必备能力。 生信代码入门,旨在帮助初学者从零开始学习生物信息学中的编程基础。通过学习常用

husky 工具配置代码检查工作流:提交代码至仓库前做代码检查

提示:这篇博客以我前两篇博客作为先修知识,请大家先去看看我前两篇博客 博客指路:前端 ESlint 代码规范及修复代码规范错误-CSDN博客前端 Vue3 项目开发—— ESLint & prettier 配置代码风格-CSDN博客 husky 工具配置代码检查工作流的作用 在工作中,我们经常需要将写好的代码提交至代码仓库 但是由于程序员疏忽而将不规范的代码提交至仓库,显然是不合理的 所