扫雷雷雷雷雷雷雷
大家好啊,我是小象٩(๑òωó๑)۶
我的博客:Xiao Xiangζั͡ޓއއ
很高兴见到大家,希望能够和大家一起交流学习,共同进步。
这一节课我们不学习新的知识,我们来做一个扫雷小游戏
目录
- 扫雷小游戏概述
- 一、扫雷游戏分析和设计
- 1.1 扫雷游戏的功能说明
- 1.2 设计思路总结:
- 二、扫雷游戏代码的实现
- game.h
- game.c
- test.c
- 三、扫雷游戏的扩展
- 四、结尾
扫雷小游戏概述
扫雷是一款极具趣味性和挑战性的逻辑解谜游戏,玩家需要在一个布满方块的网格中,根据数字提示推理出隐藏地雷的位置,并标记或避开它们。这款游戏历史悠久,许多操作系统都将其作为自带游戏,因其简单易上手却又充满策略性而深受玩家喜爱。
一、扫雷游戏分析和设计
1.1 扫雷游戏的功能说明
• 使用控制台实现经典的扫雷游戏
• 游戏可以通过菜单实现继续玩或者退出游戏
• 扫雷的棋盘是9*9的格子
• 默认随机布置10个雷
• 可以排查雷
◦ 如果位置不是雷,就显示周围有几个雷
◦ 如果位置是雷,就炸死游戏结束
◦ 把除10个雷之外的所有非雷都找出来,排雷成功,游戏结束
1.2 设计思路总结:
首先,利用控制台打造经典扫雷游戏,含菜单可选择继续或退出。棋盘为 9×9,默认随机布置 10 个雷。玩家排查雷,若选中非雷位置,显示周围雷数;选中雷则游戏结束;找出所有非雷位置,游戏胜利。
然后我们可以采用两个 11×11 的字符数组,mine数组存放布置好的雷信息(初始为’0’,布置雷处改为’1’),show数组存放排查出的雷的信息(初始为’*') ,以此避免信息混淆,同时扩大数组防止排查雷时越界。
最后再通过多文件形式开发,test.c编写测试逻辑,game.c实现游戏函数,game.h声明数据类型和函数,使代码结构清晰,便于维护。
二、扫雷游戏代码的实现
之前学习了多文件的形式对函数的声明和定义,这里我们实践⼀下,我们设计三个文件:
test.c //⽂件中写游戏的测试逻辑
game.c //⽂件中写游戏中函数的实现等
game.h //⽂件中写游戏需要的数据类型和函数声明等
game.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define EASY_COUNT 10
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2//初始化棋盘void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);//打印棋盘void DisplayBoard(char board[ROWS][COLS], int row, int col);//布置雷void SetMine(char board[ROWS][COLS], int row, int col);//排查雷void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
这是一个头文件,主要用于声明函数和定义常量,为其他源文件提供必要的接口和信息,以实现模块化编程。
前面包含了标准输入输出库 <stdio.h>、标准库 <stdlib.h> 和时间库
<time.h>,这些库提供了后续代码中使用的基本函数,如 printf、scanf、rand 和 time 等。
宏定义:EASY_COUNT 定义了简单难度下雷的数量为 10 个。 ROW 和 COL 分别定义了游戏棋盘的实际行数和列数,这里是 9x9的棋盘。 ROWS 和 COLS 分别是在实际棋盘基础上增加了两行两列的扩展棋盘大小,用于方便处理边界情况。
声明了四个函数,这些函数的具体实现将在 game.c 文件中完成。
InitBoard 用于初始化棋盘,将棋盘的每个元素设置为指定的字符。
DisplayBoard 用于打印棋盘,方便玩家查看游戏状态。
SetMine 用于在棋盘上随机布置雷。
FindMine用于玩家排查雷,根据玩家输入的坐标判断是否踩到雷,并更新游戏状态。
game.c
#include <stdlib.h>
#include <time.h>
#include "game.h"void InitBoard(char board[ROWS][COLS], int rows, int cols, char set){int i = 0;for (i = 0; i < rows; i++){int j = 0;for (j = 0; j < cols; j++){board[i][j] = set;}}}void DisplayBoard(char board[ROWS][COLS], int row, int col){int i = 0;printf("--------扫雷游戏-------\n");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 ", board[i][j]);}printf("\n");}}void SetMine(char board[ROWS][COLS], int row, int col){//布置10个雷//⽣成随机的坐标,布置雷int count = EASY_COUNT;while (count){int x = rand() % row + 1;int y = rand() % col + 1;if (board[x][y] == '0'){board[x][y] = '1';count--;}}}int GetMineCount(char mine[ROWS][COLS], int x, int y)
{return (mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y-1] + mine[x + 1][y] +mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0');
}
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int win = 0;while (win < row * col - EASY_COUNT){printf("请输⼊要排查的坐标:>");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (mine[x][y] == '1'){printf("很遗憾,你被炸死了\n");DisplayBoard(mine, ROW, COL);break;}else{//该位置不是雷,就统计这个坐标周围有⼏个雷int count = GetMineCount(mine, x, y);show[x][y] = count + '0';DisplayBoard(show, ROW, COL);win++;}}else{printf("坐标⾮法,重新输⼊\n");}}if (win == row * col - EASY_COUNT){printf("恭喜你,排雷成功\n");DisplayBoard(mine, ROW, COL);}
}
这是一个源文件,主要实现了 game.h 中声明的函数,是扫雷游戏的核心功能实现文件。
InitBoard 函数:使用双重循环遍历棋盘的每个元素,将其初始化为指定的字符 set。
DisplayBoard 函数:打印棋盘的行列编号,并输出棋盘的每个元素,方便玩家查看游戏状态。
SetMine 函数:利用 rand 函数生成随机坐标,在棋盘上随机布置 EASY_COUNT 个雷,直到布置完成。
GetMineCount 函数:计算指定坐标周围 8 个格子中雷的数量,通过字符 ‘1’ 和 ‘0’ 的 ASCII 码差值来统计。
FindMine 函数:处理玩家排查雷的操作,根据玩家输入的坐标判断是否踩到雷。如果踩到雷,游戏结束;否则,统计周围雷的数量并更新显示棋盘,直到所有非雷格子都被排查完,玩家获胜。
test.c
#include "game.h"void menu(){printf("***********************\n");printf("***** 1. play *****\n");printf("***** 0. exit *****\n");printf("***********************\n");}void game(){char mine[ROWS][COLS];//存放布置好的雷char show[ROWS][COLS];//存放排查出的雷的信息//初始化棋盘//1. mine数组最开始是全'0'//2. show数组最开始是全'*'InitBoard(mine, ROWS, COLS, '0');InitBoard(show, ROWS, COLS, '*');//打印棋盘//DisplayBoard(mine, ROW, COL);DisplayBoard(show, ROW, COL);//1. 布置雷SetMine(mine, ROW, COL);//DisplayBoard(mine, ROW, COL);//2. 排查雷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;}
这也是一个源文件,主要负责游戏的流程控制和用户交互,是游戏的入口文件。
主函数main是程序的入口点,使用 srand 函数初始化随机数种子,以确保每次游戏的雷布局不同。通过 do-while 循环不断显示菜单,根据用户的选择调用相应的函数,直到用户选择退出游戏。
综上所述,game.h 提供了游戏的接口和常量定义,game.c 实现了游戏的核心功能,test.c 负责游戏的流程控制和用户交互,三个文件协同工作,实现了一个简单的扫雷游戏。
三、扫雷游戏的扩展
• 是否可以选择游戏难度
简单 99 棋盘,10个雷
中等 1616棋盘,40个雷
困难 30*16棋盘,99个雷
• 如果排查位置不是雷,周围也没有雷,可以展开周围的一片
• 是否可以标记雷
• 是否可以加上排雷的时间显示
四、结尾
这一课的内容就到这里了,下节课继续学习指针的其他一些知识
如果内容有什么问题的话欢迎指正,有什么问题也可以问我!
相关文章:

扫雷雷雷雷雷雷雷
大家好啊,我是小象٩(๑ω๑)۶ 我的博客:Xiao Xiangζั͡ޓއއ 很高兴见到大家,希望能够和大家一起交流学习,共同进步。 这一节课我们不学习新的知识,我们来做一个扫雷小游戏 目录 扫雷小游戏概述一、扫雷游戏分析…...
图片分类实战:食物分类问题(含半监督)
食物分类问题 simple_class 1. 导入必要的库和模块 import random import torch import torch.nn as nn import numpy as np import os from PIL import Image #读取图片数据 from torch.utils.data import Dataset, DataLoader from tqdm import tqdm from torchvision impo…...

RuoYi框架添加自己的模块(学生管理系统CRUD)
RuoYi框架添加自己的模块(学生管理系统) 框架顺利运行 首先肯定要顺利运行框架了,这个我不多说了 设计数据库表 在ry数据库中添加表tb_student 表字段如图所示 如图所示 注意id字段是自增的 注释部分是后面成功后前端要展示的部分 导入…...
机器学习在地图制图学中的应用
原文链接:https://www.tandfonline.com/doi/full/10.1080/15230406.2023.2295948#abstract CSDN/2025/Machine learning in cartography.pdf at main keykeywu2048/CSDN GitHub 核心内容 本文是《制图学与地理信息科学》特刊的扩展评论,系统探讨了机…...
【JAVA架构师成长之路】【电商系统实战】第9集:订单超时关闭实战(Kafka延时队列 + 定时任务补偿)
30分钟课程:订单超时关闭实战(Kafka延时队列 定时任务补偿) 课程目标 理解订单超时关闭的业务场景与核心需求。掌握基于 Kafka 延时队列与定时任务的关单方案设计。实现高并发场景下的可靠关单逻辑(防重复、幂等性)。…...
《探秘课程蒸馏体系“三阶训练法”:解锁知识层级递进式迁移的密码》
在人工智能与教育科技深度融合的时代,如何高效地实现知识传递与能力提升,成为众多学者、教育工作者以及技术专家共同探索的课题。课程蒸馏体系中的“三阶训练法”,作为一种创新的知识迁移模式,正逐渐崭露头角,为解决这…...
K8s 1.27.1 实战系列(六)Pod
一、Pod介绍 1、Pod 的定义与核心设计 Pod 是 Kubernetes 的最小调度单元,由一个或多个容器组成,这些容器共享网络、存储、进程命名空间等资源,形成紧密协作的应用单元。Pod 的设计灵感来源于“豌豆荚”模型,容器如同豆子,共享同一环境但保持隔离性。其核心设计目标包括…...

Java CountDownLatch 用法和源码解析
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...

Unity引擎使用HybridCLR(华佗)热更新
大家好,我是阿赵。 阿赵我做手机游戏已经有十几年时间了。记得刚开始从做页游的公司转到去做手游的公司,在面试的时候很重要的一个点,就是会不会用Lua。使用Lua的原因很简单,就是为了热更新。 热更新游戏内容很重要。如果…...
深度学习进阶:神经网络优化技术全解析
文章目录 前言一、优化问题的本质1.1 目标1.2 挑战 二、梯度下降优化算法2.1 基础SGD2.2 动量法2.3 Adam优化器 三、正则化技术3.1 L2正则化3.2 Dropout 四、学习率调度4.1 为什么要调度?4.2 指数衰减4.3 ReduceLROnPlateau 五、实战优化:MNIST案例5.1 完…...
肿瘤检测新突破:用随机森林分类器助力医学诊断
前言 你有没有想过,科技能不能在肿瘤检测中发挥巨大的作用?别着急,今天我们将带你走进一个“聪明”的世界,通过随机森林分类器进行肿瘤检测。对,你没听错,机器学习可以帮助医生更快、更准确地判断肿瘤是良性还是恶性,就像医生口袋里的“超级助手”一样,随时准备提供帮…...

DeepSeek学习 一
DeepSeek学习 一 一、DeepSeek是什么?二、Deepseek可以做什么?模型理解提问内容差异使用原则 模式认识三、如何提问?RTGO提示语结构CO-STAR提示语框架DeepSeek R1提示语技巧 总结 一、DeepSeek是什么? DeepSeek是一家专注通用人工…...

编程考古-Borland历史:《.EXE Interview》对Anders Hejlsberg关于Delphi的采访内容(上)
为了纪念Delphi在2002年2月14日发布的25周年(2020.2.12),这里有一段由.EXE杂志编辑Will Watts于1995年对Delphi首席架构师Anders Hejlsberg进行的采访记录。在这次采访中,Anders讨论了Delphi的设计与发展,以及即将到来的针对Windows 95的32位版本。 问: Delphi是如何从T…...
高并发之接口限流,springboot整合Resilience4j实现接口限流
添加依赖 <dependency><groupId>io.github.resilience4j</groupId><artifactId>resilience4j-spring-boot2</artifactId><version>1.7.0</version> </dependency><dependency><groupId>org.springframework.boot…...

电脑如何拦截端口号,实现阻断访问?
如果你弟弟喜欢玩游戏,你可以查询该应用占用的端口,结合以下方法即可阻断端口号,让弟弟好好学习,天天向上! 拦截端口可以通过防火墙和路由器进行拦截 ,以下是常用方法: 方法 1:使用…...
RK3588 安装ffmpeg6.1.2
在安装 ffmpeg 在 RK3588 开发板上时,你需要确保你的开发环境(例如 Ubuntu、Debian 或其他 Linux 发行版)已经设置好了交叉编译工具链,以便能够针对 RK3588 架构编译软件。以下是一些步骤和指导,帮助你安装 FFmpeg: 1. 安装依赖项 首先,确保你的系统上安装了所有必要的…...
SQL SELECT DISTINCT 语句
在 SQL 中,SELECT DISTINCT 语句用于从表中查询不重复的值。这对于需要从数据库检索唯一值时非常有用。DISTINCT 关键字会去除结果集中重复的行,只返回唯一的记录。 SELECT DISTINCT column1, column2, ... FROM table_name; column1, column2, ... 是…...
MELON的难题
MELON的难题 真题目录: 点击去查看 E 卷 200分题型 题目描述 MELON有一堆精美的雨花石(数量为n,重量各异),准备送给S和W。MELON希望送给俩人的雨花石重量一致,请你设计一个程序,帮MELON确认是否能将雨花石平均分配。 输入描述 第1行输入为雨花石个数: n,0 < n &l…...
Restful 接口设计规范
一、资源与 URL 1. 使用名词表示资源 URL 应该以名词为主,用来表示具体的资源,而不是动词。例如,/users 表示用户资源集合,/users/{id} 表示单个用户资源。 2. 采用复数形式 一般来说,资源的 URL 应该使用复数形式…...
Java后端高频面经——Spring、SpringBoot、MyBatis
Spring定义一个Bean有哪些方法?依赖注入有哪些方法? (1)定义Bean的方法 注解定义Bean,Component 用于标记一个类作为Spring的bean。当一个类被Component注解标记时,Spring会将其实例化为一个bean࿰…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...

分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...