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

【C语言6】数组和函数实践:扫雷游戏的简单实现

在这里插入图片描述

文章目录

  • 一、扫雷游戏分析和设计
    • 1.1 扫雷游戏的功能说明
    • 1.2 游戏的分析和设计
      • 1.2.1 数据结构的分析
      • 1.2.2 文件结构设计
  • 二、扫雷游戏的代码实现
  • 三、扫雷游戏的扩展
  • 总结


一、扫雷游戏分析和设计

1.1 扫雷游戏的功能说明

  • 使用控制台实现经典的扫雷游戏
  • 游戏可以通过菜单实现继续玩或者退出游戏
  • 扫雷的棋盘是9*9的格子
  • 默认随机布置10个雷
  • 可以排查雷
    ◦ 如果位置不是雷,就显示周围有几个雷
    ◦ 如果位置是雷,就炸死游戏结束
    ◦ 把除10个雷之外的所有非雷都找出来,排雷成功,游戏结束

游戏的界面:

1.2 游戏的分析和设计

1.2.1 数据结构的分析

扫雷的过程中,布置的雷和排查出的雷的信息都需要存储,所以我们需要一定的数据结构来存储这些信息。
因为我们需要在99的棋盘上布置雷的信息和排查雷,我们首先想到的就是创建一个99的数组来存放信息。
在这里插入图片描述
那如果这个位置布置雷,我们就存放1,没有布置雷就存放0
在这里插入图片描述
假设我们排查(2,5)这个坐标时,我们访问周围的一圈8个黄色位置,统计周围雷的个数是1

假设我们排查(8,6)这个坐标时,我们访问周围的一圈8个黄色位置,统计周围雷的个数时,最下面的三个坐标就会越界,为了防止越界,我们在设计的时候,给数组扩大一圈,雷还是布置在中间的99的坐标上,周围一圈不去布置雷就行,这样就解决了越界的问题。所以我们将存放数据的数组创建成1111是比较合适。

再继续分析,我们在棋盘上布置了雷,棋盘上雷的信息(1)和非雷的信息(0),假设我们排查了某一个位置后,这个坐标处不是雷,这个坐标的周围有1个雷,那我们需要将排查出的雷的数量信息记录存储,并打印出来,作为排雷的重要参考信息的。那这个雷的个数信息存放在哪里呢?如果存放在布置雷的数组中,这样雷的信息和雷的个数信息就可能或产生混淆和打印上的困难。

这里我们肯定有办法解决,比如:雷和非雷的信息不要使用数字,使用某些字符就行,这样就避免冲突了,但是这样做棋盘上有雷和非雷的信息,还有排查出的雷的个数信息,就比较混杂,不够方便。

这里我们采用另外一种方案,我们专门给一个棋盘(对应一个数组mine)存放布置好的雷的信息,再给另外一个棋盘(对应另外一个数组show)存放排查出的雷的信息。这样就互不干扰了,把雷布置到mine数组,在mine数组中排查雷,排查出的数据存放在show数组,并且打印show数组的信息给后期排查参考。

同时为了保持神秘,show数组开始时初始化为字符 ‘*’,为了保持两个数组的类型一致,可以使用同一套函数处理,mine数组最开始也初始化为字符’0’,布置雷改成’1’。如下如:
mine数组布置雷后的状态
在这里插入图片描述
show输出初始化的状态
在这里插入图片描述
对应的数组是:

char mine[11][11] = {0};//用来存放布置好的雷的信息
char show[11][11] = {0};//用来存放排查出的雷的个数信息

1.2.2 文件结构设计

之前学习了多文件的形式对函数的声明和定义,这里我们实践一下,我们设计三个文件:

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 printBoard(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);

game.c

#define  _CRT_SECURE_NO_WARNINGS#include "game.h"void initBoard(char board[ROWS][COLS], int rows, int cols, char set)
{for (int i = 0; i < rows; ++i){for (int j = 0; j < cols; ++j){board[i][j] = set;}}
}void printBoard(char board[ROWS][COLS], int row, int col)
{printf("------扫雷游戏------\n");for (int i = 0; i <= row; ++i){printf("%d ", i);}printf("\n");for (int i = 1; i <= row; ++i){printf("%d ", i);for (int j = 1; j <= col; ++j){printf("%c ", board[i][j]);}printf("\n");}
}void setMine(char mine[ROWS][COLS], int row, int col)
{//随机设置10个雷int count = EASY_COUNT;while (count){int x = rand() % ROW + 1; //1-9的随机x.yint y = rand() % COL + 1;if (mine[x][y] == '0'){mine[x][y] = '1';count--;}}
}static int get_Mine_count(char mine[ROWS][COLS], int x, int y)
{return mine[x + 1][y + 1] + mine[x + 1][y - 1] + mine[x - 1][y - 1] + mine[x - 1][y + 1] +mine[x][y + 1] + mine[x][y - 1] + mine[x + 1][y] + mine[x - 1][y] - 8 * '0';
}void findMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x, y;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");printBoard(mine, ROW, COL);break;}else{if (show[x][y] == '*'){show[x][y] = get_Mine_count(mine, x, y) + '0';printBoard(show, ROW, COL);win++;}}}else{printf("您输入的坐标不合法,请重新输入\n");}}if (win == ROW * COL - EASY_COUNT){printf("恭喜你!排雷成功!\n\n");printBoard(mine, ROW, COL);}
}

