C语言——简易版扫雷

目录

前言

​编辑

 游戏规则

 游戏结构的分析

游戏的设计 

使用多文件的好处有以下几点:

 游戏代码实现

框架(test.c)

 game函数(test.c)

InitBoard初始化(game.c)

 Print打印棋盘(game.c)

Setmine设置雷(game.c)

Findmine排查雷(game.c) 

GetMine  

game.h

game.c

exe程序

 Debug和Release的区别



前言

扫雷游戏是一种益智类的游戏,目标是通过揭示方块上的数字来找到不带雷的方块,避免触雷。 


 游戏规则

玩家的目标是根据已翻开的方块信息来推测出地雷的位置,并避开它们。每个方块要么是空白,要么显示数字。数字表示该方块周围八个方向上的地雷数量。通过使用数字信息和逻辑推理,玩家可以确定哪些方块是安全的,哪些是地雷。当玩家翻开所有非地雷方块时,游戏胜利。如果玩家不慎踩到地雷,游戏失败。


 游戏结构的分析

扫雷的过程中,布置的雷和排查出的雷的信息都需要存储,所以我们需要⼀定的数据结构来存储这些 信息。

所以我们首先会想到一个9*9的矩阵。

我们将有雷的设置为“1”,没雷的地方设置为“0”

示例

0123456789
1010000000
2000000000
3000001010
4100100000
5000000000
6000000000
7001000001
8000010000
9100000100

假设我们排查(5,3),在(5,3)周围的一圈有雷,则会在屏幕上记起来。

这就是我们想要设计的样子,但是当我们想访问(6,9)的时候,我访问就会越界,到了界外去了,为了解决这一问题,我们将表格变成11*11的模型,这就能很好的解决这个问题。

0123456789
1010000000
2000000000
3000001010
4100100000
5000000000
6000000000
7001000001
8000010000
9100000100

继续分析,我们已经设置了数字“1”为雷,“0”为非雷,当我们排查到一个雷时,需要将这个雷的信息储存起来,然后将它打印出来,作为排雷的重要参考信息的。。那这个雷的个数信息存放在哪⾥呢?如果存放在布 置雷的数组中,这样雷的信息和雷的个数信息就可能或产⽣混淆和打印上的困难。

将雷和⾮雷的信息不要使⽤数字,使⽤某些字符就⾏,这样就避免冲 突了,但是这样做棋盘上有雷和⾮雷的信息,还有排查出的雷的个数信息,就⽐较混杂,不够⽅便。

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

mine数组

01234567891011
0
1‘1’‘0’‘0’‘0’‘0’‘0’‘0’‘1’‘0’‘0’
2‘0’‘0’‘0’‘0’‘0’‘0’‘0’‘0’‘0’‘1’
3‘0’‘0’‘0’‘0’‘1’‘0’‘0’‘0’‘0’‘0’
4‘0’‘1’‘0’‘0’‘0’‘0’‘0’‘0’‘1’‘0’
5‘0’‘0’‘0’‘0’‘0’‘0’‘0’‘0’‘0’‘0’
6‘0’‘0’‘0’‘0’‘1’‘0’‘0’‘0’‘0’‘0’
7‘1’‘0’‘0’‘0’‘0’‘0’‘0’‘0’‘1’‘0’
8‘0’‘0’‘0’‘0’‘0’‘0’‘0’‘0’‘0’‘0’
9‘0’‘0’‘0’‘0’‘1’‘0’‘0’‘0’‘0’‘0’
10‘0’‘0’‘0’‘0’‘0’‘0’‘0’‘0’‘0’‘0’
11

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

对于show数组就是将所有‘0’和‘1’换成‘*’这里就不展示了,不水字数了。


游戏的设计 

