初阶c语言:趣味扫雷游戏
目录
前言
制作菜单
构建游戏选择框架
实现游戏功能
模块化编程:查看前节三子棋的内容
初始化雷区
编辑
优化棋盘
随机埋入地雷
点击后的决策
实现此功能代码
game();的安排
前言
《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非地雷的格子,同时避免踩到地雷,踩到一个地雷全盘皆输。
玩家需要在雷区中,将所有地雷一一排查出来:9x9规格
test.c - - - - 测试游戏的逻辑
game.c - - - - 游戏代码的实现
game.h - - - - 游戏代码的声明 ( 函数声明,符号定义 )
制作菜单
在玩游戏时,我们在进入游戏都会有菜单选项,选择开始游戏,推出游戏等这些指令,说到选择,那么我们可以依据我们所学的循环和分支语句来先完成基本框架的设计。
首先我们进入游戏都是先显示选项,做出选择,并且在玩游戏时玩一局,还想玩怎么办(想一想我们前边的知识哪种结构符合先进入游戏出现菜单再循环这一需求)那肯定是do…while的循环结构更符合,那么我们就先使用函数来打印输出一个菜单选项
void menu()
{printf("*****************************\n");printf("*****************************\n");printf("**********1.play^************\n");printf("**********0.exit^************\n");//菜单printf("*****************************\n");printf("*****************************\n");
}int main()
{int a = 0;do{menu();printf("请选择:");scanf("%d",&a);}while();
return 0;
}
构建游戏选择框架
游戏菜单已在屏幕上显示完成,现在需要完成选择,并且在玩游戏时玩一局,还想玩怎么办。
这时候需要应用博主之前阐述的switch语句来实现:
int main()
{int input = 0;do{menu();printf("PLEASE SELECT:");scanf("%d", &input);switch(input){case 1:game(); //以上为界面的选择break;case 0:printf("Exit\n");break;default:printf("ERRO,PLEASE CHOOSE AGAIN\n");break;}} while (input);//while循环可以利用0为假,其余为来实现用户可反复选择
//直到选到合适为止return 0;
}
实现游戏功能
模块化编程:查看前节三子棋的内容
test.c:是用来实现游戏逻辑 game.c:用来实现游戏功能的函数 game.h:用来申明游戏功能函数(可引用)使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等!
此为game.h的文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS//使用scanf函数的报错处理方式
#include <stdio.h>//打印函数的使用工具箱
#include<Windows.h>//颜色函数和清屏指令的工具箱
#include<stdlib.h>//在使用rand的时候需要用到srand, srand((unsigned int)time(NULL))随机函数,调用一次就可以
#include<time.h>
#define row 9//常量
#define col 9
#define cols col+2//定义常量
#define rows row+2
void initboard(char board[rows][cols],int hang, int lie,char set);//形参数
void displayboard(char board[rows][cols], int hang, int lie);//只设置9*9格子
void setmine(char board[rows][cols], int hang, int lie);//埋入地雷
void panduan(char show[rows][cols], char mine[rows][cols],int hang, int lie);
后边会逐个剖析 :
用来引用在test.c文件中
初始化雷区
首先映入眼帘的一定是 9×9 的雷区,这 81 个被遮盖的格子,
当我们随机的点击其中的格子时,会出现以下二种情况:
① 当翻开的格子是地雷时,玩家被炸“死”,游戏结束;
② 当翻开的格子不是地雷时,该格子会显示周围的 8 个格子存在的地雷的个数;
由图例可以得出结论,实现 9×9 的扫雷游戏,创建一个 9 行 9 列的二维数组并不合适。
既然对 9 行 9 列的二维数组的边界元素进行操作时,会导致数组越界访问,那我们干脆就直接将二维数组扩大一圈,将那些会导致越界访问的范围包括在数组内,从源头上解决问题,这是一个非常巧妙的办法!
所以需要设置两个数组(二维数组)
(1)一个为储存埋雷数据的(用于判断是否踩雷)
(2)一个为展示给玩家的棋盘(类似于上面的蓝色未知方块,点开后显示周围8格雷数)
需要将两个数组同时初始化initboard子函数
void initboard(char board[rows][cols], int hang, int lie,char set)
{int i = 0;int j = 0;for (i = 0; i < hang; i++){for (j = 0; j < lie; j++){board[i][j] = set;}}
}//initboard(mine, rows, cols, '0');//在test.c中引用的函数
//initboard(show, row, col, '*');
优化棋盘
由于雷区行号较长,所以需要给每行列标注序号displayboard子函数
void displayboard(char board[rows][cols], int hang, int lie)
{int i = 0;int j = 0; printf("---------------------------------------\n");for(j = 0; j <=lie; j++){printf("%d ",j);}printf("\n");for (i = 1; i <=hang; i++){printf("%d ", i);for (j = 1; j <=lie; j++){printf("%c ", board[i-1][j-1]);}printf("\n");}printf("---------------------------------------\n");
}
效果图
随机埋入地雷
应为此为9x9雷区,故10个雷足够。但怎么样实现随机在合适的区域内埋雷呢
C语言生成随机数的方法:
void setmine(char board[rows][cols], int hang, int lie)//随机埋入地雷
{int count = 10;while (count){int x = rand() % hang ;int y = rand() % lie ;if (board[x][y] == '0'){board[x][y] = '1';}count--;}}//srand((unsigned int)time(NULL));//布置雷的随机时间函数,在test.c主函数
中引用一次就够
点击后的决策
展开后周围多少雷
在扫雷游戏中,当我们点击的方格不是地雷,且周围一片区域都没有地雷时,会直接展开一片雷区,具体效果如下图
扫雷游戏中,当玩家翻转一个方格时,若该方格不是地雷则会显示该方格周围 8 个方格存在的地雷个数。如果该方格周围 8 个坐标都不存在地雷时会将这 9 个方格都展开,以此类推直到遇到一个方格的周围 8 个方格存在地雷时停止展开,两种情况如下图所
为实现这一功能,则需要我们遍历玩家输入的坐标的周围 8 个坐标,统计该坐标周围所存在的地雷个数。
int get_mine(char board[rows][cols],int x, int y)
{return (board[x - 1][y - 1]+ board[x - 1][y]+ board[x - 1][y + 1]+ board[x][y + 1]+ board[x][y - 1]+ board[x + 1][y + 1]+ board[x + 1][y]+ board[x + 1][y - 1] - 8* '0');//周围8个坐标相加
}
实现此功能代码
void Mark(char board[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;while (1){printf("\n请输入要标记的坐标>>");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col) //判断玩家输入坐标是否合法{if (board[x][y] == '!') //若坐标元素为 '!' 则表示该坐标已被标记过{printf("\n<该坐标已标记,无需重复标记,请重新输入>\n");}else //该坐标未被标记{board[x][y] = '!'; //将 '!' 赋值给该坐标元素DisplayBoard(board, row, col); //将标记地雷后的雷区展示于玩家break;}}else{printf("\n<坐标非法,请重新输入>\n\n");}}
}
game();的安排
void game()
{char mine[rows][cols] = { 0 };//存放雷的信息char show[rows][cols] = { 0 };//显示给玩家的游戏界面信息initboard(mine, rows, cols, '0');initboard(show, row, col, '*');//displayboard(mine, row, col);setmine(mine, row,col);displayboard(show, row, col);panduan(show,mine, row, col);
}
好了以上内容到今天就结束了希望大家多多支持!
其中一些内容借鉴了一些博主的,希望大家谅解。
相关文章:

初阶c语言:趣味扫雷游戏
目录 前言 制作菜单 构建游戏选择框架 实现游戏功能 模块化编程:查看前节三子棋的内容 初始化雷区 编辑 优化棋盘 随机埋入地雷 点击后的决策 实现此功能代码 game();的安排 前言 《扫雷》是一款大众类的益智小游戏&…...

JVM——内存模型
1.java内存模型 1.1 原子性 1.2 问题分析 这里与局部变量自增不同,局部变量调用iinc是在局部变量表槽位上进行自增。 静态变量是在操作数栈自增。 这里的主内存和工作内存时再JMM里的说法。 因为操作系统是时间片切换的多个线程轮流使用CPU. 1.3解决方法 JMM中…...

java八股文面试[JVM]——元空间
JAVA8为什么要增加元空间 为什么要移除永久代? 知识来源: 【2023年面试】JVM8为什么要增加元空间_哔哩哔哩_bilibili...

科技云报道:云计算下半场,公有云市场生变,私有云风景独好
科技云报道原创。 大数据、云计算、人工智能,组成了恢弘的万亿级科技市场。这三个领域,无论远观近观,都如此性感和魅力,让一代又一代创业者为之杀伐攻略。 然而高手过招往往一瞬之间便已胜负知晓,云计算市场的巨幕甫…...

Oracle 如何给大表添加带有默认值的字段
一、讲故事 你是否遇到过开发人员添加字段,导致数据库锁表问题? 但是令开发疑惑的事,他们添加字段,有的时候很快,有的时候很慢? 为什么呢? 询问得知,**加的慢时候是带上了default默…...

记录Taro大坑2丢失api无法启动
现象 解决方案 看了很多。很多说要改成一致的版本号。其实没什么用。 正确方案 再新建一个模板跑起来对比config的配置,以及package.json发现关闭预编译即可。预编译导致api丢失...
Java-Maven-解决maven deploy时报 401 Reason Phrase Unauthorized 错误
Java-Maven-解决maven deploy时报 401 Reason Phrase Unauthorized 错误 环境 Java JDK 1.8Maven 3.3.9 引言 项目需要打成jar包上传到私服,供其它项目引用。此时需要执行 mvn clean deploy 命令,执行过程中报 401 错误。 解决401错误 报错信息 执…...

【数据结构】 栈(Stack)的应用场景
文章目录 🌏前言🍀改变元素的序列🚩场景一📌解析: 🚩场景二📌解析: 🎍将递归转化为循环🌳[括号匹配](https://leetcode.cn/problems/valid-parentheses/)&…...

人力资源小程序的设计原则与实现方法
随着移动互联网的快速发展,小程序成为了各行各业推广和服务的新利器。对于人力资源行业来说,开发一款定制化的小程序不仅可以提升服务效率,还可以增强品牌形象和用户粘性。那么,如何定制开发人力资源类的小程序呢?下面…...
检查Javascript对象数组中是否存在对象值,如果没有向数组添加新对象
需求: 如果我有以下对象数组: [ { id: 1, username: fred }, { id: 2, username: bill }, { id: 2, username: ted } ]有没有办法循环遍历数组,以检查特定的用户名值是否已经存在,如果它什么都不做,但是如果它没有用…...

UG\NX二次开发 使用录制功能录制操作记录时,如何设置默认的开发语言?
文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,C\C,Qt-CSDN博客 简介: NX二次开发使用BlockUI设计对话框时,如何设置默认的代码语言? 效果: 方法: 依次打开“文件”->“实用…...

【业务功能篇83】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-应用层实战
五、ElasticSearch应用 1.ES 的Java API两种方式 Elasticsearch 的API 分为 REST Client API(http请求形式)以及 transportClient API两种。相比来说transportClient API效率更高,transportClient 是通过Elasticsearch内部RPC的形式进行请求…...

VBJSON报错:缺少:语句结束
项目中使用JSON库VBJSON时报错: 编译错误:缺少:语句结束 cJSONScript和cStringBuilder报相同的错误,都在第一行: VERSION 1.0 CLASS 研究了半天没啥结果,之前使用这个库的时候没有什么问题,所以判定是当前…...

Docker安装ES+kibana8.9.1
参考:基于Docker安装Elasticsearch【保姆级教程、内含图解】_docker elasticsearch_Acloasia的博客-CSDN博客 创建网络 docker network create es-net 基于Docker安装Elasticsearch 拉取镜像 docker pull elasticsearch:8.9.1 挂载文件 mkdir -p /usr/local/e…...

12. Oracle中case when详解
格式: case expression when condition_01 then result_01 when condition_02 then result_02 ...... when condition_n then result_n else result_default end 表达式expression符合条件condition_01,则返回…...
【电路设计】220V AC转低压DC电路概述
前言 最近因项目需要,电路板上要加上一个交流220V转低压直流,比如12V或者5V这种。一般来说,比较常见也比较简单的做法是使用一个变压器将220V AC进行降压,比如降到22V AC,但是很遗憾的是,支持220V的变压器一般体积很大,而板子留给电源部分的面积又非常有限,所以不得不研…...

网络地址转换NAT-动态NAT的使用范围和配置-思科EI,华为数通
网络地址转换NAT-动态NAT的使用范围和配置 什么是动态NAT? 使用公有地址池,并以先到先得的原则分配这些地址。当具有私有 IP 地址的主机请求访问 Internet 时,动态 NAT 从地址池中选择一个未被其它主机占用的 IP 地址一对一的转化。当数据会话…...

远程连接虚拟机中ubuntu报错:Network error:Connection refused
ping检测一下虚拟机 可以ping通,说明主机是没问题 #检查ssh是否安装: ps -e |grep ssh发现ssh没有安装 #安装openssh-server sudo apt-get install openssh-server#启动ssh service ssh startps -e |grep ssh检查一下防火墙 #防火墙状态查看 sudo ufw…...

快速排序三种思路详解!
一、快速排序的介绍 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中 的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,…...

【二叉树入门指南】链式结构的实现
【二叉树入门指南】链式结构的实现 一、前置说明二、二叉树的遍历2.1前序遍历2.2中序遍历2.3 后序遍历 三、以前序遍历为例,递归图解四、层序遍历五、节点个数以及高度等5.1 二叉树节点个数5.2二叉树叶子节点个数5.3 二叉树第k层节点个数5.4 二叉树查找值为x的节点5…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
信息系统分析与设计复习
2024试卷 单选题(20) 1、在一个聊天系统(类似ChatGPT)中,属于控制类的是()。 A. 话语者类 B.聊天文字输入界面类 C. 聊天主题辨别类 D. 聊天历史类 解析 B-C-E备选架构中分析类分为边界类、控制类和实体类。 边界…...
【Java基础】向上转型(Upcasting)和向下转型(Downcasting)
在面向对象编程中,转型(Casting) 是指改变对象的引用类型,主要涉及 继承关系 和 多态。 向上转型(Upcasting) ⬆️ 定义 将 子类对象 赋值给 父类引用(自动完成,无需强制转换&…...