控制台扫雷(C语言实现)
目录
- 博文目的
- 实现思路
- 项目创建
- 文件解释
- 具体实现
- 判断玩家进行游戏还是退出
- 扫雷棋盘的确定
- 地图初始化
- 埋雷
- 玩家扫雷的实现
- 雷判断函数
- 源码
- game.c
- game.h
- 扫雷.c
博文目的
相信不少人都学习了c语言的函数,循环,分支那我们就可以写一个控制台的扫雷小游戏来检验自己学得如何。
在做一件事之前我们都要先考虑我们学要做哪些。同样要实现一个扫雷小游戏,我们首先要思考学要做什么。
实现思路
实现思路可以参考以下步骤:
-
判断玩家进行游戏还是退出。
-
将扫雷的棋盘确定。
-
地图初始化。
-
埋雷 。
-
玩家扫雷的实现。
-
对玩家扫的是不是雷判断,周围几颗雷判断
项目创建
在所有开始之前我们先建项目。
文件解释
对文件的解释如下:
-
创一个头文件game.h里面放都要用到的头文件和参数。
-
在game.c中实现我们的游戏逻辑。
-
在扫雷.c中把游戏串起来。
具体实现
具体实现可以参考如下思路:
判断玩家进行游戏还是退出
使用一个menu函数将作为菜单打印。
在主函数中使用do-while循环来判断用户是玩还是退出。
void menu()
{printf("------------------------------\n");printf("----------1.play--------------\n");printf("----------0.exit--------------\n");printf("------------------------------\n");
}
int main()
{int a;do{menu();scanf("%d",&a);} while(a);return 0;
}
扫雷棋盘的确定
首先会先想到创建一个9 * 9的数组来表示棋盘。
但是我们就要考虑到判断周围雷个数时的判断,只创建9*9的棋盘,那在边界上的雷就不好判断周围有几颗雷,要判断就需要在写其他的判断方法不能与中间的判断方法统一了。
所以扩大一圈创建11 * 11的地图。
在头文件中使用宏定义出地图的长度和能访问的长度。
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
地图初始化
我们将代表地图的数组有雷的设为1,无雷的设为0。
想到这我们又会考虑到 什么代表雷呢,我们就以字符0代表没雷1代表有雷;
难道我们在控制台输出0 1吗,那还玩个屁啊。
因此我们应该还要创建一个地图来输出。
在扫雷.c文件中定义出两个数组,在game.c文件中写数组初始化函数。
//扫雷.c中封装函数
void game()
{char map1[ROWS][COLS];char map2[ROWS][COLS];init(map1, '0');init(map2, '*');
}
//game.c中初始化棋盘函数
void init(char a[ROWS][COLS], char ch)
{for (int i = 0; i < ROWS; i++){for (int j = 0; j < COLS; j++){a[i][j] = ch;}}
}
埋雷
我们要埋雷而且还要是随机的,那我们就要用到随机数生成函数,
如果我们像这样布置雷,随机数生成后会不会相等,让同一位置布置多个雷了?
所以我们要判断生成的是否已经埋雷。
//埋雷函数
void LayMine(char map1[ROWS][COLS])
{int count = MINE_NUMBER;srand((unsigned int)time(NULL));while(count){ int x = rand() % ROW + 1;int y = rand() % COL + 1;if (map1[x][y] == '0'){map1[x][y] = '1';count--;}}
}
玩家扫雷的实现
玩家在控制台上扫雷是通过坐标来输入,那我们打印棋盘时就去提供每个坐标,不然输入时要玩家自己一个一个数坐标,本来就玩的不爽,就更不爽了。
/打印棋盘
void Print(char map[ROWS][COLS])
{printf("=====扫雷===========\n");for (int i = 0; i <= COL; 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 ", map[i][j]);}printf("\n");}
}
雷判断函数
对玩家扫的是不是雷判断,周围几颗雷判断 。
void FindMine(char map1[ROWS][COLS], char map2[ROWS][COLS])
{int count = 0;//记扫了几个雷while (count < MINE_NUMBER){int x = 0, y = 0;printf("请输入需要排查的坐标 ");scanf("%d%d", & x, & y);if ((x >= 1 && x <= ROW) && (y >= 1 && y <= COL))//确保用户输入正确坐标{if (map1[x][y] == '1'){printf("踩雷结束\n");Print(map1);break;}else{count--;int num = 0;for (int i = x - 1; i <= x + 1; i++){for (int j = y - 1; j <= y + 1; j++){if (map1[i][j] == '1'){num++;}}}map2[x][y] = num + '0';Print(map2);}}else{printf("错误输入\n");}}if (count == MINE_NUMBER){printf("过关牛逼\n");}
}
源码
源码呈上:
game.c
game.c文件下的代码
# define _CRT_SECURE_NO_WARNINGS 1;
#include"game.h"//初始化棋盘函数
void init(char a[ROWS][COLS], char ch)
{for (int i = 0; i < ROWS; i++){for (int j = 0; j < COLS; j++){a[i][j] = ch;}}
}//埋雷函数
void LayMine(char map1[ROWS][COLS])
{int count = MINE_NUMBER;srand((unsigned int)time(NULL));while(count){ int x = rand() % ROW + 1;int y = rand() % COL + 1;if (map1[x][y] == '0'){map1[x][y] = '1';count--;}}
}//打印棋盘
void Print(char map[ROWS][COLS])
{printf("=====扫雷===========\n");for (int i = 0; i <= COL; 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 ", map[i][j]);}printf("\n");}
}
void FindMine(char map1[ROWS][COLS], char map2[ROWS][COLS])
{int count = 0;//记扫了几个雷while (count < MINE_NUMBER){int x = 0, y = 0;printf("请输入需要排查的坐标 ");scanf("%d%d", & x, & y);if ((x >= 1 && x <= ROW) && (y >= 1 && y <= COL))//确保用户输入正确坐标{if (map1[x][y] == '1'){printf("踩雷结束\n");Print(map1);break;}else{count--;int num = 0;for (int i = x - 1; i <= x + 1; i++){for (int j = y - 1; j <= y + 1; j++){if (map1[i][j] == '1'){num++;}}}map2[x][y] = num + '0';Print(map2);}}else{printf("错误输入\n");}}if (count == MINE_NUMBER){printf("过关牛逼\n");}
}
game.h
game.h文件下的代码:
#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define MINE_NUMBER 10void init(char a[ROWS][COLS], char ch);
void LayMine(char map1[ROWS][COLS]);
void Print(char map[ROWS][COLS]);
void FindMine(char map1[ROWS][COLS], char map2[ROWS][COLS]);
扫雷.c
扫雷.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 map1[ROWS][COLS];char map2[ROWS][COLS];init(map1, '0');init(map2, '*');LayMine(map1);//Print(map1);Print(map2);FindMine(map1, map2);
}
int main()
{int a;do{menu();scanf("%d", &a);switch (a){case 1:game();break;case 0:printf("exit\n");break;default:printf("错误输入\n");break;}} while (a);return 0;
}
相关文章:

控制台扫雷(C语言实现)
目录 博文目的实现思路项目创建文件解释 具体实现判断玩家进行游戏还是退出扫雷棋盘的确定地图初始化埋雷玩家扫雷的实现雷判断函数 源码game.cgame.h扫雷.c 博文目的 相信不少人都学习了c语言的函数,循环,分支那我们就可以写一个控制台的扫雷小游戏来检…...

操作系统期末复习 | 批处理程序 | PV实现同步互斥 | 调度算法 | 页面置换算法 | 磁盘调度算法
操作系统引论 批处理程序 单道批处理:引入脱机输入/输出技术,并由监督程序负责控制作业的输入、输出。主要优点是缓解了一定程度的人机速度矛盾,资源利用率有所提升。主要缺点是内存中仅能有一道程序运行,只有该程序运行结束之后…...
字符串的六种遍历方式
在 Java 中,有多种遍历字符串的方法。以下是几种常见的遍历字符串的方法,并附有示例代码 1. 使用 for 循环 这是最常见和基础的遍历方法,通过索引访问每个字符。 public class StringTraversal {public static void main(String[] args) {S…...
在码云(Gitee)上建立分支(Branch)的步骤如下:
步骤一:登录码云 首先,打开码云的官方网站(gitee.com),输入用户名和密码登录你的账号。 步骤二:创建仓库 登录后,在页面右上方的搜索框中输入仓库名称,并点击“创建”按钮创建新的仓…...

JVM专题四:JVM的类加载机制
Java中类的加载阶段 类加载 Java中的类加载机制是Java运行时环境的一部分,确保Java类可以被JVM(Java虚拟机)正确地加载和执行。类加载机制主要分为以下几个阶段: 加载(Loading):这个阶段&#x…...

Python爬取中国天气网天气数据.
一、主题式网络爬虫设计方案 1.主题式网络爬虫名称 名称:Python爬取中国天气网天气数据 2.主题式网络爬虫爬取的内容与数据特征分析 本次爬虫主要爬取中国天气网天气数据 3.主题式网络爬虫设计方案概述(包括实现思路与技术难点) reques…...

EXCEL快速填充空白内容
** EXCEL快速填充空白内容 ** 1.全选所有需要填充的内容,按住电脑的F5或者CTRLG点击定位 2.可以看到空白处被自动选定,之后按电脑和⬆,最后CTRLenter 可以看到空白处已经被填充。...

CBSD创建和管理bhyve容器Ubuntu@FreeBSD
bhyve介绍:bhyve:FreeBSD下的原生虚拟机管理器_freebsd 虚拟化平台bhyve-CSDN博客 两个bhyve的管理软件:使用bvm管理bhyve虚拟机管理系统FreeBSD-CSDN博客 vm-bhyve:bhyve虚拟机的管理系统FreeBSD-CSDN博客 现在,我…...
STM32开发实战:SPI接口在W25Q64 Flash存储器中的应用
摘要 本文将深入探讨STM32微控制器如何利用SPI接口与W25Q64 Flash存储器进行通信。W25Q64是一款常用的SPI串行Flash存储器,具有8Mbit的存储容量。本教程将指导读者完成硬件连接、SPI配置、读写操作,并提供实际的代码实现。 1. SPI接口概述 SPI是一种串…...
python一些进阶用法:hook 钩子函数以及Registry机制
写在前面 一句话讲,register机制 和 hook 都是函数/类 调用和传参机制的一种灵活运用,将函数作为传参对象,进行回调和封装,通常扩展了或修改了原始函数的行为;这些高级用法都是编程经验中沉淀下来的常用范式࿰…...

工作实践:11种API性能优化方法
一、索引优化 接口性能优化时,大家第一个想到的通常是:优化索引。 确实,优化索引的成本是最小的。 你可以通过查看线上日志或监控报告,发现某个接口使用的某条SQL语句耗时较长。 此时,你可能会有以下疑问ÿ…...

正版软件 | WIFbox:智能化文件管理工具,让效率与隐私并行
在数字化办公日益普及的今天,文件管理成为了提升工作效率的关键。WIFbox 一款智能文件管理工具,利用强大的人工智能技术,帮助您快速对文件进行分类,完成复杂的智能文件分类任务。 智能分类,效率倍增 WIFbox 通过精细化…...
Postman接口工具实战
为了更好地展示Postman接口测试的实战过程,我将以一个简单的实战示例来说明如何使用Postman完成一个API的测试。假设我们要测试一个假想的天气查询API,该API允许用户通过城市名查询天气情况。我们将执行以下步骤: 1. 准备工作 确保已经安装…...

江协科技51单片机学习- p17 定时器
🚀write in front🚀 🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝…...
【D3.js in Action 3 精译】前言
早在 2017 年,我还是一名渴望迈出职业生涯关键一步的前端开发者。虽然我很热衷于网站开发,但总感觉缺了点什么。我一直希望自己的工程专业背景和对教学的热爱能与新的编程技能相结合。就在这时,搭档建议我学学数据可视化。出于某种原因&#…...

Java SE入门及基础(58) 并发 进程与线程概念
目录 并发 进程和线程 1. 进程和线程 2. 进程 3.线程 总结 并发 并发(Concurrency) Computer users take it for granted that their systems can do more than one thing at a time. They assume that they can continue to work in a word processor, while other app…...
放松一下,简简单单了
哈哈哈哈哈...
【智能制造-5】数采和电机
既然可以采集PLC的数据,为什么要采集电机的数据? 采集PLC(可编程逻辑控制器)的数据和采集电机的数据是两个不同的概念和目的。 PLC是用于控制和监控工业自动化过程的设备,它可以接收传感器的输入信号并根据预设的逻辑…...
【软考论文】论信息系统的安全性与保密性设计
目录 一、题目二、论文2.1 摘要2.2 正文三、扩展3.1 信息安全包括5个基本要素3.2 国产秘钥算法3.3 等保(信息安全等级保护)3.4 其他一、题目 在企业信息化推进的过程中,需要建设许多信息系统,这些系统能够实现高效率、低成本的运行,为企业提升竞争力。但在设计和实现这些…...

【图文教程】电脑查看显卡GPU温度方法:小白也能秒懂!
在电脑操作中,显卡是电脑的重要组件之一,其温度控制对于保持系统稳定运行是特别重要的。但是,许多新手用户不知道要怎么操作才能查看电脑显卡CPU的温度?接下来小编给大家介绍三种简单有效的查看显卡温度方法,操作简单&…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...

PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...