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

C语言:扫雷小游戏

文接上一篇博文C语言:三子棋小游戏。本篇博文是使用C语言来实现扫雷小游戏的。这里不对扫雷的规则进行赘述。玩家通过键盘输入坐标来探雷。博主在实现扫雷之前从未看过扫雷实现的相关视频,所以这里实现的扫雷完全是博主的原生思路,具有逻辑性。下面详细介绍一下如何实现扫雷。

(建议在阅读过上一篇博文再阅读本文,因为再本文中对重复的问题不会再次解读。)

步骤一:制定框架

框架是什么?如何制定框架?这些问题在三子棋的实现中就已经解答了,这里也不多讲。这里的框架与三子棋的框架完全相同。

#include"detect.h"
int main()
{srand((unsigned)time(NULL));//这里设置了随机种子,为了之后随机生成雷int n = 0;do{menu();printf("your choice:\n");scanf("%d", &n);switch (n){case 1:system("cls");game();break;case 0:system("cls");printf("exit game\n");break;default:printf("input error,again:\n");Sleep(1000);system("cls");}} while (n);return 0;
}

menu是什么在三子棋实现中也提过,这里使用了Sleep函数(程序暂停运行多少毫秒)和system("cls")(清屏)是为了更好的游戏体验。这里的detect.h代码如下:

#pragma once
#define ROW 10
#define COL 10
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
void menu();
void game();

步骤二:实现game函数

跟三子棋的game函数一样,我们需要事先想好整个game的流程。

分析过程:既然有雷,我们需要将雷的位置记录下来,那我们就需要一个字符二维数组,雷用大写字符'O'表示,雷的位置就初始化为'O',其他位置为空格。另外,开局时我们一个地方都没探测,我们难道要将带雷的数组直接打印上去吗?显然这样雷就直接被打印出来了。我们可以想到用第二个字符二维数组,里面初始时全是空格字符,这个数组是用来打印的。我们在这个数组中进行探测。

结束条件:如果探的是雷,那么直接宣告失败,结束本次游戏;如果这一次避开了所有的雷,那么直接宣告成功,结束本次游戏;如果这一次没探到雷而且没有结束,那么显示此处旁边雷的个数

那我们怎么知道探出的是不是雷?其实很简单,在数组一中此处如果是雷,说明这次探到雷了

下面是game的代码

void game()
{char map1[ROW][COL] = { 0 };char map2[ROW][COL] = { 0 };mapInit(map1, ROW, COL);//真正存储炸弹mapInit(map2, ROW, COL);//用来打印BoomInit(map1, ROW, COL);system("cls");showMap(map2, ROW, COL);while (1){int ret=playerMove(map1, map2, ROW, COL,ROW*COL/8);if (ret==1)//炸了{system("cls");showMap(map1, ROW, COL);printf("game over\n");system("pause");break;}else if (ret== 2)//排除了所有炸弹{system("cls");showMap(map1, ROW, COL);//展示所有炸弹位置printf("detect successfully\n");Sleep(2000);break;}system("cls");showMap(map2, ROW, COL);}
}

当然只是代码还是很模糊的,下面依然需要对game中的各个部分进行讲解。

map1:即数组一,用来存放炸弹的

map2:即数组二,用来打印的

ROW,COL:宏定义,这个宏定义在"detect.h"中,之前已经给出

mapInit:用来初始化两个数组,将两个数组的每一个元素变成空格字符

BoomInit:用来将map1的随机位置放上炸弹

showMap:将map2打印出来(连带格子的线条,之后会详细实现)

playerMove:返回值为int类型,玩家在map2中的一个位置进行探测,如果在map1中相应位置是炸弹就返回1,避开所有炸弹就返回2,其他情况返回0;

 步骤三:实现game中的函数