使用多文件的好处有以下几点:

  • 1. 组织性好:将代码划分到不同的文件中,可以更好地组织和管理代码。每个文件可以分别负责不同的功能模块,使代码结构更清晰。

  • 2. 可维护性强:多文件的编程方式使得修改或更新某个功能模块变得更加简单。只需修改相应的文件,不需要修改整个程序。

  • 3. 可重用性高:将一些常用的函数或功能封装到单独的文件中,可以在多个项目中复用这些代码。

  • 4. 编译效率高:当调用某个函数时,编译器只需要编译包含该函数的文件,而不需要重新编译整个程序,提高了编译速度。

  • 5. 可扩展性强:如果需要添加新的功能模块,只需添加一个新的文件,不会对原有代码造成影响。

  • 6. 可测试性好:每个文件可以独立地进行测试,便于定位和修复问题。

总之,使用多文件的编程方式可以提高代码的组织性、可维护性、可重用性和扩展性,提高编译效率和测试效率。

在这个扫雷中我们需要:

game.h         ⽂件中写游戏需要的数据类型和函数声明等

game.c         ⽂件中写游戏中函数的实现等

text.c            ⽂件中写游戏的测试逻辑


 游戏代码实现

框架(test.c)

我们写个基础的框架。将头文件都放在game.h里面,就需要包含头文件,而我们自己的头文件要用“”。

#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
int main()
{text();return 0;
}

我们进入text函数是,打印菜单menu(),让玩家进行选择,是进入游戏,还是退出游戏。

void menu()
{printf("******************\n");printf("***** 1.game *****\n");printf("***** 0.exit *****\n");printf("******************\n");
}

 函数进来是直接do-while进行打印菜单,然后供玩家选择,选择1进入游戏,0退出游戏,若输入以外的内容则会提示出错误,需要重新输入。

void text()
{int input = 0;srand((unsigned int)time(NULL));//这是播种由函数 rand 使用的随机数发生器。//我们先放在这里do{menu();printf("请输入你的选择:");scanf("%d", &input);switch(input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("选择错误,请重新输入:");break;}} while (input);
}

 game函数(test.c)

我们整体思路是将数组初始化,mine初始化为‘0’,show初始化为‘*’;随后布置地雷,我们初始化和布置雷好后都能打印一下看看是否符合我们的要求。最后进行排查地雷,将所有的雷找出来就行了。

void game()
{char mine[ROWS][COLS] ;char show[ROWS][COLS] ;//初始化InitBoard(mine, ROWS, COLS, '0'); InitBoard(show, ROWS, COLS, '*');//打印棋盘Print(show, ROWS, COLS);/*Print(mine, ROWS, COLS);*///布置地雷Setmine(mine, ROW ,COL);//排查地雷Findmine(mine,show,ROW,COL);
}

InitBoard初始化(game.c)

对数组mine和show进行初始化,将mine的数组全部初始化为‘0’,show初始化为‘*’。如果只是简单的在数组中初始化化‘0’,‘*’。我们传入应该char set就能够让代码更加灵活,不用在写一样的代码浪费时间和空间。

