【C语言项目】扫雷(详解,附图、附代码示范)

文章目录

  • 项目思路
  • 一、分文件进行创建
  • 二、进入游戏前的目录
    • 2.1 目录的功能:
    • 2.2 目录界面:
    • 2.3 选择进入或退出游戏
      • 2.3.1 代码示范
      • 2.3.2 图片示例:
  • 三、画出游戏界面
    • 3.1 创建两个数组
    • 3.2 初始化数组
    • 3.3 打印游戏界面
      • 3.3.1 代码思路
      • 3.3.2 代码示范:
  • 四、用随机值放雷
    • 4.1 代码思路:
    • 4.2 代码示范:
  • 五、游玩扫雷
    • 5.1 代码思路:
    • 5.2 注意事项:
    • 5.3 代码实现:
  • 六、整体代码示范
    • game.h
    • test.c
    • game.c
  • 写在最后

项目思路

  1. 分文件进行创建
  2. 进入游戏前的目录
  3. 画出游戏界面
  4. 用随机值放雷
  5. 游玩扫雷

接下来,我们分步骤进行详细的解释说明。

一、分文件进行创建

在具体的项目实施中,我们需要分成不同的文件进行创建和书写,以此来保证项目的模块化。
那么在扫雷的实际书写中,

  • 源文件:
    • 测试游戏用的代码文件用test.c或者日期.c来作为文件名
    • 游戏实现的底层代码用game.c文件作为文件名
  • 头文件
    • 游戏实现中使用的各个函数的声明,以及包含的其他库函数的头文件需要写在头文件game.h文件里
      如图所示:
      image.png

二、进入游戏前的目录

2.1 目录的功能:

  1. 在游戏开始时,给玩家视觉上的帮助和提示
  2. 让玩家可以选择进入游戏或者退出游戏
  3. 将游戏形成一个可以不断重玩的循环
    接下来,我们分步骤进行书写:

2.2 目录界面:

void menu()
{printf("***********************\n");printf("*****1、开始游戏*******\n");printf("*****0、退出游戏*******\n");printf("***********************\n");
}

接着,在main函数里面进行调用:

int main()
{menu();return 0;
}

这样目录的表面就写好了,接下来需要写玩家选择进入游戏和退出游戏的功能了

2.3 选择进入或退出游戏

选择功能的逻辑:1进入游戏,0退出游戏。
显然,必备的库函数有scanf,switch、case和default。为了让游戏的体验更加良好,可以再加一个printf增加视觉上的游玩帮助,用户友好。
那么根据刚刚的逻辑,可以写出如下的选择结构,其中game函数虽然还没有写出来,但是整体的框架可以先确定下来,之后再往里慢慢写内容。

2.3.1 代码示范

int main()
{int input = 0;menu();printf("请选择:--->");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("非法输入!请重试\n");break;}return 0;
}

2.3.2 图片示例:

image.png

三、画出游戏界面

3.1 创建两个数组

因为扫雷是一个隐藏式的游戏,放雷的数组玩家是不能看到的,所以需要两个数组,一个用来存放雷,一个用来展示给玩家隐藏后的界面,用来游玩。
创建数组代码示范:

	char mine[ROWS][COLS];char show[ROWS][COLS];

这里的行和列,用自定义变量来代替,这样以后在想更改行列的时候就可以很方便了
自定义变量代码在头文件game.h中,代码示范:

#define ROW 9
#define COL 9

3.2 初始化数组

现在数组已经创建好了,由于没有进行初始化,数组里放的是一些“烫烫烫”之类的乱码。
所以需要写一个函数,给这两个数组进行初始化,这一步也是为之后的重玩奠定了基础。
代码思路:遍历数组每一个元素并赋值。
由于是给数组赋值,直接通过地址操作数组的,所以不需要返回值,直接void类型就可以。
至于接收值,需要接收:数组名、以及需要赋值的符号,这样才能让函数有效的对不同的数组进行初始化。

代码示范:

void InitBoard(char board[ROWS][COLS], int row, int col, char set)
{for (i = 0; i < row; i++){for (j = 0; j < col; j++){board[i][j] = set;}}
}

在game里面的函数:

void game() 
{char mine[ROWS][COLS];//用mine数组来放雷char show[ROWS][COLS];//用show数组来展示隐藏后的雷区InitBoard(mine, ROWS, COLS,'0');//把放雷的数组赋值成全0,这样可以方便之后的扫雷显示InitBoard(show, ROWS, COLS, '*');//把隐藏后的雷区赋成*(这个换其他的符号也可以)
}

3.3 打印游戏界面

3.3.1 代码思路

