C语言小游戏之扫雷

  • 一.游戏介绍
  • 二.游戏步骤及实现的功能
    • 1.初始化雷盘
    • 2.打印雷盘
    • 3.随机布置雷
    • 4.玩家排雷
    • 5.防止玩家第一次被炸死
    • 6.统计所选位置周围八个位置中雷的个数
    • 7.递归拓展已选位置周围的区域
    • 8.标记雷及取消标记

一.游戏介绍

看到这张图片,相信很多小伙伴都非常熟悉,很多小伙伴都玩过扫雷这个小游戏,扫雷是一款益智类游戏,在放松娱乐的同时可以锻炼各位小伙伴的智商。

游戏规则:如上图,玩家需要在不被炸死的前提下找出图中雷的位置,若能找出所有雷,则游戏胜利,若不幸踩到雷则被炸死。

注:先介绍程序实现的主要功能,后文会有完整代码

二.游戏步骤及实现的功能

(一) 游戏步骤

  1. 程序开始执行时玩家需要选择是否开始游戏,输入1则游戏开始,输入0则退出游戏
  2. show地图出现后玩家开始选择进行选择,输入1则开始选择区域,输入2则可以标记自己认为是雷的区域,输入3则可以取消原先被标记的区域
  3. 当所有非雷区域全部被排出来后则游戏胜利
//遍历show地图,以便判断最后的胜利
int Travel(char show[ROWS][COLS], int row, int col)
{int i = 0;int j = 0;int win = 0;for (i = 1; i <= row; i++){for (j = 1; j <= col; j++){if (show[i][j] == '*' || show[i][j] == '!'){win++;}}}return win;
}

以下为效果图:

(二)实现的功能

  1. 初始化雷盘
  2. 打印雷盘
  3. 随机布置雷
  4. 玩家开始排雷
  5. 防止玩家第一次被雷炸死.
  6. 统计所选位置周围八个位置中雷的个数
  7. 递归拓展已选位置周围的区域
  8. 标记雷及取消标记

1.初始化雷盘

初始化雷盘时需要构造两个二维数组,一个数组(mine数组)里面是存放雷的,用于实现各种功能,另一个数组(show数组)是给玩家操作时看的,看不到雷的具体位置。
由于需要统计每个位置周围八个区域中雷的个数,在统计最边缘的位置时为了利于功能的实现,在初始化雷盘时构建的二维数组mine数组的行和列比show数组多两行两列

//初始化雷盘
//主函数中函数的调用
//Initboard(mine, ROWS, COLS,'0');
//Initboard(show, ROWS, COLS, '*');
void Initboard(char board[ROWS][COLS], int rows, int cols,char set)
{int i = 0, j = 0;for (i = 0; i < rows; i++){for (j = 0; j < cols; j++){board[i][j] = set;}}
}

初始化雷盘时,mine数组全部初始化为字符‘0’,show数组全部初始化为字符‘*’

2.打印雷盘

玩家需要通过打印出的show数组雷盘进行游戏,打印雷盘时将行号和列号全部打印出来有利于玩家进行操作

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{int i = 0, j = 0;//打印列号for (i = 0; i <= col; 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");}
}

雷盘打印如下:

3.随机布置雷

在show数组中,用字符‘0’表示无雷区域,用字符‘1’表示有雷区域,由于第一个步骤中已经将show数组全部初始化为字符‘0’了,故只需使用srand和rand函数生成随机数,使得雷的分布为随机位置。

//随机布置雷
void SetMine(char board[ROWS][COLS], int row, int col)
{int x = 0, y = 0;int count = EASY_COUNT;while (count){x = rand() % row+1;y = rand() % col+1;if (board[x][y] != '1'){board[x][y] = '1';count--;}}
}

4.玩家排雷

玩家根据show数组展示出的地图开始排雷,选择自己认为不是雷的区域

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int ch = 0;int flag_count = 0;int win = 0;int fch = 1;//用来标记玩家是否为第一次排雷while (1){menu1();scanf("%d", &ch);if (ch == 1){int x = 0, y = 0;printf("请开始排雷:>");scanf("%d%d", &x, &y);//判断坐标合法if (x <= row && x > 0 && y > 0 && y <= col){//判断玩家是否是第一次排雷if (fch == 1 && mine[x][y] == '1'){//是第一次排雷ChangePlace(mine, row, col, x, y);fch++;}else {//判断是否踩雷if (mine[x][y] == '1'){printf("游戏结束\n");printf("恭喜你,踩到雷了\n");DisplayBoard(mine, row, col);break;}else{broad(mine, show, x, y);DisplayBoard(show, row, col);}fch++;}  }else{printf("输入坐标不合法,请重新输入\n");}}else if (ch == 2){printf("请开始标记雷:>\n");//标记雷的函数//原先的博客不能改变实参flag_count,此处已改正flag_count = Flagmine(show, row, col, flag_count);DisplayBoard(show, row, col);}else if (ch == 3){printf("请选择要取消标记的位置:>\n");//取消标记的函数flag_count = Cancelflag(show, row, col, flag_count);DisplayBoard(show, row, col);}//遍历show地图(改进)win=Travel(show, row, col);if (win == EASY_COUNT)break;}if (win == EASY_COUNT){printf("恭喜你,游戏胜利\n");}
}