test.c

#define  _CRT_SECURE_NO_WARNINGS#include "game.h"static void menu()
{printf("*************************************\n");printf("************   1. play   ************\n");printf("************   0. exit   ************\n");printf("*************************************\n");
}static void game()
{char mine[ROWS][ROWS];char show[ROWS][ROWS];//初始化//1. mine数组最开始是全'0'//2. show数组最开始是全'*'initBoard(mine, ROWS, COLS, '0');initBoard(show, ROWS, COLS, '*');//设置雷setMine(mine, ROW, COL);//打印//printBoard(mine, ROW, COL);printBoard(show, ROW, COL);//排雷findMine(mine, show, ROW, COL);
}int main()
{srand((unsigned int)time(NULL));int input = -1;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;
}

三、扫雷游戏的扩展

  • 是否可以选择游戏难度
    ◦ 简单 99 棋盘,10个雷
    ◦ 中等 16
    16棋盘,40个雷
    ◦ 困难 30*16棋盘,99个雷
  • 如果排查位置不是雷,周围也没有雷,可以展开周围的一片
  • 是否可以标记雷
  • 是否可以加上排雷的时间显示

在线扫雷游戏:http://www.minesweeper.cn/


总结

今天结合前面的知识实现了一个小的扫雷游戏,基本功能可以实现,扩展部分有待补充…
在这里插入图片描述

相关文章:

【C语言6】数组和函数实践:扫雷游戏的简单实现

文章目录 一、扫雷游戏分析和设计1.1 扫雷游戏的功能说明1.2 游戏的分析和设计1.2.1 数据结构的分析1.2.2 文件结构设计 二、扫雷游戏的代码实现三、扫雷游戏的扩展总结 一、扫雷游戏分析和设计 1.1 扫雷游戏的功能说明 使用控制台实现经典的扫雷游戏游戏可以通过菜单实现继续…...

LeetCode 热题 100----1.两数之和

LeetCode 热题 100----1.两数之和 题目描述 我的解法 语言&#xff1a;js 思路就是&#xff1a;用双重循环去找哪两个数字相加等于target&#xff0c;目前的时间复杂度为O(n2)&#xff0c;之后右优化思路再更新。...

《模式和状态管理》知识总结三-EcuM与BswM模块的交互

前言 这篇文章主要搞清楚在模式管理中&#xff0c;BswM和EcuM各自的分工。距离学完模式管理也有几天时间了&#xff0c;写这篇文章算是复习一下。 EcuM及BswM交互总览 EcuM负责Ecu的上下电状态的处理&#xff0c;当Ecu处于正常运行状态的时候&#xff0c;EcuM会将Ecu的控制权…...

RK3568平台(网络篇)RTL8111网卡

RTL8111 是 Realtek 推出的一款高性能千兆以太网控制器芯片,广泛应用于 PCIE 网卡中。 其工作原理涉及 数据链路层 和 物理层 的协同工作,以下是其核心原理的详细说明: 一.网卡的基本功能 1.数据封装与解封装: 网卡负责将计算机中的数据封装成网络传输的帧(Frame),并…...

客户需求模糊或频繁变更怎么办

应对客户需求模糊或频繁变更的关键在于 明确沟通、敏捷应对、科学决策。其中&#xff0c;明确沟通尤为重要&#xff0c;因为通过有效沟通&#xff0c;不仅能迅速厘清客户真实需求&#xff0c;还能及时发现隐藏问题&#xff0c;降低项目风险&#xff0c;为后续调整提供有力数据支…...

动静态库-Linux 学习

在软件开发中&#xff0c;程序库是一组预先编写好的程序代码&#xff0c;它们存储了常用的函数、变量和数据结构等。这些库可以帮助开发者节省大量的时间和精力&#xff0c;避免重复编写相同的代码。当我们在 Linux 系统中开发程序时&#xff0c;经常会用到两种类型的程序库&am…...

DeepSeek 系列模型:论文精读《A Survey of DeepSeek Models》