​
​
void mapInit(char map[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){map[i][j] = ' ';}}
}//这个函数很简单,不作讲解
void BoomInit(char map[ROW][COL], int row, int col)
{int boomNum = row * col / 6;//6分之一是炸弹//设置炸弹进mapint curNum = 0;int x = 0;int y = 0;while (curNum != boomNum){x = rand() % row;y = rand() % col;if (map[x][y] == ' ')//如果是空格才能正常放入,如果已经是炸弹就不放,重新生成一个坐标{map[x][y] = 'O';curNum++;}}
}void showMap(char map[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){printf(" %c ", map[i][j]);if (j < col - 1)printf("|");}printf("\n");if (i < row - 1){for (int x = 0; x < col; x++){printf("---");if (x < col - 1)printf("|");}printf("\n");}//这一段其实是将画格子线和棋子一并画出,//需要自己动手操作一下才能明白这段代码每一句是在做什么//不动手再怎么讲都不会弄明白}
}
//warning函数是为了完成playerMove函数而写的,请先看playerMove函数
char warning(char map[ROW][COL], int row, int col, int x, int y)
{int countBoom = 0;//最大为8,加上'0'变成字符for (int i = x - 1; i <= x + 1;i++){for (int j = y - 1; j <= y + 1; j++){if (i >= 0 && i <= row && j >= 0 && j <= col)//越界了就不判断是不是雷{if (map[i][j] == 'O')countBoom++;}}}return countBoom +'0';
}
int playerMove(char map1[ROW][COL],char map2[ROW][COL], int row, int col,int boomNum)
{int x = 0;int y = 0;static count = 0;//静态局部变量,记录用户一共开了几个格子while (1){printf("input x:\n");scanf("%d", &x);printf("input y:\n");scanf("%d", &y);x--;y--;//用户输入的1就是第一个位置,数组下标就是0if (x < 0 || x >= row || y < 0 || y >= col || map2[x][y] != ' '){printf("wrong place,again\n");//非法坐标,重新输入}else{break;//合法,退出循环}}//如果探到雷了,map2的该位置就改成'O',没探到雷就显示旁边有几个雷//这里的warning函数就是用来给出map1的相应位置旁边有几个雷,返回值是char类型map2[x][y] = map1[x][y]=='O'?'O':warning(map1,ROW,COL,x,y);if (map2[x][y] == 'O')return 1;//探到雷了,返回1else//判断是否排除完{count++;if (count == col * row - boomNum){count = 0;//归零,下一次进行游戏count还是从0开始计数,否则count还是之前的值return 2;//避开了所有的雷,返回2}}return 0;//正常进行下一次探测,返回0
}​​

 到这里为止,所有的工作就完成了,我们来看看效果

测试:

 配合清屏和睡眠函数效果还是不错的,只是和原版的扫雷少了一个功能。我们知道,原版的扫雷在探到一个格子旁边没有一个炸弹时,也就这里实现的扫雷显示'0'时,会自动将旁边的格子显示出来,只是这个功能实现起来有点困难。当时想过用递归解决这个问题,就是说如果map2中探到一个0雷格,将旁边八个格子打开,如果这八个格子还有0雷格,就会进行递归,继续将旁边的格子打开,只是这样会有一个问题,0雷格挨在一起的话会陷入死递归。个人感觉这个问题使用递归是最好解决的,之后想到了解决方案会更新博文。

相关文章:

C语言:扫雷小游戏

文接上一篇博文C语言&#xff1a;三子棋小游戏。本篇博文是使用C语言来实现扫雷小游戏的。这里不对扫雷的规则进行赘述。玩家通过键盘输入坐标来探雷。博主在实现扫雷之前从未看过扫雷实现的相关视频&#xff0c;所以这里实现的扫雷完全是博主的原生思路&#xff0c;具有逻辑性…...

VScode SSH无法免密登录

配置方法 引用高赞贴&#xff1a;点击 debug方法 连不上需要找到问题原因&#xff0c;看ssh的 log Linux服务器&#xff1a;2222是我们指定的端口&#xff0c;可以是1234等 sudo /usr/sbin/sshd -d -p 2222windows这边&#xff1a;端口号要一致 ssh -vvv ubuntusername192…...

Spring Cloud--从零开始搭建微服务基础环境【四】

&#x1f600;前言 本篇博文是关于Spring Cloud–从零开始搭建微服务基础环境【四】&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;…...

FreeRTOS操作系统中,断言输出 Error:..\..\FreeRTOS\portable\RVDS\ARM_CM4F\port.c,766 原因

分析&#xff1a;Error:..\..\FreeRTOS\portable\RVDS\ARM_CM4F\port.c,766 出现这个原因表示&#xff0c;你现在系统某个中断的优先级高于FreeRTOS可管理的优先级范围&#xff0c;一旦你这个中断触发&#xff0c;断言的信息即你串口就会输出这个条语句&#xff08;前提你串口…...

【Linux】进程间通信与同步

IPC进程间通信 无名管道pipe&#xff08;血缘关系的进程&#xff09;有名管道fifo &#xff08;无血缘关系的进程&#xff09;共享内存信号(开销小)消息队列信号量套接字 进程间同步 文件锁信号量...

SpringBoot 统一功能处理

目录 一、用户登录权限验证 1.1 SpringAOP可以进行处理吗&#xff1f; 1.2 创建自定义拦截器 1.3 将自定义拦截器配置到系统配置项中 1.4 拦截器的实现原理 1.4.1 实现原理源码分析 1.5 统一访问前缀添加 二、统一异常处理 2.1 为什么需要使用统一异常处理&#xff1f;…...

解决:sh: vite: command not found

文章目录 问题描述原因分析解决方案 问题描述 第一次pull项目&#xff0c;运行npm run dev时报错&#xff1a;sh: vite: command not found 原因分析 查看了package.json&#xff0c;发现是有vite的。 没有安装依赖导致的&#xff1b; 解决方案 执行npm i重新安装依赖&#…...

el-select下拉多选框 el-select 设置默认值不可删除功能