由于打印游戏界面是一个需要频繁进行的操作,无论是每次扫雷,还是被炸死的时候显示雷的位置,都需要打印。所以在这里,我们同样需要单独写一个函数来完成这个操作。

  1. 遍历数组并打印
  2. 返回值:由于是直接打印,是一个动作,所以做完后直接销毁就行,void类型
  3. 接收值:需要接收需要打印的数组、行、列
  4. 注意事项:
    1. 标头可以打印一个扫雷游戏分割线
    2. 在合适的地方加上换行,以保证游戏界面是9x9的正方形
    3. 在边缘处加上行和列的标号,以便玩家更方便的看到想扫的雷的坐标
    4. 注意是char数组,用%c 来打印,每个元素后面最好加空格,每一句后最好加换行
    5. 注意打印时数组的下标要从1开始,不要从0开始,否则扫雷的时候会向右下偏一位

3.3.2 代码示范:

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{printf("------扫雷游戏------\n");for (i = 0; i <= row; i++){printf("%d ", i);	//在第一行打印列数}printf("\n");for (i = 1; i <= row; i++){printf("%d ", i);//在第一列打印行数for (j = 1; j <= col; j++){printf("%c ", board[i][j]);//打印每一位元素}printf("\n");}
}

图片示例:image.png

四、用随机值放雷

4.1 代码思路:

  1. 首先放雷是需要一个随机性的,那么就可以使用srand和rand函数(伪随机数),加上时间戳,构成一个真随机数,再利用这个真随机数取一个行列的模,就可以实现随机的放雷了。
  2. 随机取十个坐标,把mine里面的数字放成1,10个雷全部放完之后就有71个0和10个1。
  3. 在实现代码的时候需要注意,随机取的坐标不能重复,需要是0才能赋1。
  4. 一共只需要十个雷,while循环,再用一个int count来计算真实赋进去的雷的个数,就可以实现随机放雷了。
  5. 由于还是远程操作数组,所以返回值是void,接收值仍然是数组和行列。
  6. 在雷数方面,可以通过自定义变量来方便以后的操作。

4.2 代码示范:

void SetMine(char board[ROWS][COLS], int row, int col)
{int count = EASY_COUNT;while (count) {i = rand() % row+1;j = rand() % col+1;if (board[i][j] == '0'){board[i][j] = '1';count--;}}
}

头文件的代码:

#define EASY_COUNT 10

五、游玩扫雷

5.1 代码思路:

  1. printf进行视觉提示,scanf让玩家输入坐标
  2. 将坐标所处的数组元素进行判断
    1. 如果是雷,游戏结束
    2. 如果不是雷,统计该地点周围8个点位的雷数,并显示在棋盘上
    3. 如果位置超出棋盘范围,则重新输入
    4. 此过程不断循环,直到除了雷以外的所有点位被排干净,判定玩家赢

5.2 注意事项:

  1. 如果该点位处于边角位,如果统计周边8个点位,数组会越界,所以需要把数组多拓两行,避免越界
  2. 数字和字符的相互转换:加上‘0’。比如如果想要把数字1转换为字符1,就需要加一个字符0,原理是0的ASCII码值是48,1的ASCII码值是49……加上字符0相当于加上48,正好是字符1的ASCII码值

5.3 代码实现:

void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS] ,int row, int col)
{int win = 0;while (win < col * row - EASY_COUNT){printf("请输入要排查的坐标>:");scanf("%d %d", &i, &j);if (i > 0 && i <= row && j > 0 && j <= col){if (mine[i][j] == '1'){printf("很遗憾,你被炸死了\n");DisplayBoard(mine, ROW, COL);break;}else{int count = GetCountMine(mine, i, j);show[i][j] = count + '0';DisplayBoard(show, ROW, COL);win++;}}elseprintf("位置非法,请重新输入");}if (win == col * row - EASY_COUNT){printf("恭喜你,游戏胜利!\n");}
}

六、整体代码示范

game.h