void InitBoard(char arr[ROWS][COLS], int rols, int cols,char set)
{for (int i = 0; i < rols; i++){for (int j = 0; j < cols; j++){arr[i][j] = set;//'0' , '*'}}
}

 Print打印棋盘(game.c)

对数组mine和数组show进行打印虽然我们设置的是11*11的棋盘,但是对于玩家来说他们只需要再9*9的棋盘里面进行排查雷就行了,所以我们打印的是9*9的棋盘。在加上坐标,能让玩家更精确的定位。

void Print(char arr[ROWS][COLS], int rols, int cols)
{printf("-----扫雷游戏——————\n");//让界面整体更加美观for (int i = 0; i < rols - 1 ; i++){printf("%d ", i);}printf("\n");for (int i = 1; i < rols - 1; i++){printf("%d ", i);for (int j = 1; j < cols - 1; j++){printf("%c ", arr[i][j]);}printf("\n");}
}

Setmine设置雷(game.c)

我们只需要在9*9的棋盘随机布置雷就行了,这时需要用到rand这个函数rand()%row = 8 再加1。

void Setmine (char board[ROWS][COLS], int row, int col)
{int count = minebox;while(count){//设置行数和列数的随机int x = rand() % row + 1;int y = rand() % col + 1;if (board[x][y] == '0'){board[x][y] = '1';count--;}}
}

需要的头文件 

 rand---->  #inlcude<stdlib.h>

 time---->  #include<time.h>

Findmine排查雷(game.c) 

开始我们需要踹按创建变量x和y,供玩家输入坐标,我们的坐标只有1~9所以需要  0<x<10,0<y<10作为条件,这个坐标之外的为非法最标,需要重新输入如果玩家排查的坐标是雷,那么游戏结束,并打印棋盘。如果不是雷,我们需要统计一下它周围有几个雷,这就需要统计雷GetMine,将雷的信息传到数组show上,个数统计出来还要加上‘0’;如果仅仅是这样的话游戏是不会结束的,还需要给whle加上条件win< row * col - minebox(minebox是雷的数量),每次没排查到雷级win++。

如果有耐心的坚持去玩,那么肯定是能玩完的,前提是没被炸死哈。

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 - minebox){printf("请输入要扫的坐标:");scanf("%d %d", &x, &y);if (x > 0 && x < row && y >0 && y < col){system("cls");if (mine[x][y] == '1'){printf("你被炸死了,游戏失败\n");Print(show, ROWS, COLS);break;}else {int count = GetMine(mine, x, y);show[x][y] = count + '0';Print(show, ROWS, COLS);win++;}}else{printf("非法输入\n");}}if (win == row * col - minebox){printf("恭喜你,排雷成功\n");Print(mine, ROW, COL);}}

system("cls")的头文件跟rand的一样

GetMine  

static是静态的意思,静态函数只能在声明它的文件中可见,其他文件不能引用该函数。

‘1’的值是49;'0'的值是48;‘1’-‘0’=1是个整数。我们将周边的数都加起来-8*‘0’就能得到雷的数。

static int GetMine(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');
}

game.h

#define ROW 9 //行数
#define COL 9 //列数#define ROWS ROW+2 
#define COLS COL+2#define minebox 10 //雷的个数#include<stdio.h>   //main函数的头文件
#include<time.h>    //time函数的头文件
#include<stdlib.h>  //system,rand函数的头文件//初始化棋盘
void InitBoard(char arr[ROWS][COLS], int rols, int cols, char set);//打印棋盘
void Print(char arr[ROWS][COLS], int rols, int cols);//设置雷
void Setmine(char arr[ROWS][COLS], int x, int y);//找雷
void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

game.c

同理,game.c要使用game.h的东西也得包含头文件。

到这里,我们这个简易版的扫雷就实现了。

怎么把代码编程可发布的exe程序呢?


exe程序

  1. 将debug模式改为Release模式。
  2. 打开“项目”点击属性。
  3. 打开“C/C++”下的“代码生成”将“运行库”改为多线程(/MT)
  4. “Ctrl+F5”运行程序,这里exe的程序就出现在文件夹里面了。
  5. 打开我们存放代码的文件夹找到x64里面会有两个文件夹,一个是Debug,一个是Relase,点开,我们就能看到一个exe的程序后缀,这样就能直接发给其他人。

 Debug和Release的区别

Debug和release是软件开发中常见的两种构建(build)模式,它们在编译、优化和调试方面有以下区别:

  • 1. 编译方式:Debug模式通常会生成包含调试信息的可执行文件,以便在调试过程中能够准确定位代码的问题。而release模式会采用更高级别的优化和压缩,生成体积更小、性能更高的可执行文件。
  • 2. 优化级别:Debug模式通常会使用较低级别的优化,以便更好地保留源代码的结构和逻辑,使得调试更容易。而release模式会使用更高级别的优化,以提高程序的运行性能。
  • 3. 调试信息:Debug模式会保留更多的调试信息,如变量名、函数名等,以便在调试器中能够查看和修改这些信息。而release模式会舍弃部分调试信息,以减小可执行文件的体积。
  • 4. 异常处理:Debug模式通常会提供更多的异常信息,使得在程序出错时能够更方便地定位问题。而release模式会舍弃部分异常信息,以提高程序的性能和稳定性。

总之,Debug模式适用于开发和调试阶段,能够提供更多的调试信息和更好的可读性;而release模式适用于发布阶段,能够提供更高的性能和较小的体积。在实际开发中,通常会进行Debug模式的开发和调试,然后再切换到release模式进行最终的发布。

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

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

相关文章

掘根宝典之C++迭代器简介

在C中&#xff0c;容器是一种用于存储和管理数据的数据结构。C标准库提供了多种容器&#xff0c;每种容器都有其独特的特点和适用场景。 我们知道啊&#xff0c;我们可以通过下标运算符来对容器内的元素进行访问&#xff0c;但是只有少数几种容器才同时支持下标运算符&#xf…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的商品识别系统(深度学习+UI界面+训练数据集+Python代码)

摘要&#xff1a;在零售行业的技术进步中&#xff0c;开发商品识别系统扮演着关键角色。本博文详细阐述了如何利用深度学习技术搭建一个高效的商品识别系统&#xff0c;并分享了一套完整的代码实现。系统采用了性能强劲的YOLOv8算法&#xff0c;同时对YOLOv7、YOLOv6、YOLOv5等…

Linux操作系统与Windows文件互传(FTP)

一、开启Ubuntu下的FTP服务 打开Ubuntu的终端窗口&#xff0c;然后执行如下命令来安装 FTP服务。 sudo apt-get install vsftpd等待软件安装完成后&#xff0c;用输入以下命令打开vsftpd.conf文件 sudo vim /etc/vsftpd.conf 找到下图的两个使能语句改成如图即可(记住保存后再…

Beans模块之工厂模块BeanFactoryAware

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

专题二 - 滑动窗口 - leetcode 904. 水果成篮 | 中等难度

leetcode 904. 水果成篮 leetcode 904. 水果成篮 | 中等难度1. 题目详情1. 原题链接2. 基础框架 2. 解题思路1. 题目分析2. 算法原理3. 时间复杂度 3. 代码实现4. 知识与收获 leetcode 904. 水果成篮 | 中等难度 1. 题目详情 你正在探访一家农场&#xff0c;农场从左到右种植…

比特币普通地址、隔离见证(兼容)、隔离见证(原生)、Taproot 地址傻傻分不清楚

我们在使用比特币钱包的时候&#xff0c;可以看到各种地址类型&#xff1a;普通地址、隔离见证&#xff08;兼容&#xff09;、隔离见证&#xff08;原生&#xff09;、Taproot 地址。 看得我们一脸懵逼&#xff0c;为什么会有这么多种类型的地址&#xff1f; 它们之间都有什么…

C语言 指针(4) qsort函数

目录 前言 一、回调函数 二、qsort函数 2.1 使用qsort函数排序整型数据 2.2 使用qsort排序结构数据 三、qsort函数的模拟实现 总结 前言 今天我们主要来学习一下C语言中的qsort排序函数。 一、回调函数 回调函数就是⼀个通过函数指针调用的函数。 如果你把函数的指针&a…

spring启动时如何自定义日志实现

一、现象 最近在编写传统的springmvc项目时&#xff0c;遇到了一个问题&#xff1a;虽然在项目的web.xml中指定了log4j的日志启动监听器Log4jServletContextListener&#xff0c;且开启了日志写入文件&#xff0c;但是日志文件中只记录业务代码中我们声明了日志记录器的日志&a…

力扣98、530、501-java刷题笔记

一、98. 验证二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 1.1题目 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左 子树 只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点…

[leetcode~dfs]1261. 在受污染的二叉树中查找元素

给出一个满足下述规则的二叉树&#xff1a; root.val 0 如果 treeNode.val x 且 treeNode.left ! null&#xff0c;那么 treeNode.left.val 2 * x 1 如果 treeNode.val x 且 treeNode.right ! null&#xff0c;那么 treeNode.right.val 2 * x 2 现在这个二叉树受到「污…

C#四部曲(知识补充)

Unity跨平台原理 .Net相关 只要编写的时候遵循.NET的这些规则&#xff0c;就能在.NET平台下通用 各种源码→根据.NET规范编写→(虚拟机)生成CIL中间码(保存在程序集中)→转成操作系统原代码 跨语言← 跨平台↓ Unity跨平台原理&#xff08;Mono&#xff09; c#脚本→MonoC#编…

MySQL 事务的原理以及长事务的预防和处置

transaction_isolation 隔离级别 读未提交 读提交 视图是在每个 SQL 语句开始执行的时候创建的 可重复读 视图是在事务启动时创建的&#xff0c;整个事务存在期间都用这个视图 串行化…

安装OneNote for Win10 | Win10/Win11

前言 PC端的OneNote分为2个版本&#xff0c;分别是Microsoft Store版本和Office版本&#xff0c;Microsoft Store版本即为OneNote for Win10&#xff0c;此版的OneNote有最近笔记功能&#xff0c;但检索功能不如Office版本&#xff0c;个人认为2个版本各有优劣。 但OneNote f…

【硬件基础】电容的选型

1、电容的理论基础 电容器的本质就是储能&#xff0c;充放电 根据作用可分为&#xff1a;滤波电容&#xff0c;旁路电容&#xff0c;耦合电容&#xff0c;退耦电容&#xff0c;自举电容 2、电容的取值 计算取值&#xff0c;查手册&#xff0c;经验取值 3、电容的选取 分为铝…

“删边“的并查集------反向并查集

目录 1.题目2.思路3.代码 默认大家都会并查集了 1.题目 小美认为&#xff0c;在人际交往中&#xff0c;但是随着时间的流逝&#xff0c;朋友的关系也是会慢慢变淡的&#xff0c;最终朋友关系就淡忘了。 现在初始有一些朋友关系&#xff0c;存在一些事件会导致两个人淡忘了他们…

AssetBundle打包与加载

官方文档 参照视频 1.AssetBundle打包 1.1设置资源的命名和后缀 命名只支持小写 1.2创建Editor文件夹&#xff0c;在里面创建编辑器打包AssetBundle的脚本 using UnityEditor; using System.IO;public class CreateAssetBundles {[MenuItem("Assets/Build AssetBun…

旅游景区公共广播 园区广播 公路服务区广播

旅游景区公共广播 园区广播 公路服务区广播 旅游景区公共广播 旅游景区公共广播(又称背景音乐)简称BGM&#xff0c;它的主要作用是掩盖噪声并创造一种轻松和谐的气氛&#xff0c;是一种创造轻松愉快环境气氛的音乐。掩盖环境噪声&#xff0c;创造与旅游景区相适应的气氛&#…

遥感云计算的一个拐点

GeoForge&#xff0c;一个值得关注的遥感大数据应用 简介 GeoForge是由Ageospatial公司开发的一个基于大语言模型(GeoLLMs)的地理空间分析平台。GeoForg的目的是使每个人都可以轻松进行地图绘制和地理空间分析&#xff0c;无论您是外行还是专家。 Geo for ChatGPT 作者团队已…

07-java基础-锁之AQSReentrantLockBlockingQueueCountDownLatchSemapho

文章目录 0&#xff1a;AQS简介-常见面试题AQS具备特性state表示资源的可用状态AQS定义两种资源共享方式AQS定义两种队列自定义同步器实现时主要实现以下几种方法&#xff1a;同步等待队列条件等待队列 1&#xff1a;AQS应用之ReentrantLockReentrantLock如何实现synchronized不…

双环PID控制详细讲解

参考博客&#xff1a; &#xff08;1&#xff09;PID双环控制&#xff08;速度环和位置环&#xff09; &#xff08;2&#xff09;PID控制&#xff08;四&#xff09;&#xff08;单环与双环PID&#xff09; &#xff08;3&#xff09;内外双环pid算法 0 单环PID 目标位置→系…