Element3.0vue3.0 el-select下拉多选框 el-select 设置默认值不可删除功能 Element-UI是一款广泛使用的Vue.js组件库&#xff0c;其中El-Select下拉多选框组件在实际项目开发中经常被使用。然而&#xff0c;在Element 3.0版本中&#xff0c;El-Select下拉多选框默认值可被删除&…...

Jetsonnano B01 笔记1:基础理解—网络配置—远程连接

今日开始学习 Jetsonnano B01&#xff0c;这是一台小电脑&#xff0c;可以用来&#xff1a; 运行现代 AI 负载&#xff0c;并行运行多个神经网络&#xff0c;以及同时处理来自多个高清传感器的数据&#xff0c;可广泛应用与图像分类、对象检测、图像分割、语音处 理等领域。它…...

Ubuntu系统信息查看指南:了解你的操作系统

要查看Ubuntu系统的信息&#xff0c;你可以使用一些命令行工具来获取系统的各种信息。以下是一些常用的命令&#xff1a; 1. lsb_release -a&#xff1a;列出Ubuntu版本号、发行代号和描述信息。 2. uname -a&#xff1a;显示Linux内核的版本信息。 3. lscpu&#xff1a;提供…...

【STM32】学习笔记-SPI通信

SPI通信 SPI通信&#xff08;Serial Peripheral Interface&#xff09;是一种同步的串行通信协议&#xff0c;用于在微控制器、传感器、存储器、数字信号处理器等之间进行通信。SPI通信协议需要使用4个线路进行通信&#xff1a;时钟线(SCLK)、主输入/主输出线(MISO)、主输出/主…...

解决vue项目首行报红( ESLint 配置)和新建的vue文件首行报红问题

目录 前情提要&#xff1a; 修改ESLint 配置 新建的vue文件首行还是报红 报红原因&#xff1a; 解决方法&#xff1a; 前情提要&#xff1a; 在网上查到的方法可能是在package.json文件或者.eslintrc.js文件中添加 requireConfigFile: false 如果此方法对你的错误不起作用…...

Linux 调试技术 Kprobe

目录 用途&#xff1a;一、技术背景1.1 kprobes的特点与使用限制1.2 kprobe原理 二、 基于kprobe探测模块的探测方式2.1、struct kprobe结构体2.2 kprobe API函数2.3 示例代码参考资料&#xff1a; 用途&#xff1a; 判断内核函数是否被调用&#xff0c;获取调用上下文、入参以…...

一文了解评估 K8s 原生存储产品需要关注的关键能力

近些年&#xff0c;越来越多的企业使用 Kubernetes&#xff08;K8s&#xff09;支持生产环境关键业务。这些业务往往对存储性能和稳定性具有更高的要求&#xff0c;传统存储方案难以充分满足&#xff0c;因此不少用户开始关注更契合 K8s 环境的 K8s 原生存储方案。 不过&#…...

linux免密登录报错 Bad owner or permissions on /etc/ssh/ssh_config.d/05-redhat.conf

问题&#xff1a;权限不对的 解决&#xff1a; 1.检查文件的所有者和权限。 确保文件的所有者是正确的。 运行以下命令来确定文件的所有者和权限&#xff1a; ls -l /etc/ssh/ssh_config.d/05-redhat.conf 通常情况下&#xff0c;SSH配置文件应该属于root用户。如果所有者不是…...

Kafka常用参数

文章目录 概要broker端参数producer端参数consumer端参数 概要 kafka broker、consumer、和producer都有很多可配置的参数。本文主要总结日常开发中常用到的参数。其中producer端可以在org.apache.kafka.clients.producer.ProducerConfig 中找到配置项&#xff0c;consumer端可…...

NFT Insider#105:The Sandbox即将参加韩国区块链周,YGG的声誉和进步(RAP)将引领玩家晋升到下一层级

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members(https://twitter.com/WHALEMembers)、BeepCrypto&#xff08;https://twitter.com/beep_crypto&#xff09;联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜、最有价值的讯息。每期周…...

TCP socket error (The proxy type is invalid for this operation).

“TCP socket error (The proxy type is invalid for this operation)” 错误通常是由于使用了无效的代理类型导致的。在使用QModbusTcpClient连接Modbus TCP设备时&#xff0c;如果您没有配置代理服务器&#xff0c;或者配置的代理类型不正确&#xff0c;就会出现这个错误。 …...

根据需求生成一个Vue模块的类图示例

以下是一个Vue模块的类图示例&#xff1a; ------------------------ | VueModule | ------------------------ | -name: string | | -data: object | | -methods: object | | -computed: object | | -watchers: object | ---…...

C# 类class、继承、多态性、运算符重载,相关练习题

34.函数重载 /*函数重载您可以在同一个范围内对相同的函数名有多个定义。函数的定义必须彼此不同&#xff0c;可以是参数列表中的参数类型不同&#xff0c;也可以是参数个数不同。不能重载只有返回类型不同的函数声明。下面的实例演示了几个相同的函数 Add()&#xff0c;用于对…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...