C语言实现 扫雷游戏 | 简单项目
目录
文件组成
test.c 游戏主题框架
infor.h 信息模块函数的声明
infor.c 信息模块的函数定义与功能实现
game.h 游戏模块函数的声明
game.c 游戏模块的函数定义与功能实现
结尾 源码
文件组成
要写一个扫雷游戏,由于体量较大,我们打算分三个.c 文件(源文件) 来定义函数,实现代码,两个 .h 文件(头文件) 来实现我们.c文件中函数的声明和库函数头文件的引用。
三个 源文件 : test.c , game.c , print.c
两个头文件:game.h , print.h
文件的源码 我会放在结尾以供大家学习
test.c 游戏主题框架
#define _CRT_SECURE_NO_WARNINGS 1#include "game.h" /这里引上我们编写好的头文件
#include "infor.h"/里面有我们所有自定函数的声明和库函数头文件的引用void menu() {/游戏主界面的菜单printf("***************************\n");printf("******* 1. PLAY *******\n");printf("******* 0. EXIT *******\n");printf("******* 2. INFOR *******\n");printf("***************************\n");}int main() {srand((unsigned int)time(NULL));/由于游戏中布置雷需要随机数,我们在这里就将它初始化int input;/用来接收玩家输入do {/主题采用循环结构 当玩家结束游戏后可以进行选择进入或者退出menu();/打印菜单printf("请选择序号:>");/提示玩家选择scanf("%d", &input);switch (input) {case 1:game();/进入游戏模块break;case 0:printf("退出游戏\n");/退出游戏break;case 2:INFOR();/进入信息菜单 查看规则以及其他信息break;default:printf("输入错误 重新输入\n");/输入错入提示}} while (input);/当玩家输入0 退出程序return 0;
}
此时我们程序运行起来 就会是这个样子
infor.h 信息模块函数的声明
#pragma oncevoid INFOR();/信息模块入口
void menu_in();/信息模块的菜单
void game_rules();/游戏规则说明
void infor();/补充信息
infor.c 信息模块的函数定义与功能实现
#include<stdio.h>/引上库函数的头文件void menu_in() {/只是当玩家选择 1 后显示的菜单printf("1.游戏规则\n");printf("2.制作信息\n");printf("3.奖励\n");printf("0.返回\n");}
void game_rules() {/游戏规则printf("\n踩点和标记需输入对应 行和列如 第一行第一列 应该输入 \"1 1\"\n猜到雷会被炸死,恐怖至极,骨灰都找不到!!!\n踩到非雷会显示以它中心3X3矩形范围内雷的个数.\n如果显示0会自动帮你展开\n正确标记出所有雷,或者踩完所有非雷点即可获胜.\nthats it...\n\n");
}
void infor() {/其他信息这里可以看自己喜好添加printf(".一步一步按提示来 不然要炸\n\n");
}
void reward() {/奖励printf("完成1级难度即可获得:> ");printf("游戏作者的大拇指!!!\n");}以上是这一模块函数的定义
——————————————————————————————————————————————————————
以下是则以模块的的框架
跟主界面类似 用到循环体 以实现重复选择void INFOR() {/这一模块的框架menu_in();/菜单int input;do {printf("请选择序号:>");scanf("%d", &input);switch (input) {case 1:game_rules();/规则break;case 2:infor();/信息break;case 3:reward();/奖励break;case 0:break;/退出循环,回到主界面default:printf("输入错误 重新输入\n");/输入错入提示}} while (input);/可以重复选择
}
结束后回到主界面
这时 如果你运行程序 并在主界面输入 2 并按下回车
将会是这样
如继续输入 0 就回到主界面
至此 扫雷游戏除了游戏 就都编写完成了(狗头)
game.h 游戏模块函数的声明
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<Windows.h>
#include<string.h>/定义 棋盘行列的全局变量
为了方便 我们定义11X11的棋盘 但只使用 其中9X9的空间
#define ROW 9
#define COL 9
#define ROWS 11
#define COLS 11/扫雷游戏主体
void game();
/初始化棋盘的函数
void InitBoard(char Board[ROWS][COLS], int rows, int cols, char set);
/打印棋盘的函数
void DisplayBoard(char Board[ROWS][COLS], int row, int col);
/设置雷的函数
void SetMine(char Board[ROWS][COLS],int row,int col,int nub);
/玩家排雷(一直玩到结束,返回值为输赢结果)
char FindMine(char Board[ROWS][COLS], char show[ROWS][COLS], int row, int col,int nub);
/返回点周围雷的个数
char CountMine(char Board[ROWS][COLS],char[ROWS][COLS] ,int row, int col);
/将点展开
void Extend(char Board[ROWS][COLS], char show[ROWS][COLS], int row, int col);
/判断赢没赢(赢返回 1 ,没赢返回 0 )
int Is_win(char Board[ROWS][COLS],char show[ROWS][COLS], int row, int col,int nub);
/游戏胜利 或 失败后延时打印结果
void SleepPrint(char* p);
game.c 游戏模块的函数定义与功能实现
为了方便 我们定义两个二维数组 来分别代表 用户看到的棋盘数字 ,标记 (排查雷的信息)的棋盘 和 存放雷的棋盘 里面 只有 雷。
用户棋盘show board:
存雷棋盘:
玩家可以选择是要踩 还是 要 标记,把所有非标记的雷周围的点都踩完 就赢了:
当玩家踩到非雷时 会显示 这个点 周围雷的个数:
当这个点周围没有雷时 不会显示数字0,而是自动帮你展开 到周围有雷的位置:
只有胜利 或者 被炸死从而结束游戏时 会 打印一次 存放雷的棋盘:
代码如下 :
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"/初始化棋盘的函数
void InitBoard(char Board[ROWS][COLS],int rows,int cols,char set) {int i;int j;for (i = 0; i < rows; i++) {/将每个元素都设为0for (j = 0; j < cols; j++) {Board[i][j] = set;}}
}
/打印棋盘的函数
void DisplayBoard(char Board[ROWS][COLS], int row, int col) {int i;int j;printf("————扫雷游戏————\n");for (j = 0; j < 10; j++) {if (0 == j) {printf("%d ", j);continue;}printf("%d ",j);}printf("\n\n");for (i = 1; i <=row; i++) {printf("%d ", i);for (j = 1; j <= col; j++) {printf("%c ", Board[i][j]);}printf("\n");}printf("————扫雷游戏————\n");}
会打印如下棋盘
/设置雷的函数
void SetMine(char Board[ROWS][COLS], int row, int col,int nub) { int i;int j;while (nub) { /nub为雷的个数i = rand() % row + 1;/随机生成行j = rand() % col + 1;/随机生成列if (Board[i][j] == '*') {/查重Board[i][j] = '#';/我们用 字符'#'来表示雷nub--;/每设置一个雷 nub自减}}
}
/数雷的个数的函数
char CountMine(char Board[ROWS][COLS], char show[ROWS][COLS],int row, int col) {char count = '0';int i; int j;for (i = row - 1; i < row + 2; i++) {for (j = col - 1; j < col + 2; j++) {/排查点 周围 雷的个数if (Board[i][j] == '#') {count++;}}}return count;}/当3X3范围内没有雷时 自动展开的函数
这里用到了递归,若周围没有雷就把这个点设成 空白字符 并自动把周围的点都踩了,直到周围有雷为止
void Extend(char Board[ROWS][COLS],char show[ROWS][COLS],int row,int col){show[row][col] = ' ';int i, j;for (i = row - 1; i < row + 2; i++) {for (j = col - 1; j < col + 2; j++) {if (show[i][j] == '*') {show[i][j] = CountMine(Board, show, i, j);if (show[i][j] == '0') {Extend(Board, show, i, j);}}}}
}
/判断 游戏的函状态的函数
int Is_win(char Board[ROWS][COLS],char show[ROWS][COLS], int row, int col,int nub) {int i,j;int count = 0;/数正确的标记int count0 = 0;/数标记的总个数int COUNT = 0;/数*号后面是雷的个数int COUNT0 = 0;/数*号的总个数for (i = 1; i <=row; i++) {for (j = 1; j <= col; j++) {if (show[i][j] == '!') {count0++;if (Board[i][j] == '#') {count++;}}if (show[i][j] == '*') {COUNT0++;if (Board[i][j] == '#') {COUNT++;}}}}if ((nub == count&&nub==count0)|| COUNT == COUNT0) {
/如果标记出了所有雷 或者 正确标记了所有没踩了的雷 就代表胜利return 1;返回 1}else if (nub == count && nub <= count0) {
/如果有错误标记或者标记过多return 2;返回 2}/一切正常 但没赢 return 0; 返回 0
}
/玩家 排雷或者标记的函数!
char FindMine(char Board[ROWS][COLS],char show[ROWS][COLS], int row,int col,int nub) {int a, b;int input=1;while (1) {printf("请选择是要踩(1)还是要标记(2):>");/标记(插旗)或者 踩点scanf("%d", &input);switch (input)/这里用switch语句来对玩家的输入 执行不同的语句{case 1:/ 若玩家输入 1 就是踩点 ,则执行一下语句printf("请输入要走的行列:>");while (1) { /执行踩scanf("%d %d", &a, &b);if (a > 0 && a < 10 && b>0 && b < 10) {if (show[a][b] != '*' && show[a][b] != '!') {/查重printf("这个点 (%d行%d列) 已经踩过了,重新输入:>", a, b);continue;}break;}elseprintf("输入错误,重新输入:>");/输入错误提示 }if (Board[a][b] == '#') {/如果该点是雷,则失败,结束游戏return 'F';}else {show[a][b] = CountMine(Board, show, a, b);/如果不是雷,数周围雷的个数if (show[a][b] == '0') {/如果周围没有雷,调用自动展开函数来自动展开Extend(Board, show, a, b);}}if (1 == Is_win(Board, show, row, col, nub)) {/每次走完 判断是否已经赢下游戏DisplayBoard(show, row, col);/如果赢了就结束游戏return 'W';}DisplayBoard(show, row, col);/打印棋盘break;case 2://标记
/更踩点思路相似printf("请输入要标记的行列:>");while (1) {scanf("%d %d", &a, &b);/行 列if (a > 0 && a < 10 && b>0 && b < 10) {/判断坐标的合法性if (show[a][b] == '!') {/如果这是标记过的点 ,我们就把这个标记取消show[a][b] = '*';
/判断是否赢得游戏if (1 == Is_win(Board, show, row, col, nub)) {DisplayBoard(show, row, col);return 'W';}
/如果标记多了就提示if (2 == Is_win(Board, show, row, col, nub)) {printf("标记多了...");}break;}else {/如果是没标记过的点 我们就把这个点 标记上
/随后在检测是否赢得游戏show[a][b] = '!';if (1==Is_win(Board, show, row, col,nub)) {return 'W';}if (2 == Is_win(Board, show, row, col, nub)) {printf("标记多了...");}break;}}else {printf("输入错误,重新输入:>");}}DisplayBoard(show, row, col);break;
/这里判断 最开始选择要踩还是标记那里 是否 输入错误default:printf("输入错误,重新输入:>");printf("\n");}}}/这是一个 延时打印 胜利图案的函数 增加游戏的趣味性
void SleepPrint(char* p) {int i;int len = strlen(p);for (i = 0; i < len; i += 2) {printf("%c%c", *(p + i), *(p + i + 1));Sleep(600);}}
这是游戏模块的主体框架
void game() {char Board[ROWS][COLS] = { 0 };//布置好雷的信息char show[ROWS][COLS] = { 0 };//排查出雷的信息InitBoard(Board, ROWS, COLS, '*');InitBoard(show, ROWS, COLS, '*');printf("请选择游戏难度(1~3):>");int tmpe;int nub=0;do {scanf("%d", &tmpe);switch (tmpe){case 1:nub = 10;break;case 2:nub = 15;break;case 3:nub = 20;break;default:printf("输入错误,重新输入:>");break;}} while (tmpe != 1 && tmpe != 3 && tmpe != 2);SetMine(Board, ROW, COL, nub);DisplayBoard(show, ROW, COL);char Result=FindMine(Board, show, ROW, COL,nub);switch (Result) {case 'F':/如果输了 就延时打印 “你被炸死了”SleepPrint("你被炸死了");for (int i = 0; i < 3; i++) {printf(".");Sleep(600);}printf("\n");DisplayBoard(Board, ROW, COL);break;case'W':/如果赢了就延时打印 “你赢了”SleepPrint("你赢了");for (int i = 0; i < 3; i++) {printf("!");Sleep(600);}printf("\n");DisplayBoard(Board, ROW, COL);}
}
/随后退出到 主界面 让玩家选择是退出程序 或是进入某个模块
这样 ,我们的扫雷游戏的部分就 完成了 .
结尾 源码
希望这篇博客 能对大家有所帮助,祝看到这篇的博客的人都早日成为 大牛!!!
游戏的 源文件 头文件:>
扫雷游戏https://gitee.com/leyi999/project.githttps://gitee.com/leyi999/project.git
.
C语言实现 扫雷游戏 | 简单项目相关推荐
- C语言编写扫雷游戏,超简单
C语言编写扫雷游戏,超简单 1.扫雷游戏的流程 2.代码编写 3.总结 通过学习C语言的基础知识,基本上是理解了大部分内容,现在就通过所学的知识,写个简单的扫雷游戏,加深对基础知识的理解,正所谓实践是 ...
- 用C语言实现扫雷游戏
用C语言实现扫雷游戏 -扫雷游戏的基本思路 1.打印游戏的菜单 2.为了便于后面排查周围雷的个数,初始化两个二维数组,一个作为向玩家显示的面板,一个作为布雷的面板.两个数组嵌套在一起.如下图所示: 3 ...
- 用c语言编写最大最小值_C语言学习教程,用C语言编写扫雷游戏
本文实例为大家分享了C语言实现扫雷游戏及其优化的具体代码,供大家参考,具体内容如下 关于扫雷优化 1.核心思想:使用两个二维数组进行设计,一个用于显示,一个用于后台雷的布置. 2.使用宏常量,后期可以 ...
- c++扫雷游戏代码_C语言学习教程,用C语言编写扫雷游戏
本文实例为大家分享了C语言实现扫雷游戏及其优化的具体代码,供大家参考,具体内容如下 关于扫雷优化 1.核心思想:使用两个二维数组进行设计,一个用于显示,一个用于后台雷的布置. 2.使用宏常量,后期可以 ...
- 超详细分解c 语言——实现扫雷游戏(详解)
之前利用三子棋程序,介绍探讨了 c语言简单游戏编写主要模块及使用方法. 今天,我们就利用这个经典扫雷游戏,来加强对于程序思路的编写及思路. 目录 前引 游戏规则介绍 一.基本游戏思路(游戏实现方法) ...
- c语言—实现扫雷游戏
文章目录 什么是扫雷游戏 一.实现思路 二.头文件 三.主函数文件 1.菜单函数 2.主函数 四.游戏文件 1.地图初始化 2.展示地图 3.埋雷函数 4.判断该位置附近雷的个数 5.主游戏函数 五. ...
- c语言扫雷游戏计时功能_C语言实现扫雷游戏(可以自动展开)
前言 本篇博客主要介绍如何使用C语言实现扫雷游戏. 一.游戏规则 在一张ROW行COL列的地图上存在MINE_COUNT个地雷.玩家输入坐标翻开格子,若没有踩雷,则计算此格子周围8个格子的地雷总数,并 ...
- C语言实现扫雷游戏(超详细讲解+全部源码)
电子信息 工科男 一点一点努力! 文章目录 前言 一.游戏介绍 二.游戏设计思路 二.具体步骤 1.创建test.c和game.c源文件以及 game.h头文件 2.创建菜单 3.创建雷盘 4.初始化 ...
- c语言程序设计扫雷游戏实验报告,C语言程序设计扫雷游戏实验报告.doc
C语言程序设计扫雷游戏实验报告 中南大学 程序设计基础实践报告 题 目 设计一个和window系统类似的小游戏[挖地雷] 学生姓名 张兰兰 学 院 信息科学与工程学院 专业班级 物联网工程1301班 ...
最新文章
- 深入分析Linux内核源码oss.org.cn/kernel-book/
- 数据库六大约束用法:主键(primary key)、外键(foreign key)、非空(not null)、默认(default)、检查(check)、唯一(unique)
- 基于Boost::beast模块的同步http服务器
- javaScript第二天(1)
- mysql 卸载批处理_MYSQL 注册启动 及 停用卸载 批处理脚本 (补)
- jQuery按钮隐藏与显示
- 让用户闭着眼睛买东西可还行?雷军谈小米的目标...
- dubbo调用超时回滚_微服务痛点基于Dubbo + Seata的分布式事务(AT模式)
- 设计安全的账号系统的正确姿势
- ODBC和JDBC是做什么的?为初学者理解概念问题
- 群辉安装linux软件下载,群晖系统Synology DSM安装ipkg包管理和套件安装方法
- 合与荣—— 惠普融合战略的深化与落地
- Javascript传奇
- 【论文随笔2】COALA: Co-Aligned Autoencoders for Learning Semantically Enriched Audio Representations
- 穷人python入门教程视频_《穷》字意思读音、组词解释及笔画数 - 新华字典 - 911查询...
- 如何快速搭建在家里(外网)也能访问的云办公云桌面系统
- 用案例说话,教你如何写出有吸引力的开发信以及主题
- ghttp作为客户端下载大文件的问题
- 笔记:springboot-admin 整合spring security应用注册失败问题
- c语言的变量和指针,怎么理解?