用C语言实现扫雷

本篇适用于C语言初学者,主要涉及对于函数,数组,分支循环的运用。

目录

设计思想:

总代码(改进后):

运行结果展示:

分布介绍:

声明:

代码主体部分:

功能模块实现:

初始化模块:

打印模块:

埋雷模块:

判断模块:

总结:


设计思想:

首先要有一个游戏菜单,输入1表示开始,0表示结束,其它数字则提示输入错误,请重新输入;其次要有雷盘,雷盘用二维数组表示,开始时要有初始化模块对二维数组初始化,要有埋雷模块放置雷,要有判断输赢及返回结果模块,要有打印模块向玩家展示雷盘,为了更容易实现这些模块,我们选择两个二维数组表示雷盘,其中一个埋雷,其中一个向玩家展示。为了方便计算周围雷的个数,空用 '0' 表示,;雷用 '1'表示。

总代码(改进后):

#include <stdio.h>
#include <stdlib.h>
#include <time.h>#define ROW 9
#define COL 9#define ROWS ROW + 2
#define COLS COL + 2#define Easy_Mine 10void InitBorad(char borad[ROWS][COLS], int rows, int cols, char ch);
void DisplayBorad(char borad[ROWS][COLS], int row, int col);
void SetMine(char borad[ROWS][COLS], int row, int col);
void FindMine(char mine_borad[ROWS][COLS], char show_board[ROWS][COLS], int row, int col);//初始化
void InitBorad(char borad[ROWS][COLS], int rows, int cols, char ch)
{int i = 0;for (i = 0; i < rows; i++){int j = 0;for (j = 0; j < cols; j++){borad[i][j] = ch;}}
}//打印拓展
void DisplayBorad(char borad[ROWS][COLS], int row, int col)
{int i = 0;//列标for (i = 0; i <= col; i++){printf(" %d |", i);}printf("\n");for (i = 0; i <= col; i++){printf("---|", i);}printf("\n");for (i = 1; i <= row; i++){//行标printf(" %d |", i);int j = 0;for (j = 1; j <= col; j++){printf(" %c |",borad[i][j]);}printf("\n");for (j = 0; j <= col; j++){printf("---|", i);}printf("\n");}printf("\n");
}//放置雷
void SetMine(char borad[ROWS][COLS], int row, int col)
{int count = Easy_Mine;while (count){int x = rand() % row + 1;int y = rand() % col + 1;if (borad[x][y] == '0'){borad[x][y] = '1';count--;}}}//改进判断法//递归实现扫雷的展开一片
void GetMineCount(char mine_borad[ROWS][COLS], char show_borad[ROWS][COLS], int x, int y, int* count)
{if (x >= 1 && x <= ROW && y >= 1 && y <= COL && show_borad[x][y] == '*'){int i = x - 1;int j = y - 1;int sum = 0;//计算周围有几个雷for (i = x - 1; i <= x + 1; i++){for (j = y - 1; j <= y + 1; j++){sum = sum +(mine_borad[i][j] - '0');}}//如果周围没有雷,将此坐标置为空格,递归查找周围的周围是否有雷...if (sum == 0){show_borad[x][y] = ' ';for (i = x - 1; i <= x + 1; i++){for (j = y - 1; j <= y + 1; j++){//更正循环次数(*count)--;GetMineCount(mine_borad, show_borad, i, j, count);}}}//如果周围有雷,将此坐标字符该为对应雷的个数的字符else{//更正循环次数(*count)--;show_borad[x][y] = sum + '0';}}
}void FindMine(char mine_borad[ROWS][COLS], char show_board[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int count = row * col - Easy_Mine;//实现主体while (count){printf("请输入坐标:>");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (mine_borad[x][y] == '1'){printf("嘭!你被炸死了!\n");DisplayBorad(mine_borad, ROW, COL);break;}else if (mine_borad[x][y] == '0' && show_board[x][y] == '*');{GetMineCount(mine_borad, show_board, x, y, &count);//count = count_number(show_board, row, col);//DisplayBorad(mine_borad, ROW, COL);DisplayBorad(show_board, ROW, COL);}}else{printf("输入坐标非法,请重新输入!\n");}}if (count == 0){printf("恭喜你,你赢了!\n");DisplayBorad(mine_borad, row, col);}
}void menu()
{printf("******************************\n");printf("********   1.paly   **********\n");printf("********   0.exit   **********\n");printf("******************************\n");
}void game()
{//此二维数组用来放置雷char mine[ROWS][COLS] = { 0 };//此二维数组用于像玩家展示char show[ROWS][COLS] = { 0 };//初始化两个二维数组InitBorad(mine, ROWS, COLS, '0');//DisplayBorad(mine, ROW, COL);InitBorad(show, ROWS, COLS, '*');//放置雷SetMine(mine, ROW, COL);//打印棋盘DisplayBorad(show, ROW, COL);//DisplayBorad(mine, ROW, COL);//游戏实现主体FindMine(mine, show, ROW, COL);
}//主函数
int main()
{int input = 0;srand((unsigned int)time(NULL));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;
}

运行结果展示:

 

 

 

分布介绍:

声明:

如果想要更改雷盘大小,放置雷个数,只需对ROW , COL , Easy_Mine作相应的修改即可。 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//标识符定义行与列
#define ROW 9
#define COL 9
//雷盘实际大小
#define ROWS ROW + 2
#define COLS COL + 2
//雷的个数
#define Easy_Mine 10
//主要函数声明
void InitBorad(char borad[ROWS][COLS], int rows, int cols, char ch);
void DisplayBorad(char borad[ROWS][COLS], int row, int col);
void SetMine(char borad[ROWS][COLS], int row, int col);
void FindMine(char mine_borad[ROWS][COLS], char show_board[ROWS][COLS], int row, int col);

代码主体部分:

关于作为9 * 9的雷盘为什么要选择11 * 11的二维数组表示,是为了防止越界访问,以及更容易地实现扫雷后的判断和返回结果。用字符0将要放置雷的二维数组初始化,用字符*将向玩家展示的二维数组初始化,用字符1表示雷。

//游戏菜单
void menu()
{printf("******************************\n");printf("********   1.paly   **********\n");printf("********   0.exit   **********\n");printf("******************************\n");
}
//实现主体
void game()
{//此二维数组用来放置雷char mine[ROWS][COLS] = { 0 };//此二维数组用于像玩家展示char show[ROWS][COLS] = { 0 };//初始化两个二维数组InitBorad(mine, ROWS, COLS, '0');//DisplayBorad(mine, ROW, COL);InitBorad(show, ROWS, COLS, '*');//放置雷SetMine(mine, ROW, COL);//打印棋盘DisplayBorad(show, ROW, COL);//DisplayBorad(mine, ROW, COL);//游戏实现主体FindMine(mine, show, ROW, COL);
}
//主函数
int main()
{int input = 0;//生成随机数起点,为埋雷模块服务srand((unsigned int)time(NULL));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;
}

功能模块实现:

初始化模块:

通过嵌套for循环用传过来的字符将传过来的数组初始化。

//初始化
void InitBorad(char borad[ROWS][COLS], int rows, int cols, char ch)
{int i = 0;for (i = 0; i < rows; i++){int j = 0;for (j = 0; j < cols; j++){borad[i][j] = ch;}}
}

打印模块:

原始打印模块:

先利用for循环打印列标,再利用嵌套for循环打印行标及二维数组。代码及雷盘展示如下:

//打印
void DisplayBorad(char borad[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 ", borad[i][j]);}printf("\n");}printf("\n");
}

雷盘:

改进打印模块:

原理如上,加以修饰,代码及雷盘展示如下:

//打印拓展
void DisplayBorad(char borad[ROWS][COLS], int row, int col)
{int i = 0;//列标for (i = 0; i <= col; i++){printf(" %d |", i);}printf("\n");for (i = 0; i <= col; i++){printf("---|", i);}printf("\n");for (i = 1; i <= row; i++){//行标printf(" %d |", i);int j = 0;for (j = 1; j <= col; j++){printf(" %c |",borad[i][j]);}printf("\n");for (j = 0; j <= col; j++){printf("---|", i);}printf("\n");}printf("\n");
}

 雷盘:

埋雷模块:

要实现在雷盘上随机放置雷,需要srand()和time()库函数来确定随机数生成期起点,rand()库函数来生成随机数,将获得的随机数大小控制在1~9之间(雷盘逻辑大小),获得要放置雷的坐标后,找到与之对应的二维数组元素,将其置为字符1。(字符0表示不是雷,字符1表示雷)模块代码及放置雷的二维数组展示:

//放置雷
void SetMine(char borad[ROWS][COLS], int row, int col)
{//要放置的雷的个数int count = Easy_Mine;while (count){//获得要放置雷的坐标int x = rand() % row + 1;int y = rand() % col + 1;//如果此坐标未放置雷,则放置雷,否则重新获得坐标if (borad[x][y] == '0'){borad[x][y] = '1';count--;}}
}

放置雷的二维数组:

判断模块:

原始判断模块;

此模块需要将真雷盘和假雷盘二维数组都传过去。玩家输入要扫雷的坐标,如果坐标不合法,提示输入错误,重新输入。如果坐标合法,与放置雷的二维数组的相应坐标对照,如果此坐标是雷,则输出玩家扫雷失败,并将埋雷的二维数组向玩家展示,游戏结束,如果此坐标不是雷,则判断此坐标周围一圈有无雷,如果无雷,返回0,有雷的话,返回雷的个数,并将向玩家展示的二维数组的对应的坐标更改为雷的个数,更正循环控制条件,继续游戏。当循环控制条件不再满足(及已将所有不是雷的坐标扫出)则获得游戏胜利,游戏结束。

//原始判断法//返回此坐标周围雷的个数
int GetMineCount(char borad[ROWS][COLS], int x, int y)
{//字符1~9减去一个字符0就可以得到整型数1~9,这也是选择用字符0和1表示是否有雷的原因return (borad[x - 1][y] + borad[x - 1][y - 1] + borad[x][y - 1] + borad[x + 1][y - 1]+ borad[x + 1][y] + borad[x + 1][y + 1] + borad[x][y + 1] + borad[x - 1][y + 1] - 8 * '0');
}//判断输赢
void FindMine(char mine_borad[ROWS][COLS], char show_board[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;//循环控制条件int count = row * col - Easy_Mine;while (count){printf("请输入坐标:>");scanf("%d %d", &x, &y);//判断输入坐标是否合法if (x >= 1 && x <= row && y >= 1 && y <= col){//此坐标是雷if (mine_borad[x][y] == '1'){printf("嘭!你被炸死了!\n");//打印放置雷的二维数组DisplayBorad(mine_borad, ROW, COL);break;}//此坐标不是雷else if (mine_borad[x][y] == '0' && show_board[x][y] != ' ');{//函数调用返回雷的个数int ret = GetMineCount(mine_borad, x, y);//将向玩家展示的二维数组的对应坐标更改为雷的个数(将整型数1~9加一个字符0就可转换成字符1~9)show_board[x][y] = ret + '0';//打印DisplayBorad(show_board, ROW, COL);//更正循环控制条件count--;}}else{printf("输入坐标非法,请重新输入!\n");}}//游戏胜利判定if (count == 0){printf("恭喜你,你赢了!\n");DisplayBorad(mine_borad, row, col);}
}

运行展示:

改进判断模块: 

上述判断模块跟扫雷游戏还是有些实质差异,在扫雷游戏中,当一个坐标周围一圈都没有雷时,就会为空,再对他周围的坐标的周围进行判断......因此需要对其进行改进,总体思想不变,仅需对判断坐标周围一圈雷数的子模块以及循环控制条件进行修改即可。当输入坐标周围一圈都没有雷时,将向玩家展示的二维数组的对应坐标置为空格,更改循环控制条件,并判断它周围坐标的周围是否有雷.....依此类推。这里通过循环和递归思想实现此功能。

//改进判断法//递归实现扫雷的展开一片
void GetMineCount(char mine_borad[ROWS][COLS], char show_borad[ROWS][COLS], int x, int y, int* count)
{//递归限制条件 if (x >= 1 && x <= ROW && y >= 1 && y <= COL && show_borad[x][y] == '*'){int i = x - 1;int j = y - 1;//此变量表示雷的个数 int sum = 0;//计算周围有几个雷for (i = x - 1; i <= x + 1; i++){for (j = y - 1; j <= y + 1; j++){sum = sum +(mine_borad[i][j] - '0');}}//如果周围没有雷,将此坐标置为空格,递归查找周围的周围是否有雷...if (sum == 0){show_borad[x][y] = ' ';for (i = x - 1; i <= x + 1; i++){for (j = y - 1; j <= y + 1; j++){//更正循环次数(*count)--;//递归 GetMineCount(mine_borad, show_borad, i, j, count);}}}//如果周围有雷,将此坐标字符改为对应雷的个数的字符else{//更正循环次数(*count)--;show_borad[x][y] = sum + '0';}}
}void FindMine(char mine_borad[ROWS][COLS], char show_board[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int count = row * col - Easy_Mine;//实现主体while (count){printf("请输入坐标:>");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (mine_borad[x][y] == '1'){printf("嘭!你被炸死了!\n");DisplayBorad(mine_borad, ROW, COL);break;}else if (mine_borad[x][y] == '0' && show_board[x][y] == '*');{GetMineCount(mine_borad, show_board, x, y, &count);//count = count_number(show_board, row, col);//DisplayBorad(mine_borad, ROW, COL);DisplayBorad(show_board, ROW, COL);}}else{printf("输入坐标非法,请重新输入!\n");}}if (count == 0){printf("恭喜你,你赢了!\n");DisplayBorad(mine_borad, row, col);}
}

运行展示:

 

 

总结:

关于扫雷游戏的基本模块已经实现,可以开始游戏啦!当然,这个简易扫雷游戏还是可以继续优化的,比如增加标记功能等,这些模块的实现就需要大家自行去探索了,我就不过多阐述了。本期内容就到这里,如果帮到你的话,还请给个一键三连吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/343164.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ArcGIS JSAPI 学习教程 - ArcGIS Maps SDK for JavaScript - 框选显示高亮几何对象

ArcGIS JSAPI 学习教程 - ArcGIS Maps SDK for JavaScript - 框选显示高亮对象 核心代码完整代码&#xff1a;在线示例 在研究 ArcGIS JSAPI RenderNode 高亮&#xff08;highlights&#xff09;FBO 的时候&#xff0c;实现了一下框选高亮几何对象&#xff0c;这里分享一下。 …

Nvidia/算能 +FPGA+AI大算力边缘计算盒子:隧道和矿井绘图设备

RockMass 正在努力打入采矿业和隧道工程利基市场。 这家位于多伦多的初创公司正在利用 NVIDIA AI 开发一款绘图平台&#xff0c;帮助工程师评估矿井和施工中的隧道稳定性。 目前&#xff0c;作为安全预防措施&#xff0c;地质学家和工程师会站在离岩石五米远的地方&#xff0…

chrome调试手机网页

前期准备 1、 PC端安装好chrmoe浏览器 2、 安卓手机安装好chrmoe浏览器 3、 数据线 原文地址&#xff1a;https://lengmo714.top/343880cb.html 手机打开调试模式 进入手机设置&#xff0c;找到开发者模式&#xff0c;然后启用USB调试 打开PC端chrome调试功能 1、点击chr…

聚焦Cayman 环二核苷酸(CDNs)

环二核苷酸CDNs 环二核苷酸&#xff08;cyclic dinucleotides&#xff0c;CDNs&#xff09;是一类天然的环状RNA分子&#xff0c;细菌衍生的CDNs分子包括c-di-GMP、c-di-AMP和3,3-cGAMP&#xff0c;它们介导对恶性、病毒性和细菌性疾病的先天免疫的保护作用&#xff0c;并在自…

springboot古诗文学习系统的设计与实现-计算机毕业设计源码91747

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;古诗文学习系统当然也不能排除在外。古诗文学习系统是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&am…

跨境反向海淘系统:业务流程解析与未来发展展望

随着全球化的深入发展和互联网技术的飞速进步&#xff0c;跨境购物已经成为越来越多消费者日常生活中的一部分。在这个过程中&#xff0c;反向海淘系统以其独特的优势&#xff0c;逐渐崭露头角&#xff0c;成为跨境电商领域的新星。作为一名在跨境反向海淘系统业务中耕耘了10年…

信创国产化 | 聚铭网络携手银河麒麟完成产品兼容性互认证

在我国信创国产化战略深入推进的大背景下&#xff0c;聚铭网络与麒麟软件积极响应国家号召&#xff0c;共同致力于软件和操作系统的国产化发展。近日&#xff0c;双方宣布已完成产品兼容性互认证工作&#xff0c;这一成果标志着两家公司在信创国产化道路上迈出了坚实的一步。 …

Acrobat Pro DC 2023 for Mac/Win:全平台PDF编辑器的终极解决方案

对于需要处理PDF文档的个人和企业用户来说&#xff0c;Adobe Acrobat Pro DC 2023是一款不可或缺的工具。作为全球领先的PDF编辑器&#xff0c;Acrobat Pro DC 2023在Mac和Windows平台上提供了丰富的功能和令人印象深刻的性能&#xff0c;使其成为用户编辑、转换和管理PDF文档的…

实验9 浮动静态路由配置

--名称-- 一、 原理描述二、 实验目的三、 实验内容四、 实验配置五、 实验步骤 一、 原理描述 浮动静态路由也是一种特殊的静态路由&#xff0c;主要考虑链路冗余。浮动静态路由通过配置一条比主路由优先级低的静态路由&#xff0c;用于保证在主路由失效的情况下&#xff0c;…

商城项目【尚品汇】07分布式锁-2 Redisson篇

文章目录 1 Redisson功能介绍2 Redisson在Springboot中快速入门&#xff08;代码&#xff09;2.1 导入依赖2.2 Redisson配置2.3 将自定义锁setnx换成Redisson实现&#xff08;可重入锁&#xff09; 3 可重入锁原理3.1 自定义分布式锁setnx为什么不可以重入3.2 redisson为什么可…

华为面经整理

文章目录 实习第一面准备提问相关算法相关 第一面结果提问环节 总结 实习 第一面准备 提问相关 操作系统有哪些功能 进程管理&#xff1a; 进程调度、进程同步和通信、多任务处理 内存管理&#xff1a; 内存分配、虚拟内存技术、内存保护 文件系统管理&#xff1a; 文件存储…

数据中心网络架构设计与优化

数据中心是现代企业和组织的核心基础设施&#xff0c;它们用于存储、处理和传输大量的数据和信息。为了满足不断增长的数据需求和提供可靠的服务&#xff0c;设计和优化数据中心网络架构至关重要。 首先&#xff0c;数据中心网络架构设计需要考虑可扩展性。随着业务的增长&…

【Pycharm】功能介绍

1.Code Reformat Code 格式化代码&#xff0c;可以帮助我们去自动调整空格等&#xff0c;根据python语法规范自动调整 2.Settings 1.创建py文件默认填充模版 3.读写py文件编码格式一致性 顶部代码指定的编码方式作用&#xff1a; 可以保证python2/3解释器在读取文件的时候按…

【SpringBoot + Vue 尚庭公寓实战】租期管理接口实现(四)

【SpringBoot Vue 尚庭公寓实战】租期管理接口实现&#xff08;四&#xff09; 文章目录 【SpringBoot Vue 尚庭公寓实战】租期管理接口实现&#xff08;四&#xff09;1、查询全部租期列表2、保存或更新租期信息3、根据ID删除租期 租期管理共有三个接口&#xff0c;分别是 保…

MySQL中获取时间的方法

大家好&#xff0c;在MySQL数据库开发中&#xff0c;获取时间是一个常见的需求。MySQL提供了多种方法来获取当前日期、时间和时间戳&#xff0c;并且可以对时间进行格式化、计算和转换。 以下是一些常用的MySQL时间函数及其示例&#xff1a; 1、NOW()&#xff1a;用于获取当前…

网线制作(双绞线+水晶头)——T568B标准

参考视频&#xff1a;https://www.bilibili.com/video/BV1KQ4y1i7zP/ 1、使用剥线器 2、将线捋顺、排序、剪掉牵引线 记忆技巧 1.线序颜色整体是一浅一深 2.颜色顺序是黄、蓝、绿、棕 一个黄种人、从上向下看&#xff0c;分别看到的是蓝天、青草(绿)、泥土(棕色) 3.中间两根浅…

反序列化漏洞

概念 序列化&#xff08; serialization &#xff09;&#xff1a;讲数据结构、对象等状态转化成可使用的格式&#xff08;一般用于&#xff1a;缓存、网络发送、身份信息等&#xff09;&#xff0c;以备能够被还原为原始状态&#xff1b; 序列化 & 反序列化功能一般用作…

硬件产品经理

边端协调管理平台 主页一&#xff1a;模型管理1.1 边侧模型管理 二&#xff1a;配置管理2.1 终端软件配置管理 三&#xff1a;设备管理3.1 区域位置管理3.2 工控机管理&#xff08;其实就是围绕授权&#xff09;3.3 生产设备管理3.4 设备运行管理 四&#xff1a;数据服务4.1 实…

Unity 资源 之 风格化地形纹理(Stylized Terrain Textures)免费领取

风格化地形纹理&#xff1a;Stylized Terrain Textures 前言资源包内容领取兑换码 前言 亲爱的 Unity 游戏开发者们&#xff0c;我们自豪地为大家推荐最新的每周免费资源&#xff1a;风格化地形纹理&#xff01;这些令人惊叹的纹理将为你的游戏世界带来独特而引人入胜的视觉体…

MySQL与PostgreSQL关键对比三(索引类型)

目录 索引类型 B-tree 索引 Hash 索引 Full-text 索引 GiST 索引 GIN 索引 BRIN 索引 索引创建示例 MySQL PostgreSQL 结论 以下SQL语句的执行如果需要开发工具支持&#xff0c;可以尝试使用SQLynx或Navicat来执行。 MySQL和PostgreSQL在索引方面有许多相似之处&am…