引言&#xff1a;一篇快速了解 DeepSeek 系列的论文。我在翻译时加入了一些可以提高 “可读性” 的连词 ✅ NLP 研 2 选手的学习笔记 笔者简介&#xff1a;Wang Linyong&#xff0c;NPU&#xff0c;2023级&#xff0c;计算机技术 研究方向&#xff1a;文本生成、大语言模型 论文…...

Python解决“找出整形数组中占比超过一半的数”问题

这里写目录标题 问题描述测试样例解决思路代码法1法2 问题描述 小R从班级中抽取了一些同学&#xff0c;每位同学都会给出一个数字。已知在这些数字中&#xff0c;某个数字的出现次数超过了数字总数的一半。现在需要你帮助小R找到这个数字。 测试样例 样例1&#xff1a; 输入&…...

机器人学习模拟框架 robosuite (3) 机器人控制代码示例

Robosuite框架是一个用于机器人模拟和控制的强大工具&#xff0c;支持多种类型的机器人。 官方文档&#xff1a;Overview — robosuite 1.5 documentation 开源地址&#xff1a;https://github.com/ARISE-Initiative/robosuite 目录 1、通过键盘或SpaceMouse远程控制机器人…...

kakfa-3:ISR机制、HWLEO、生产者、消费者、核心参数负载均衡

1. kafka内核原理 1.1 ISR机制 光是依靠多副本机制能保证Kafka的高可用性&#xff0c;但是能保证数据不丢失吗&#xff1f;不行&#xff0c;因为如果leader宕机&#xff0c;但是leader的数据还没同步到follower上去&#xff0c;此时即使选举了follower作为新的leader&#xff…...

【微知】如何查看Mellanox网卡上的光模块的信息?(ethtool -m enp1s0f0 看型号、厂商、生产日期等)

背景 服务器上插入的光模块经常被忽略&#xff0c;往往这里是定位问题最根本的地方。如何通过命令查看&#xff1f; 命令 ethtool提供了-m参数&#xff0c;m是module-info的意思&#xff0c;他是从光模块的eeprom中读取数据。&#xff08;应该是用i2c协议读取的&#xff09;…...

yum源选要配置华为云的源,阿里云用不了的情况

curl -O /etc/yum.repos.d/CentOS-Base.repo https://repo.huaweicloud.com/repository/conf/CentOS-7-reg.repo...

nginx accesslog 打印自定义header

比如我在请求的header中添加了一个path-match-type&#xff0c;那我现在nginx的accesslog 中打印出来&#xff0c;应该如何配置呢&#xff1f; rootnginx-59f5d66df6-jw5k8:/# cat /etc/nginx/nginx.conf user nginx; worker_processes auto;error_log /var/log/nginx/erro…...

好数——前缀和思想(题目分享)

今天我的舍友去参加“传智杯”广东省的省赛&#xff0c;跟我说了这样一道题&#xff0c;他说他想不出来怎么去优化代码&#xff0c;怎么做都是套用两层for循环超时&#xff0c;下面我就根据题意&#xff0c;使用前缀和的算法去优化一下思路&#xff0c;题目本身是不难的&#x…...

MWC 2025 | 移远通信大模型解决方案加速落地,引领服务机器人创新变革

随着人工智能、大模型等技术的蓬勃发展&#xff0c;生成式AI应用全面爆发。在此背景下&#xff0c;服务机器人作为大模型技术在端侧落地的关键场景&#xff0c;迎来了前所未有的发展机遇。 作为与用户直接交互的智能设备&#xff0c;服务机器人需要应对复杂场景下的感知、决策和…...

【大模型基础_毛玉仁】0.概述

更多内容&#xff1a;XiaoJ的知识星球 【大模型基础_毛玉仁】 系列文章参考 系列文章 【大模型基础_毛玉仁】0.概述 【大模型基础_毛玉仁】1.1 基于统计方法的语言模型 更新中。。。。。。 参考 书籍&#xff1a;大模型基础_完整版.pdf Github&#xff1a;https://github.co…...

ADB、Appium 和 大模型融合开展移动端自动化测试

将 ADB、Appium 和 大模型(如 GPT、LLM) 结合,可以显著提升移动端自动化测试的智能化水平和效率。以下是具体的实现思路和应用场景: 1. 核心组件的作用 ADB(Android Debug Bridge): 用于与 Android 设备通信,执行设备操作(如安装应用、获取日志、截图等)。Appium: 用…...

springboot425-基于SpringBoot的BUG管理系统(源码+数据库+纯前后端分离+部署讲解等)

&#x1f495;&#x1f495;作者&#xff1a; 爱笑学姐 &#x1f495;&#x1f495;个人简介&#xff1a;十年Java&#xff0c;Python美女程序员一枚&#xff0c;精通计算机专业前后端各类框架。 &#x1f495;&#x1f495;各类成品Java毕设 。javaweb&#xff0c;ssm&#xf…...