#pragma once
#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_COUNT 10void InitBoard(char board[ROWS][COLS],int row,int col,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 board[ROWS][COLS], int row, int col);

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#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];InitBoard(mine, ROWS, COLS,'0');InitBoard(show, ROWS, COLS, '*');//DisplayBoard(mine, ROW, COL); 这里的展示棋盘是用来测试代码用的,实际应用不需要DisplayBoard(show, ROW, COL);SetMine(mine, ROW, COL);//DisplayBoard(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;
}

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"int i, j = 0;
void InitBoard(char board[ROWS][COLS], int row, int col, char set)
{for (i = 0; i < row; i++){for (j = 0; j < col; j++){board[i][j] = set;}}
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{printf("------扫雷游戏------\n");for (i = 0; i <= row; i++){printf("%d ", i);	}printf("\n");for (i = 1; i <= row; i++){printf("%d ", i);for (j = 1; j <= col; j++){printf("%c ", board[i][j]);}printf("\n");}
}void SetMine(char board[ROWS][COLS], int row, int col)
{int count = EASY_COUNT;while (count) {i = rand() % row+1;j = rand() % col+1;if (board[i][j] == '0'){board[i][j] = '1';count--;}}
}int GetCountMine(char mine[ROWS][COLS] ,int x,int y)
{return (mine[x - 1][y + 1] + mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y + 1] + mine[x][y - 1] + mine[x + 1][y + 1] + mine[x + 1][y] + mine[x + 1][y - 1] - 8 * '0');
}void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS] ,int row, int col)
{int win = 0;while (win < col * row - EASY_COUNT){printf("请输入要排查的坐标>:");scanf("%d %d", &i, &j);if (i > 0 && i <= row && j > 0 && j <= col){if (mine[i][j] == '1'){printf("很遗憾,你被炸死了\n");DisplayBoard(mine, ROW, COL);break;}else{int count = GetCountMine(mine, i, j);show[i][j] = count + '0';DisplayBoard(show, ROW, COL);win++;}}elseprintf("位置非法,请重新输入");}if (win == col * row - EASY_COUNT){printf("恭喜你,游戏胜利!\n");}
}

写在最后

如果本文对您有帮助,可不可以给我一个小小的点赞呀❤~您的支持是我最大的动力。

博主小白一枚,才疏学浅,难免有所纰漏,欢迎大家讨论和提出问题,博主一定第一时间改正。

谢谢观看嘿嘿(๑•̀ㅂ•́)و✧~!

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

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

相关文章

gin框架内容(二)

上一篇过于gin的内容 https://mp.csdn.net/mp_blog/creation/editor/131953861 CSDNhttps://mp.csdn.net/mp_blog/creation/editor/131953861 一、路由组 为了管理具有相同前缀的URL, 将拥有URL共同前缀的路由划分为一组 为了代码的阅读性&#xff0c;使用{}包裹相同组的路由…

WPF icon的设置

想给控件设置个圆形图片&#xff0c;代码如下&#xff1a; ​<Setter Property"Icon"><Setter.Value><Image Source"/WpfApp1;component/Resource/1.ico" Width"16" Height"16"/></Setter.Value></Setter&…

ncnn-android-yolov7跑自己模型的注意事项

ncnn-android-yolov7 这是一个示例 ncnn android 项目&#xff0c;它依赖于 ncnn 库和 opencv https://github.com/Tencent/ncnn https://github.com/nihui/opencv-mobile https://github.com/xiang-wuu/ncnn-android-yolov7 如何构建和运行 步骤1 https://github.com/Ten…

linux 在excel里面找内容

linux 在excel里面找内容 背景&#xff1a;在大数据行业中&#xff0c;很多数据源是excel文件&#xff0c;但是常常会出现查找excel内容找到对应的文件&#xff0c;所以制作了简单的shell脚本方便查询对应的excel文件 查看下面精简的内容即可&#xff0c;开箱即用 shell转换 …

vue项目实现数组中添加多个相同的对象

在写项目的时候&#xff0c;有时候想有一个有较大length的对象数组&#xff0c;则可以使用如下的方法&#xff1a; export default {data() {const item {date: 2016-05-02,name: 王小虎,address: 上海市普陀区金沙江路 1518 弄};return {tableData: Array(20).fill(item)}} …

将Parasoft和ChatGPT相结合会如何?

ChatGPT是2023年最热门的话题之一&#xff0c;是OpenAI训练的语言模型。它能够理解和生成自然语言文本&#xff0c;并接受过大量数据的训练&#xff0c;包括用各种编程语言编写的许多开源项目的源代码。 软件开发人员可以利用大量的知识库来协助他们的工作&#xff0c;因为它具…

「预告」飞凌嵌入式邀您相约第13届配电技术应用论坛

2023年8月3日~5日&#xff0c;第十三届配电技术应用论坛即将在浙江杭州举行&#xff0c;飞凌嵌入式受邀参加。 作为助力快速实现“双碳”目标和新型电力系统建设&#xff0c;加强“双碳”目标下的智能配电网技术研发布局的主要会议&#xff0c;第十三届配电技术应用论坛将从政…

FPGA开发:按键消抖

按键是FPGA开发板上的重要交互元件&#xff0c;因为按键的内部的结构设计&#xff0c;在按下和松开按键时&#xff0c;按键会无法避免地产生机械抖动&#xff0c;因此要对按键输入进行特殊处理&#xff0c;否则可能会因为机械抖动产生意外的重复触发。 按键消抖有很多方法&…

C++设计模式之模板方法、策略模式、观察者模式

面向对象设计模式是”好的面向对象设计“&#xff0c;所谓”好的面向对象设计“指的是可以满足”应对变化&#xff0c;提高复用“的设计。 现代软件设计的特征是”需求的频繁变化“。设计模式的要点是”寻求变化点&#xff0c;然后在变化点处应用设计模式&#xff0c;从而更好地…

