C++实现扫雷游戏示例讲解

作者:叁三山雨 时间:2022-05-03 18:49:05 

C/C++实现扫雷小游戏

源代码:

github:https://github.com/KamSss/C-Practice/tree/master/Minesweeper扫雷小游戏/Minesweeper扫雷

总体构造:

a.简易的游戏菜单逻辑
b.初始化棋盘
c.布置雷的位置
d.排雷、棋盘打印、判断输赢(难点)

a.简易的游戏菜单逻辑

简单的通过一个输入0和1实现判断是玩游戏还是退出游戏的逻辑
输入1则进入游戏
输入0则break退出游戏,且退出do…while循环,程序结束。


void test(){
int input = 0;
do{
menu();
cout << "请输入:>--";
cin >> input;
switch (input)
{
case 1:
game();
break;
case 0:
cout << "退出游戏" << endl;
break;
default:
cout << "    选择错误!请重新输入" << endl;
break;
}
} while (input);
}

b.初始化棋盘

一、越界情况的考虑

为了减少边界情况可能出现越界访问的情况,把棋盘扩大一圈,但是在显示的时候只显示没扩大之前的棋盘。

C++实现扫雷游戏示例讲解

二、棋盘打印的考虑

如果只使用一个二维数组,同时要记录雷的位置和每一个位置附近的雷数以及点击和未点击的位置显示显然不合适。
所以: 初始化两个棋盘,一个专门用来存放雷的位置,一个专门用于打印当前棋盘给玩家看。


//初始化格子
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
memset(&board[0][0], set, rows*cols*sizeof(board[0][0]));
}

初始化完,得到一个全0的雷盘,和一个全*的显示盘。

c.布置雷的位置

这里用随机数布置雷的位置,会不会对同一个点多次放雷呢?这里的解决办法是,如果当前随机到的位置已经有雷就再随机一个位置防雷。


void SetMine(char board[ROWS][COLS], int row, int col)
{
srand((unsigned int)time(NULL));
int count = EASY_COUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}

d.排雷、棋盘打印、判断输赢(难点)d

排雷的逻辑判断:

C++实现扫雷游戏示例讲解

如果没有雷如何打印棋盘呢?
扫雷应该做到,“点击”棋盘之后,一路“打开”到最近的出现雷的边界上。


void Spread(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
int offset_x = 0;
int offset_y = 0;
int count = 0;
//坐标合法
if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
{
//遍历周围坐标
for (offset_x = -1; offset_x <= 1; offset_x++)
{
for (offset_y = -1; offset_y <= 1; offset_y++)
{
//如果这个坐标不是雷
if (mine[x + offset_x][y + offset_y] == '0')
{
//统计周围雷的个数
count = GetMineCount(mine, x + offset_x, y + offset_y);
if (count == 0)
{
if (show[x + offset_x][y + offset_y] == '*')
{
show[x + offset_x][y + offset_y] = ' ';
Spread(mine, show, x + offset_x, y + offset_y);
}
}
else
{
show[x + offset_x][y + offset_y] = count + '0';
}
}
}
}
}
}

如何判断输赢:
很简单,踩到雷 board[i][j] == 1
所有的雷都出现了 * == MineCount 就赢了


//判断是否排雷成功
int IsWin(char show[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
int count = 0;
for (i = 1; i <= row; i++)
{
for (j = 1; j <= col; j++)
{
if (show[i][j] == '*')
{
count++;
}
}
}
return count == EASY_COUNT;
}

来源:https://blog.csdn.net/qq_42685588/article/details/98476029

标签:C++,游戏,扫雷
0
投稿

猜你喜欢

  • 使用mybatis-plus的insert方法遇到的问题及解决方法(添加时id值不存在异常)

    2023-11-12 19:25:55
  • 安卓GreenDao框架一些进阶用法整理

    2023-06-17 03:27:21
  • 最值得Java开发者收藏的网站

    2022-03-09 15:57:08
  • java 图片验证码的实现代码

    2023-11-09 13:33:52
  • 使用Postman传递arraylist数据给springboot方式

    2022-08-27 01:13:01
  • Winform跨线程操作的简单方法

    2023-04-28 09:38:46
  • C# 添加对System.Configuration.dll文件的引用操作

    2022-03-05 22:20:31
  • .Net Winform开发笔记(四)透过现象看本质

    2022-06-22 09:36:24
  • SpringBoot中实现接收文件和对象

    2022-02-08 10:16:53
  • RestTemplate自定义请求失败异常处理示例解析

    2021-12-03 22:13:17
  • ContentProvider启动流程示例解析

    2023-07-31 03:57:34
  • 深入理解Java设计模式之命令模式

    2023-11-24 11:06:31
  • SpringBoot FreeWorker模板技术解析

    2023-08-09 09:14:39
  • Java数据类型分类与基本数据类型转换

    2023-08-10 08:33:37
  • C# TreeView无限目录树实现方法

    2023-04-20 03:05:46
  • java反射机制给实体类相同字段自动赋值实例

    2023-11-25 19:52:29
  • springboot整合Quartz实现动态配置定时任务的方法

    2023-03-08 22:13:10
  • java中如何截取字符串最后一位

    2023-11-27 00:51:16
  • C# 7.0中解构功能详解

    2022-08-11 21:06:34
  • 解决Springboot启动报错:类文件具有错误的版本61.0,应为 52.0

    2023-03-13 02:16:11
  • asp之家 软件编程 m.aspxhome.com