当前位置: 首页 > news >正文

C语言——扫雷游戏

       扫雷游戏通常是一个由方格组成的区域内进行的,其中随机分布着一定数量的地雷 。玩家的目标是通过点击方格来标记出所有地雷的位置,同时避免自己点到地雷而导致游戏失败。游戏开始时,玩家通常只能看到一部分方格,而其余的方格则需要通过点击来逐渐揭示其内容(目前学的比较低级请见谅)。

 下面这个图是网页版扫雷的界面:

现在开始讲解代码:

       写一个完整代码首先都是从主函数开始(前面写的游戏可以发现主函数的流程几乎不变),do……while(一上来就先进行菜单选择),主函数包含菜单还有对菜单的输入与选择(这个没什么难度,略写),而且一般游戏都需要菜单,玩家才可以清楚了解和选择。

void menu()
{printf("**************************************\n");printf("***********    1.play     ************\n");printf("***********    0.exit     ************\n");printf("**************************************\n");
}int main()
{int input = 0;do{menu();printf("请输入你的选择:");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏!!!\n");break;default:printf("选择错误,请重新选择!!!\n");break;}} while (input);return 0;
}

       进行选择:这里为了后续的写作当然是要选1的,接着跳到game函数。 

void game()
{char mine[ROWS][COLS] = { 0 };char show[ROWS][COLS] = { 0 };InitBoard(mine, ROWS, COLS, '0');InitBoard(show, ROWS, COLS, '*');//PrintBoard(mine, ROW, COL);//这个不需要打印,不然就看着答案排雷了PrintBoard(show, ROW, COL);SetMine(mine, ROW, COL);PrintBoard(mine, ROW, COL);FindMine(show, mine, ROW, COL);
}

       扫雷游戏内部需要两个数组一个是屏幕显现出来(show);另一个则是藏在我们背后(mine),这就是这个游戏的巧妙之处。而且这个数组显现出来的是9X9的数组,但是玩游戏需要计算坐标周围一圈,假设想要检验数组四条靠边的坐标,计算坐标一圈数组会越界这时需要数组都加二(即四条边都加一)

#define ROW 9
#define COL 9

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

       一开始要对这两个数组初始化,而且初始化时需要整个数组都初始化而不是只对显现出来的数组初始化,不然后面会影响。show数组初始化没什么要求,然而为了后面计算【至于为什么后面会提到】mine数组初始化为‘0’(即字符0)。这里有一个简便的操作,就是数组设置为board,这样不管是show还是mine只需要改变数组就可以调用初始化的这个函数。

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

       接下来就是打印数组,单纯只打印数组的话数坐标有些困难,所以需要在数组前标数字方便数数,还需要分界线。

void PrintBoard(char board[ROWS][COLS], int row, int col)
{printf("--------扫雷-------\n");int i = 0;int j = 0;for (i = 0; i <= row; i++){if (i != 0) {printf(" %d", i);}else{printf(" ");}}printf("\n");for (i = 0; i <= row; i++){printf("--");}printf("\n");for (i = 1; i <= row; i++){printf("%d|", i);for (j = 1; j <= col; j++){printf("%c ", board[i][j]);}printf("\n");}for (i = 0; i <= row; i++){printf("--");}printf("\n\n");
}

       下面就到布置地雷,游戏分初级,中级,高级。我们就先简单一点的设置10个地雷,然后就是随机挑选坐标(当然是没有地雷的坐标中挑选啦),选中一个那对应的地雷数要减少一个,这样才知道地雷是否符合标准。

#define EASY 10void SetMine(char mine[ROWS][COLS], int row, int col)
{srand((unsigned int)time(NULL));int count = EASY;while (count){int a = rand() % row + 1;int b = rand() % col + 1;if (mine[a][b] == '0'){mine[a][b] = '1';count--;}}
}

       最后就是重难点排查地雷,先要输入你要排查的坐标,讨论输入的坐标是否符合数组范围,然后再看这个坐标是否有地雷,如若有雷游戏结束且需要打印mine数组的地雷位置供玩家参考;相反没有地雷的话需要打印周围一圈地雷的数量,这个就是mine数组初始化为字符0的原因,数字0和字符0之间相差一个字符0,所以计算地雷数量只需将坐标周围的字符分别都减一个字符0再相加起来就是坐标周围一圈的地雷数量,show数组中是字符,所以地雷数量还需加一个字符0,在打印show数组就会出现地雷数。

       游戏的胜利是需要把所有的不是地雷的坐标找出来才算胜利,所以需要累计排查的坐标是否满足总的坐标减去地雷数,当然过程中不能有重复排查的坐标,不然满足但还有坐标没有排查,这就不符合游戏规则。

int get_round_mine(char mine[ROWS][COLS], int x, int y)
{int i = 0;int j = 0;int ch = 0;for (i = x - 1; i <= x + 1; i++){for (j = y - 1; j <= y + 1; j++){ch = ch + (mine[i][j] - '0');}}return ch;
}void FindMine(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int win = 0;while (win < ROW * COL - EASY){printf("请输入你要排查的坐标:");scanf("%d %d", &x, &y);if (x > 0 && x <= ROW && y > 0 && y <= COL){if (show[x][y] != '*'){printf("该坐标已被排查过\n");continue;}if (mine[x][y] == '1'){printf("踩到地雷,游戏结束!!!\n");PrintBoard(mine, ROW, COL);break;}else{int n = get_round_mine(mine, x, y);show[x][y] = n + '0';PrintBoard(show, ROW, COL);win++;}}else{printf("输入超过限制,无法检测是否有地雷!\n");}}if (win == ROW * COL - EASY){printf("扫雷成功,你太厉害了吧!\n");}
}

现在这个代码还不是很好,和网页版的还是有差距的。目前能力有限往后就不太会了,见谅。 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Python基础—any(),all()函数你会用吗?
  • .net core + vue 搭建前后端分离的框架
  • Java的jstat命令输出GC信息时携带时间信息(Windows系统中)
  • Unity检测鼠标进入、离开UI
  • Gartner发布2024年网络风险管理成熟度曲线:使网络安全战略与业务目标保持一致的概念、方法、流程和技术
  • 突然提示‘由于找不到emp.dll无法继续执行代码’的问题要如何解决?
  • opencv-图像透视变换
  • OpenBayes在线教程 | 当 Llama 3.1 405B 遇上 Mistral Large 2,谁才是大模型赛道的卷王?
  • 『 Linux 』网络基础
  • unity万向锁代数法解释
  • ESP8266使用舵机以及16路PWM舵机PCA 9685的使用方式
  • 【docker】docker容器部署常用服务
  • Qt 跨平台支持任务栏进度条以及自绘消息通知显示
  • 如何使用nodejs的fsPromise.access()判断文件权限
  • git 常用指令(创建分支、提交分支、解决冲突)
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • canvas绘制圆角头像
  • crontab执行失败的多种原因
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • flutter的key在widget list的作用以及必要性
  • Git 使用集
  • java中具有继承关系的类及其对象初始化顺序
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • web标准化(下)
  • 搭建gitbook 和 访问权限认证
  • 聊聊hikari连接池的leakDetectionThreshold
  • 微信小程序--------语音识别(前端自己也能玩)
  • 一个完整Java Web项目背后的密码
  • 智能合约Solidity教程-事件和日志(一)
  • Mac 上flink的安装与启动
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​如何在iOS手机上查看应用日志
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #java学习笔记(面向对象)----(未完结)
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • ()、[]、{}、(())、[[]]命令替换
  • (1)常见O(n^2)排序算法解析
  • (10)ATF MMU转换表
  • (35)远程识别(又称无人机识别)(二)
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (Java企业 / 公司项目)点赞业务系统设计-批量查询点赞状态(二)
  • (搬运以学习)flask 上下文的实现
  • (二)正点原子I.MX6ULL u-boot移植
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (七)理解angular中的module和injector,即依赖注入
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (十三)Flask之特殊装饰器详解
  • (四)c52学习之旅-流水LED灯
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl