扫雷大战(命令行版,可以连续扫除一片空白区域)

news/2024/11/24 5:49:56/

扫雷大战(含递归算法扫出空白)

  • 扫雷的基本思路
  • 扫雷代码实现的详细步骤
  • 完整代码
    • 1、game.h部分(运行游戏需要的头文件和函数的声明)
    • 2、game.c部分(游戏引擎)
    • 3、test.c部分(测试游戏)

扫雷的基本思路

1.创建菜单,菜单中包含两个选项,


***** 1.开始游戏*****
***** 2.退出游戏*****


在这里插入图片描述
2.用switch语句实现,游戏的选择开始或者退出。
3.选择开始游戏就会打印出棋盘。
在这里插入图片描述
4.游戏部分创建两个二维数组,分别是mine和show数组。mine数组是有关炸弹的数组,有炸弹的位置是’1’,没有炸弹的位置是’0’;show数组是查找炸弹的数组,不知道的位置是‘’,查出来的位置的数字是周围的9宫格内炸弹个数
5、初始化这两个二维数组,mine数组初始化为‘0’,show数组初始化为‘

6、打印棋盘,每次输入坐标后都打印一次棋盘,以便观察
在这里插入图片描述
7、实现布置雷的操作:和三子棋一样需要rand(头文件:stdlib.h)和time(头文件:time.h),结合使用可以使电脑随机布置雷.
8、实现排查雷的操作:玩家输入一个坐标,若踩雷则会提醒游戏结束;若未踩雷,并且以该位置为中心的9宫格内没有雷,则在show数组中的相应位置中显示周围没有累的地方。(必须是与该坐标为中心)。
9、在游戏结束后,继续打印选择的菜单,由玩家决定是否继续进行游戏。

扫雷代码实现的详细步骤

1.首先创建3个文件:
在这里插入图片描述
2.game.h中主要用来包含test.c和game.c中所需要的头文件,然后,test.c和game.c包含game.h就可以达到代码的高复用性,也更加方便维护代码。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.在test.c中创建main()函数和test()函数,amin()函数调用test()函数完成,整个游戏的调用,test()函数中用switch创建一个简单的选择功能是实现游戏的开始和退出。
在这里插入图片描述
4.创建游戏选择的菜单
在这里插入图片描述
5.游戏棋盘的大小设置,这里我都设计为1111,也就是11行,11列,游戏区是99,这样的目的是方便判断边界地方的九宫格内雷的个数,我设置这个棋盘有10颗雷。
在这里插入图片描述
6.初始化棋盘
在这里插入图片描述
7.随机埋雷,我们这里设置了10颗雷。
在这里插入图片描述

8.打印棋盘
在这里插入图片描述

9.游戏棋盘的设置,这里我设计了两个棋盘,一个棋盘(mine)是用来存放地雷的位置,游戏开始的时候,初始化一次,布雷完成后这个数组就不会发生改变,另一个棋盘(show)是用来存放我们排雷的位置,初始化为全‘*’,我们输入坐标,然后计算机判断这个坐标在mine棋盘中是否是地雷,如果不是地雷则会在show棋盘中显示以该坐标为中心的九宫格内有多少个雷,如果是地雷,则游戏结束。

在这里插入图片描述