我的2023上半年总结

Hi~C站的小伙伴们好久不见哇&#xff01;釉色终于回到C站&#xff0c;开始要输出了&#xff01;这一篇文章是我的2023上半年的总结&#xff0c;以此&#xff0c;致敬那段迷茫但又不曾被辜负的时光。 文章目录 总括——你愿意花五分钟时间读读我的文章吗学习——制定目标&#…

【Matlab】基于粒子群优化算法优化BP神经网络的时间序列预测(Excel可直接替换数据)

【Matlab】基于粒子群优化算法优化BP神经网络的时间序列预测&#xff08;Excel可直接替换数据&#xff09; 1.模型原理2.数学公式3.文件结构4.Excel数据5.分块代码5.1 fun.m5.2 main.m 6.完整代码6.1 fun.m6.2 main.m 7.运行结果 1.模型原理 基于粒子群优化算法&#xff08;Pa…

nsq整体架构及各个部件作用详解

文章目录 前言 nsq的整体架构图 部件&#xff1a;nsqd 部件&#xff1a;nsqlookupd 部件&#xff1a;nsq连接库 部件&#xff1a;nsqadmin 前言 上两篇博客 centos环境搭建nsq单点_YZF_Kevin的博客-CSDN博客 linux环境搭建nsq集群_YZF_Kevin的博客-CSDN博客 我们讲了nsq是…

桥梁安全监测系统中数据采集上传用 什么?

背景 2023年7月6日凌晨时分&#xff0c;G5012恩广高速达万段230公里加80米处6号大桥部分桥面发生垮塌&#xff0c;导致造成2车受损后自燃&#xff0c;3人受轻伤。目前&#xff0c;四川省公安厅交通警察总队高速公路五支队十四大队民警已对现场进行双向管制。 作为世界第一桥梁…

Hadoop 之 Spark 配置与使用(五)

Hadoop 之 Spark 配置与使用 一.Spark 配置1.Spark 下载2.单机测试环境配置3.集群配置 二.Java 访问 Spark1.Pom 依赖2.测试代码1.计算 π 三.Spark 配置 Hadoop1.配置 Hadoop2.测试代码1.统计字符数 一.Spark 配置 环境说明环境版本AnolisAnolis OS release 8.6Jdkjava versi…

mac使用mvn下载node-sass 会Binary download failed, trying source

m1 上使用nvm 以下node的版本可以直接下载&#xff08;Binary download&#xff0c;而不是 trying source&#xff09;而不用切换mac cpu架构 zhiwenwenzhiwenwendeMBP cockpit % nvm install 14.15.5 Downloading and installing node v14.15.5... Downloading https://node…

Windows环境下git客户端中的git-bash和MinGW64

我们在 Windows10 操作系统下&#xff0c;安装了 git 客户端之后&#xff0c;可以通过 git-bash.exe 打开一个 shell&#xff1a; 执行一些 linux 系统里的命令&#xff1a; 注意到上图紫色的 MINGW64. Mingw-w64 是原始 mingw.org 项目的改进版&#xff0c;旨在支持 Window…

SpringCloud学习路线(12)——分布式搜索ElasticSeach数据聚合、自动补全、数据同步

一、数据聚合 聚合&#xff08;aggregations&#xff09;&#xff1a; 实现对文档数据的统计、分析、运算。 &#xff08;一&#xff09;聚合的常见种类 桶&#xff08;Bucket&#xff09;聚合&#xff1a; 用来做文档分组。 TermAggregation&#xff1a; 按照文档字段值分组…

Flutter Windows通过嵌入Native窗口实现渲染视频

Flutter视频渲染系列 第一章 Android使用Texture渲染视频 第二章 Windows使用Texture渲染视频 第三章 Linux使用Texture渲染视频 第四章 全平台FFICustomPainter渲染视频 第五章 Windows使用Native窗口渲染视频&#xff08;本章&#xff09; 文章目录 Flutter视频渲染系列前言…

文心一言大模型测评

访问地址 文心一言服务请求地址&#xff1a;文心千帆大模型 (baidu.com) 新手可以先实名认证后再申请使用 测评 普通对话 这里先和他进行简单的问题讨论 编程相关 询问他有关代码的内容 确实可以生成代码&#xff0c;但不像chatgpt那样提供复制按钮 我们接下来让他生成…

LeetCode45.Jump-Game-II<跳跃游戏II>

题目&#xff1a; 思路&#xff1a; 从上次大神那里获得的灵感 这题问的是次数,那么我们需要确保 1,能否跳到终点 2,得到次数. 第一次条获得的是nums[0],那么第一个数就是我们第一次能跳跃的范围.每次在范围里获得最大值.并且次数加一.然后进入下一次范围;即可得到次数; 代码…