5.防止玩家第一次被炸死

如果玩家第一次就踩雷,则提示玩家重新选择,并将该位置的雷重新随机布置。

//防止玩家第一次排雷被炸死
void ChangePlace(char mine[ROWS][COLS], int row, int col, int x, int y)
{x = rand() % row;y = rand() % col;mine[x][y] = '1';printf("第一次就踩雷了,重新选择\n");
}

6.统计所选位置周围八个位置中雷的个数

统计已选位置周围八个位置中含有雷的个数,并在该位置上数字的形式打印出来。

//计算坐标周围雷的个数
int get_mine(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';
}

此处由于数组mine中存放的是字符’0’,而不是数字0,故当统计完八个位置后需要减去字符’0’之后返回为数字。

7.递归拓展已选位置周围的区域

递归的方式拓展式排雷。

//拓展周围不是雷的区域
void broad(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{//判断坐标是否越界if (x == 0 || y == 0 || x == ROWS - 1 || y == COLS - 1)return;//判断是否已经被排除if (show[x][y] != '*'){return;}int count = get_mine(mine, x, y);if (count > 0){show[x][y] = count + '0';return;}//递归拓展地图else if (count == 0){show[x][y] = '0';broad(mine, show, x - 1, y);broad(mine, show, x - 1, y - 1);broad(mine, show, x, y - 1);broad(mine, show, x + 1, y - 1);broad(mine, show, x + 1, y);broad(mine, show, x + 1, y + 1);broad(mine, show, x, y + 1);broad(mine, show, x - 1, y + 1);}
}

如果只能一个一个雷的排,将会使得此游戏无法进行,故当选择一个位置a后对a周围八个区域进行排除,若其中一个位置b周围八个位置仍没有雷,就继续对b周围的八个位置进行排雷,以此递归的方式不断排除。
效果如下:

8.标记雷及取消标记

玩家可以通过输入坐标对自己觉得是雷的位置进行标记,标记后为‘!’,如果觉得不是也可以取消标记,取消标记后恢复为‘*’

//标记雷
int Flagmine(char show[ROWS][COLS], int row, int col,int flag_count)
{int x = 0, y = 0;//判断标记数与雷数是否相等if (flag_count == EASY_COUNT){printf("标记的雷数和实际存在的雷数相等,无法再标记\n");return;}printf("请输入你要标记位置的坐标:>\n");scanf("%d%d", &x, &y);//判断坐标是否合法if (x > 0 && x <= row && y > 0 && y <= col){//判断该坐标是否仍未被排除if (show[x][y]=='*'){show[x][y] = '!';flag_count++;}else {printf("该位置不可能是雷,请重新输入\n");}}else{printf("该坐标不合法,请重新输入:>\n");}return flag_count;
}//取消标记
int Cancelflag(char show[ROWS][COLS], int row, int col, int flag_count)
{int x = 0;int y = 0;scanf("%d%d", &x, &y);//判断坐标是否合法if (x > 0 && x <= row && y > 0 && y <= col){//判断该位置是否被标记过if (show[x][y] == '!'){show[x][y] = '*';flag_count--;}elseprintf("该位置未被标记过,无需取消标记\n");}else{printf("该坐标不合法,请重新输入:>\n");}return flag_count;
}

图中‘!’即为标记区域

综上,此程序基本实现了扫雷小游戏的功能,有一定的娱乐性,各位小伙伴感兴趣的话可以玩一把。

源代码链接:扫雷完整版源代码

感兴趣的小伙伴也可以直接点击此处开始玩游戏,体验一把扫雷.exe,赶紧开始你的扫雷之旅吧。

各位大佬有建议可以多多交流,欢迎评论区讨论。

C语言小游戏之扫雷完整版相关推荐

  1. 【C语言小游戏】扫雷

    hello,大家好,今天我们继续为大家带来一个小游戏,扫雷.相信这个游戏又是很多人的童年,那么我们今天就来实现一下这个扫雷游戏. 目录 一.游戏简介 二.游戏的基本设计 1.游戏基本思路 2.游戏基本 ...

  2. c语言小游戏猜数字学习完函数后的小练习。

    今天为大家分享一个简单的C语言小游戏--猜数字:对于刚学习完函数的小伙伴这是一个简单的练手游戏:其中唯一超纲的内容就是随机数的生成:下面为大家简单介绍这个小游戏的实现思路.希望大家看完以后亲自实践一下 ...

  3. 扫雷——完整版!!!!!!

    今天来分享一下写的扫雷小游戏,其中包括了 展开一片的递归操作,标记,和取消标记. 除了操作界面不一样之外,逻辑和平时玩的扫雷基本是一样的. 游戏规则 给定一个棋盘,期棋盘中有若干个雷,玩家需要通过分析 ...

  4. c语言小游戏代码矿井逃生_如何选择编程语言和逃生教程炼狱

    c语言小游戏代码矿井逃生 A few weeks ago, I posted about my experience attempting to learn JavaScript, C#, Pytho ...

  5. C语言小游戏设计报告

    C语言小游戏设计报告 课程设计名称:贪吃蛇小游戏 专业班级:计科15-2 学号:150809229 姓名:XXX 一.设计目标 通过设计,培养学生对电脑的动手能力,使学生巩固<C语言程序设计&g ...

  6. C语言小游戏大全,C语言贪吃蛇小游戏(附源码)

    一.C语言小游戏大全,C语言贪吃蛇小游戏(附源码) 贪吃蛇小游戏源码和更多C语言课设项目小游戏源码免 费 下 载 链 接 如下: c语言项目课设小游戏源码资料压缩包.zip-C文档类资源-CSDN下载 ...

  7. c语言小游戏-飞机大战

    今天我们来尝试用easyx图形库实现c语言小游戏-飞机大战(源代码和图片已经在结尾给出) 先引用头文件 #include<stdio.h> #include<time.h>// ...

  8. 小游戏C语言报告,C语言小游戏设计报告

    C语言小游戏设计报告 发布时间:2020-06-19 03:34:29 来源:51CTO 阅读:1412 作者:迷蒙的天空 C语言小游戏设计报告 课程设计名称:贪吃蛇小游戏 专业班级:计科15-2 学 ...

  9. c语言s开头的函数以及作用,C语言函数大全-s开头-完整版.doc

    C语言函数大全-s开头-完整版 C语言函数大全(s开头) 函数名: sbrk 功能: 改变数据段空间位置 用法: char *sbrk(int incr); 程序例: #include#include ...

最新文章

  1. SVO中 Inverse Compositional Image Alignment方法的学习笔记
  2. 第一篇:BPE算法(附加)
  3. 第十六章 tcp_wrappers
  4. 【C 语言】指针数据类型 ( 野指针 | 避免野指针推荐方案 )
  5. MVC下实现LayUI分页的Demo
  6. 可视化太酷辽!一文了解排序和搜索算法在前端中的应用
  7. 计算客 (人人都有极客精神)爆力
  8. 嵌入式操作系统内核原理和开发(基于链表节点的内存分配算法)
  9. 交通部 城轨交通运营管理规定_重庆启动节前轨道交通运营管理安全执法检查...
  10. 浏览器“四巨头”首度合作 解决网页适配问题
  11. class加载原理和Dex加载的原理-----android插件化技术
  12. EVENT:10228 trace application of redo by kcocbk
  13. Unity3D(四)Camera和SkyBox
  14. 搭建外网能访问的web服务器
  15. Spring Boot(二):整合 JPA 及 事务控制
  16. Verilog编写VGA控制器
  17. 关于.Net的面试遐想
  18. goldengate mysql to oracle,goldengate mysql to oracle OGG-00146 求助!
  19. PTA L1-049 天梯赛座位分配(20分)(python)
  20. #萌新日志#3.使用pix2pix CycleGAN和3d CycleGAN实现T1和T2加权模态的互转

热门文章

  1. 半导体功率器件测试系统
  2. 模糊PID——Z-N整定
  3. [从头学数学] 第167节 集合与函数概念
  4. 技术点详解---双链路智能切换--h3c NQA(Network Quality Analysis)
  5. 巴比特 | 元宇宙每日必读:仅9月份就有10多个平台发布退款公告,数藏行业泡沫即将破裂?...
  6. Socket 实现非阻塞式多线程文件传输(jpg mov 等各种格式)
  7. 工具类——汉字转拼音
  8. 用 VB 打开任意盘(硬盘/U盘/光盘)的文件. (转)
  9. Nginx配置实例-动静分离
  10. python实现excel排序