Ubuntu系统上部署Node.js项目的完整流程

以下是在Ubuntu系统上部署Node.js项目的完整流程&#xff0c;分为系统初始化、环境配置、项目部署三个部分&#xff1a; 一、系统初始化 & 环境准备 bash # 1. 更新系统软件包 sudo apt update && sudo apt upgrade -y# 2. 安装基础工具 sudo apt install -y buil…...

X Window---图形接口

摘抄自 鸟哥的linux私房菜 基础篇 第四版 有鉴于图形用户接口(Graphical User Interface, GUI) 的需求日益加重&#xff0c;在 1984 年由 MIT 与其他第三方首次发表了 X Window System &#xff0c;并且更在 1988 年成立了非营利性质的 XFree86 这个组织。所谓的XFree86 其实是…...

数据序列化协议 Protobuf 3 介绍(Go 语言)

Protobuf 3 入门 1. 什么是序列化&#xff1f; 1.1 概念 序列化&#xff08;Serialization 或 Marshalling&#xff09; 是指将数据结构或对象的状态转换成可存储或传输的格式。反向操作称为反序列化&#xff08;Deserialization 或 Unmarshalling&#xff09;&#xff0c;它…...

FineReport 操作注意

1.父单元格重复的时候&#xff0c;如何取消合并 效果如下&#xff1a; 只需要在单元格中&#xff0c;将数据设置为【列表】即可。 2.待定...

3D手眼标定转换详细实施步骤及原理概述

3D手眼标定转换详细实施步骤及原理概述 一、手眼标定的核心目标二、3D手眼标定的原理概述一、基本概念与坐标系定义**二、数学建模与方程推导****1. 坐标变换的齐次矩阵表示****2. 手眼标定方程推导** **三、方程求解方法****1. 分离旋转与平移****2. 旋转矩阵求解****3. 平移向…...

Verilog:SCCB控制器

目录 一、SCCB协议 &#xff08;1&#xff09;SCCB时序 &#xff08;2&#xff09;与I2C的区别 二、Verilog 实现 &#xff08;1&#xff09;设计要求 &#xff08;2&#xff09;设计要点 &#xff08;3&#xff09;模块完整代码 三、功能验证 &#xff08;1&#xff09;写…...

维度建模基础篇:从理论到核心组件解析

维度建模基础篇:从理论到核心组件解析 引言 在数据仓库与商业智能(BI)领域,维度建模​(Dimensional Modeling)作为一种经典的数据组织方法论,自Kimball提出以来,已成为构建高效分析型系统的核心范式1,2,3。其以业务需求为导向,通过事实表与维度表的组合,实现对复杂…...

与中国联通技术共建:通过obdiag分析OceanBase DDL中的报错场景

中国联通软件研究院&#xff08;简称联通软研院&#xff09;在全面评估与广泛调研后&#xff0c;在 2021年底决定采用OceanBase 作为基础&#xff0c;自研分布式数据库产品CUDB&#xff08;即China Unicom Database&#xff0c;中国联通数据库&#xff09;。目前&#xff0c;该…...

大数据与网络安全讲座

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 大数据的价值为大家公认。业界通常以4个“V”来概括大数据的基本特征——Volume(数据体量巨大)、Variety(数据类型繁多)、Value(价值密度低)、Velocity(处理速度快…...

AtCoder Beginner Contest 395 E

点我写题 题意&#xff1a;给个有向图&#xff0c;从1出发&#xff0c;每次可以走一条有向边&#xff0c;花费为1&#xff0c;也可以选择把全部有向边翻转&#xff0c;花费x&#xff0c;问到n的最小花费 思路&#xff1a;最短路dp&#xff0c;定义dis[i][0/1]表示走到i为止&…...

Linux进程管理6 - CFS调度

0、CFS调度器 CFS调度器使用完全公平调度算法。 完全公平调度算法引入虚拟运行时间的概念:虚拟运行时间 = 实际运行时间 * nice_0_weight / 进程的权重。完全公平调度算法使用红黑树把进程按虚拟运行时间从小到大排序,每次调度选择虚拟运行时间最小的进程。时间片 操作系统进…...

张驰咨询:用六西格玛重构动力电池行业的BOM成本逻辑

在动力电池行业&#xff0c;BOM&#xff08;物料清单&#xff09;成本每降低1%&#xff0c;都可能改写企业的利润曲线。某头部企业的三元锂电池BOM成本曾较行业标杆高出11%&#xff0c;单电芯利润率被压缩至3%的生死线。然而&#xff0c;通过张驰咨询的六西格玛方法论&#xff…...