//游戏引擎
void game(){//记录排掉多少个是雷的地方int count = 0;//存放地雷的数组char mine[ROWS][COLS];//存放展示排雷的数组char show[ROWS][COLS];//初始化InitBoard(mine, ROWS, COLS, '0');InitBoard(show, ROWS, COLS, '*');//随机埋雷setMine(mine, ROWS, COLS);while (count != EASY_COUNT){int x = -1, y = -1;//打印棋盘PrintBoard(show, ROWS, COLS);//PrintBoard(mine, ROWS, COLS);printf("请输入:>");scanf("%d %d", &x, &y);// 判断x和y的合法性   返回1表示合法   返回0表示不合法if (is_true(show, x, y) == 0){printf("坐标不合法请重新输入\n");continue;}//判断该坐标是否是 地雷   1表示是雷  0表示不是雷if (is_mine(mine, x, y)){printf("很遗憾,踩到雷了,游戏结束\n按任意键继续游戏\n");system("pause");break;}//扫除雷space(show, mine, x, y);//show[x][y] = (char)(FindMine(mine, x, y) + '0');/*if (((char)(FindMine(mine, x, y) + '0')) == '0'){space(show, mine, x, y);}else{show[x][y] = (char)(FindMine(mine, x, y) + '0');}*/count = show_count(show, ROWS, COLS);system("cls");}if (count == EASY_COUNT){printf("恭喜你,排雷成功!\n按任意键继续游戏\n");system("pause");}}`

10.排雷算法,这里用到了递归,是为了展>开旁边不是雷的地方,增强游戏的可玩性,
该算法首先判断以该位置为中心的九宫格内是否有雷,如果有雷就直接改变该位置的内容,不会展开其他的地方,如果没有雷,会进行展开,直到有雷,递归才会结束。
该递归算法结束的条件是:以x,y为中心的九宫格内有雷;
递归结束的另外一个条件是,判断的位置到了棋盘的边界。
防止重复检测同一个位置,将该位置赋值为‘ ’空格。
在这里插入图片描述

完整代码

1、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//表示棋盘中有10个雷
#define EASY_COUNT 10//游戏引擎
void game();//游戏菜单
void menu();

2、game.c部分(游戏引擎)

#define _CRT_SECURE_NO_WARNINGS 1#include "game.h"//游戏菜单
void menu()
{printf("------ 扫雷游戏 -------\n");printf("**********************\n");printf("****** 1.开始游戏 *****\n");printf("****** 0.退出游戏 *****\n");printf("**********************\n");printf("------ 扫雷游戏 -------\n");
}//初始化
InitBoard(char board[ROWS][COLS], int row, int col, char ret)
{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){board[i][j] = ret;}}
}//打印棋盘
PrintBoard(char board[ROWS][COLS], int row, int col)
{int i = 1;printf("------ 扫雷游戏 -------\n");printf("    ");for (i = 1; i < row - 1; i++){printf("%d ", i);}printf("\n  ");for (i = 0; i < row - 1; i++){printf("--");}printf("\n");for (i = 1; i < row - 1; i++){int j = 1;printf("%d | ", i);for (j = 1; j < col - 1; j++){printf("%c ", board[i][j]);}printf("\n");}printf("------ 扫雷游戏 -------\n");
}//随机埋雷   '1'表示有雷    '0'表示无雷
setMine(char mine[ROWS][COLS], int row, int col)
{int count = EASY_COUNT;while (count){int x = (rand() % 9) + 1;int y = (rand() % 9) + 1;if (mine[x][y] != '1'){mine[x][y] = '1';count--;}}}//判断坐标的合法性
int is_true(char show[ROWS][COLS], int x, int y)
{if (x >= 1 && x <= ROWS - 1 && y >= 1 && y <= ROWS - 1 && show[x][y] == '*'){return 1;}return 0;
}//判断该坐标是否是雷   1表示是雷  0表示不是雷
int is_mine(char mine[ROWS][COLS], int x, int y)
{return ((int)(mine[x][y] - '0'));
}//扫除雷
int FindMine(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');/*int count = 0;int i, j;for (i = x - 1; i <= x + 1; i++){for (j = y - 1; y <= y + 1; y++){if (mine[i][j] == '1'){count++;}}}return count;*/
}//展示0周围的一片
void space(char board[ROWS][COLS], char mine[ROWS][COLS], int x, int y)
{int i;if (FindMine(mine, x, y) == 0){board[x][y] = ' ';for (i = x - 1; i <= x + 1; i++){int j;for (j = y - 1; j <= y + 1; j++){if (i > 0 && i <= ROW && j > 0 && j <= COL && mine[i][j] != '1' && board[i][j] == '*'){space(board, mine, i, j);}}}}elseboard[x][y] = '0' + FindMine(mine, x, y);}//计算show中*的个数
int show_count(char show[ROWS][COLS], int row, int col)
{int count = 0;int i;for (i = 1; i < row - 1; i++){int j;for (j = 1; j < col - 1; j++){if (show[i][j] == '*'){count++;}}}return count;
}//游戏引擎
void game()
{//记录排掉多少个是雷的地方int count = 0;//存放地雷的数组char mine[ROWS][COLS];//存放展示排雷的数组char show[ROWS][COLS];//初始化InitBoard(mine, ROWS, COLS, '0');InitBoard(show, ROWS, COLS, '*');//随机埋雷setMine(mine, ROWS, COLS);while (count != EASY_COUNT){int x = -1, y = -1;//打印棋盘PrintBoard(show, ROWS, COLS);//PrintBoard(mine, ROWS, COLS);printf("请输入:>");scanf("%d %d", &x, &y);// 判断x和y的合法性   返回1表示合法   返回0表示不合法if (is_true(show, x, y) == 0){printf("坐标不合法请重新输入\n");continue;}//判断该坐标是否是 地雷   1表示是雷  0表示不是雷if (is_mine(mine, x, y)){printf("很遗憾,踩到雷了,游戏结束\n按任意键继续游戏\n");system("pause");break;}//扫除雷space(show, mine, x, y);//show[x][y] = (char)(FindMine(mine, x, y) + '0');/*if (((char)(FindMine(mine, x, y) + '0')) == '0'){space(show, mine, x, y);}else{show[x][y] = (char)(FindMine(mine, x, y) + '0');}*/count = show_count(show, ROWS, COLS);system("cls");}if (count == EASY_COUNT){printf("恭喜你,排雷成功!\n按任意键继续游戏\n");system("pause");}}

3、test.c部分(测试游戏)

#define _CRT_SECURE_NO_WARNINGS 1#include "game.h"void test()
{int input = 0;srand((unsigned)time(NULL));do{//游戏菜单menu();scanf("%d", &input);switch (input){case 1:game();system("cls");break;case 0:printf("退出游戏\n");break;default:printf("输入错误\n");break;}} while (input);}int main()
{//扫雷游戏测试函数test();return 0;
}

这份博客👍如果对你有帮助,给博主一个免费的点赞以示鼓励欢迎各位🔎点赞👍评论收藏⭐️,谢谢!!!
如果有什么疑问或不同的见解,欢迎评论区留言欧👀


http://www.ppmy.cn/news/706082.html

相关文章

接口测试必备技能-常见接口协议解析

服务与服务之间传递数据包&#xff0c;往往会因为不同的应用场景&#xff0c;使用不同的通讯协议进行传递。比如网站的访问&#xff0c;常常会使用 HTTP 协议进行传递&#xff0c;文件传输使用 FTP&#xff0c;邮件传递使用 SMTP。上述的三种类型的协议都处于网络模型中的应用层…

王者空白名字重复名字小程序源码带流量主

没啥可介绍的&#xff0c;利用大量空白代码实现改空白名重复名 程序名字&#xff1a;一亿重名 源码大小&#xff1a;813kb 源码类型&#xff1a;uniapp&#xff08;云开发&#xff09; 源码功能&#xff1a;改空白名&#xff0c;重复名&#xff0c;查最低战力&#xff0c;扫…

html空桃心的特殊符号,王者荣耀名字特殊符号空白代码 名字特殊符号爱心尾巴大全可复制...

王者荣耀名字特殊符号空白代码是什么?爱心尾巴特殊符号怎么打?特殊符号可以让你的ID变得更加的有个性,下面就为大家介绍一些非常特殊的符号,让你的ID永远的与众不同,想换ID的朋友一定要来看看! 王者荣耀特殊符号空白代码名字 点击输入框,弄空白的名字必须要输入符号,需…

lol空白名

韩文支持词&#xff1a;너도운명 日文支持词&#xff1a;こひるいまき 单子的改法&#xff1a;도我도 韩文是不会显示的&#xff0c;所以看起来就是单个字

传奇开服技术基础十条处理办法110.42.2

1:怎么添加GM,游戏管理员! 答:在游戏版本路径中的-MirServerMir200EnvirAdminList.txt文本内, 从这里增添需要重新启动,为了方便都在M2server中进行增添M2-查询-文件列表信息-管理员列表中进行增添,增添好了即时生效.人物在游戏里需要小退开始生效! 2:假如增添删除商铺物品! …

如果制作投票选举投票制作制作一个投票在线制作投票

用户在使用微信投票的时候&#xff0c;需要功能齐全&#xff0c;又快捷方便的投票小程序。 而“活动星投票”这款软件使用非常的方便&#xff0c;用户可以随时使用手机微信小程序获得线上投票服务&#xff0c;很多用户都很喜欢“活动星投票”这款软件。 “活动星投票”小程序在…

ActiveX控件的MFC设计之旅-第15步

在VB和类似的包容器在属性视图中显示控件的属性&#xff0c;特别是枚举类型的属性时&#xff0c;会有一个下拉按钮&#xff0c;当点击该按钮时&#xff0c;会弹出一个列表框&#xff0c;显示一些友好的文字&#xff0c;供用户选择。而对于某些特殊的属性&#xff0c;如字体等&a…

ActiveX控件属性的下拉列表

1、给控件类加上IPerPropertyBrowsingImpl接口 public IPerPropertyBrowsingImpl 在BEGIN_COM_MAP/END_COM_MAP()中间加上 COM_INTERFACE_ENTRY_IMPL(IPerPropertyBrowsing) 2、 在该类中添加下列函数 (A)STDMETHOD(MapPropertyToPage)(DISPID dispid, CLSID *pClsid);(B)…