C++学习心得之扫雷游戏

 更新时间:2020年03月17日 14:16:58   作者:璀璨的冰  
这篇文章主要为大家详细介绍了C++学习心得之扫雷游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C++实现扫雷游戏的具体代码,供大家参考,具体内容如下

一、序言

创建一个9*9有10个雷的扫雷游戏
文章的顺序是按照我当时的编程顺序写的,顺便写下我当初的一点思路,总的代码在文章最后,前面的都是分散的函数,有需要的朋友直接复制最后的

二、创建

创建一个头文件,一个放游戏的程序,一个放运行测试的程序

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdlib.h>//生成随机数
#include<stdio.h>
#include<time.h>//生成时间戳

#define ROW 9//行数
#define COL 9//列数
#define ROWS ROW+2
#define COLS COL+2
#define EASY 10//雷数

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);//初始函数
void DisplayBoard(char board[ROWS][COLS], int row, int col);//展示函数
void SetBoard(char board[ROWS][COLS], int row, int col);//造雷函数
void CheckBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//扫描函数

三、选择界面

进入游戏,可能出现情况三种,分别是退出,游戏和输入错误
也许有人一局完了还想玩,所以要设置循环,写完代码可以运行一下,避免最后出bug范围太大

#include"game.h"
void test()
{
 int input = 0;
 do
 {
 menu();
 printf("input choice:>");
 scanf("%d", &input);
 switch (input)
 {
 case 0:
 printf("over\n");
 break;
 case 1:
 game();
 break;
 default:
 printf("input wrong\n");
 break;
 }
 } while (input);
}
void menu()
{
 printf("*********************\n");
 printf("******* 1.game ******\n");
 printf("****** 0.over ******\n");
 printf("*********************\n");
}
int main()
{
 test();
 return 0;
}

四、游戏部分

1、声明变量和初始化

建立存储扫雷的元素的数组,这里咱们可以设置两个字符形数组,一个是标识着炸弹‘1'的mine数组,一个是用来给玩家展示的show数组
虽然是99的大小,但是在之后要由电脑扫描咱们选中点周围的区域,如果数组为9行9列,电脑在扫描最外面一行时就跟中间的部分不一样了,为了方便,咱们建立1111的数组

void game()
{
 srand((unsigned)time(NULL));//这里使用了time.h制造时间戳,以便随机生成数
 char mine[ROWS][COLS];
 char show[ROWS][COLS];
 InitBoard(mine, ROWS, COLS, '0');
 InitBoard(show, ROWS, COLS, '*');
 DisplayBoard(show, ROW, COL);
 SetBoard(mine, ROW, COL);
 CheckBoard(mine, show, ROW, COL);
}
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
 int i = 0;
 int j = 0;
 for (i = 0; i < rows; i++)
 {
 for (j = 0; j < cols; j++)
 {
 board[i][j] = set;
 }
 } 
}

2、展示函数

申明和定义好变量,肯定要让玩家看到游戏盘的变化情况才能玩,所以写一个展示函数
mine数组中炸弹用‘1'来表示,不是炸弹用‘0'表示,show数组中我们用‘*'表示一个区域,然后选中的点要是周围无炸弹,就是‘ ',否则就标识出周围的炸弹数。

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
 int i = 0;
 int j = 0;
 printf("----------------------------");
 printf("\n");
 for (i = 0; i <= row; 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");
 }
 printf("----------------------------");
 printf("\n");
}

3、造炸弹

这里咱们在头文件定义炸弹数,以后想玩多点炸弹,修改一个数就行,方便快捷

void SetBoard(char board[ROWS][COLS], int row, int col)
{
 int x = 0;
 int y = 0;
 int num = EASY;
 while (num)
 {
 x = rand() % ROW + 1;
 y = rand() % COL + 1;
 if (board[x][y] == '0')
 {
 board[x][y] = '1';
 num--;
 }
 }
}

4、扫描函数

进入游戏,玩家只有选择了要检查的点才能继续,这里有三种情况,因为要有很多次选择,所以采用循环
(1)选中雷区,那么直接跳出循环,游戏结束
(2)没选中雷区,电脑会扫描周围的区域,把周围无雷的点展开,展开周围有雷的点
这里还要说一下mine数组为什么要用‘0'和‘1'来做标记,因为0和1这两个字符在ascII码表里是连续的,一会在电脑扫描周围时可以直接通过减法算出周围的雷数

void CheckBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
 int ret = 0;
 int x = 0;
 int y = 0;
 int num = 0;
 while (ret < ROW*COL - EASY)
 {
 printf("输入排查坐标\n");
 scanf("%d%d", &x, &y);
 if (x > 0 && x <= row && y > 0 && y <= col)
 {
 if (mine[x][y] == '1')//选中雷区,游戏结束
 {
 printf("炸死\n");
 DisplayBoard(mine, row, col);//展示mine区域
 break;//跳出循环
 }
 else//没踩中雷区
 {
  ZeroLine(mine, show, x, y);//展开周围的区域
 DisplayBoard(show, row, col);
 ret++;
 }
 }
 else
 {
 printf("input wrong\n");
 }
 }
 if (ret == ROW * COL - EASY)
 {
 printf("胜利\n");
 }
}
void ZeroLine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
 int ret = 0;
 ret = AroundNum(mine, x, y);//扫描函数,扫描该点周围雷数
 if (x >= 0 && y >= 0 && x < ROWS && y < COLS)
 {
 if (ret == 0)
 {
 show[x][y] = ' ';//无雷则为空白
 if (mine[x][y + 1] == '0' && show[x][y + 1] == '*')
 {
  ZeroLine(mine, show, x, y + 1);
 }
 if (mine[x][y - 1] == '0' && show[x][y - 1] == '*')
 {
  ZeroLine(mine, show, x, y - 1);
 }
 if (mine[x - 1][y] == '0' && show[x - 1][y] == '*')
 {
  ZeroLine(mine, show, x - 1, y);
 }
 if (mine[x + 1][y] == '0' && show[x + 1][y] == '*')
 {
  ZeroLine(mine, show, x + 1, y);
 }
 if (mine[x + 1][y + 1] == '0' && show[x + 1][y + 1] == '*')
 {
  ZeroLine(mine, show, x + 1, y + 1);
 }
 if (mine[x - 1][y - 1] == '0' && show[x - 1][y - 1] == '*')
 {
  ZeroLine(mine, show, x - 1, y - 1);
 } 
 if (mine[x + 1][y - 1] == '0' && show[x + 1][y - 1] == '*')
 {
  ZeroLine(mine, show, x + 1, y - 1);
 }
 if (mine[x - 1][y + 1] == '0' && show[x - 1][y - 1] == '*')
 {
  ZeroLine(mine, show, x - 1, y + 1);
 }
 }
 else
 {
 show[x][y] = ret + '0';
 }
 }
}
int AroundNum(char mine[ROWS][COLS], int x, int y)
{
 return mine[x - 1][y - 1] + mine[x][y - 1] + mine[x - 1][y] +
 mine[x + 1][y + 1] + mine[x][y + 1] + mine[x + 1][y] +
 mine[x - 1][y + 1] + mine[x + 1][y - 1] - 8 * mine[x][y];
}

五、总代码

1、头文件

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdlib.h>
#include<stdio.h>
#include<time.h>

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY 10

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetBoard(char board[ROWS][COLS], int row, int col);
void CheckBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

2、游戏部分

#include"game.h"

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
 int i = 0;
 int j = 0;
 for (i = 0; i < rows; i++)
 {
 for (j = 0; j < cols; j++)
 {
 board[i][j] = set;
 }
 } 
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
 int i = 0;
 int j = 0;
 printf("----------------------------");
 printf("\n");
 for (i = 0; i <= row; 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");
 }
 printf("----------------------------");
 printf("\n");
}
void SetBoard(char board[ROWS][COLS], int row, int col)
{
 int x = 0;
 int y = 0;
 int num = EASY;
 while (num)
 {
 x = rand() % ROW + 1;
 y = rand() % COL + 1;
 if (board[x][y] == '0')
 {
 board[x][y] = '1';
 num--;
 }
 }
}
int AroundNum(char mine[ROWS][COLS], int x, int y)
{
 return mine[x - 1][y - 1] + mine[x][y - 1] + mine[x - 1][y] +
 mine[x + 1][y + 1] + mine[x][y + 1] + mine[x + 1][y] +
 mine[x - 1][y + 1] + mine[x + 1][y - 1] - 8 * mine[x][y];
}
void ZeroLine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
 int ret = 0;
 ret = AroundNum(mine, x, y);
 if (x >= 0 && y >= 0 && x < ROWS && y < COLS)
 {
 if (ret == 0)
 {
 show[x][y] = ' ';
 if (mine[x][y + 1] == '0' && show[x][y + 1] == '*')
 {
  ZeroLine(mine, show, x, y + 1);
 }
 if (mine[x][y - 1] == '0' && show[x][y - 1] == '*')
 {
  ZeroLine(mine, show, x, y - 1);
 }
 if (mine[x - 1][y] == '0' && show[x - 1][y] == '*')
 {
  ZeroLine(mine, show, x - 1, y);
 }
 if (mine[x + 1][y] == '0' && show[x + 1][y] == '*')
 {
  ZeroLine(mine, show, x + 1, y);
 }
 if (mine[x + 1][y + 1] == '0' && show[x + 1][y + 1] == '*')
 {
  ZeroLine(mine, show, x + 1, y + 1);
 }
 if (mine[x - 1][y - 1] == '0' && show[x - 1][y - 1] == '*')
 {
  ZeroLine(mine, show, x - 1, y - 1);
 } 
 if (mine[x + 1][y - 1] == '0' && show[x + 1][y - 1] == '*')
 {
  ZeroLine(mine, show, x + 1, y - 1);
 }
 if (mine[x - 1][y + 1] == '0' && show[x - 1][y - 1] == '*')
 {
  ZeroLine(mine, show, x - 1, y + 1);
 }
 }
 else
 {
 show[x][y] = ret + '0';
 }
 }
}
void CheckBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
 int ret = 0;
 int x = 0;
 int y = 0;
 int num = 0;
 while (ret < ROW*COL - EASY)
 {
 printf("输入排查坐标\n");
 scanf("%d%d", &x, &y);
 if (x > 0 && x <= row && y > 0 && y <= col)
 {
 if (mine[x][y] == '1')
 {
 printf("炸死\n");
 DisplayBoard(mine, row, col);
 break;
 }
 else
 {
  ZeroLine(mine, show, x, y);
 DisplayBoard(show, row, col);
 ret++;
 }
 }
 else
 {
 printf("input wrong\n");
 }
 }
 if (ret == ROW * COL - EASY)
 {
 printf("胜利\n");
 }
}

3、检测部分

#include"game.h"
void menu()
{
 printf("*********************\n");
 printf("******* 1.game ******\n");
 printf("****** 0.over ******\n");
 printf("*********************\n");
}
void game()
{
 srand((unsigned)time(NULL));
 char mine[ROWS][COLS];
 char show[ROWS][COLS];
 InitBoard(mine, ROWS, COLS, '0');
 InitBoard(show, ROWS, COLS, '*');
 DisplayBoard(show, ROW, COL);
 SetBoard(mine, ROW, COL);
 CheckBoard(mine, show, ROW, COL);
}
void test()
{
 int input = 0;
 do
 {
 menu();
 printf("input choice:>");
 scanf("%d", &input);
 switch (input)
 {
 case 0:
 printf("over\n");
 break;
 case 1:
 game();
 break;
 default:
 printf("input wrong\n");
 break;
 }
 } while (input);
}
int main()
{
 test();
 return 0;
}

更多精彩游戏小代码,请点击《游戏专题》阅读

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 用C++来解决3*3拼图的问题

    用C++来解决3*3拼图的问题

    这篇文章主要介绍了用C++来解决3*3拼图的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • C语言利用UDP实现群聊聊天室的示例代码

    C语言利用UDP实现群聊聊天室的示例代码

    UDP是一个轻量级、不可靠、面向数据报的、无连接的传输层协议,多用于可靠性要求不严格,不是非常重要的传输,如直播、视频会议等等。本文将利用UDP实现简单的群聊聊天室,感兴趣的可以了解一下
    2022-08-08
  • C语言实现万年历

    C语言实现万年历

    这篇文章主要为大家详细介绍了C语言实现万年历,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • C/C++实现快速排序算法的两种方式实例

    C/C++实现快速排序算法的两种方式实例

    快速排序是一种采用分治思想,在实践中通常运行较快一种排序算法,这篇文章主要给大家介绍了关于C/C++实现快速排序的两种方式的相关资料,文中给出了详细的示例代码,需要的朋友可以参考下
    2021-08-08
  • C++执行shell命令的多种实现方法

    C++执行shell命令的多种实现方法

    在linux系统下,用C++程序执行shell命令有多种方式,主要介绍了3中方法,具有一定的参考价值,感兴趣的可以了解一下
    2021-11-11
  • C语言 详解字符串基础

    C语言 详解字符串基础

    在 C 语言中,字符串实际上是使用空字符 \0 结尾的一维字符数组。因此,\0 是用于标记字符串的结束。空字符(Null character)又称结束符,缩写 NUL,是一个数值为 0 的控制字符,\0 是转义字符,意思是告诉编译器,这不是字符 0,而是空字符
    2022-04-04
  • C语言container of()函数案例详解

    C语言container of()函数案例详解

    这篇文章主要介绍了C语言container of()函数案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • 利用Matlab绘制一个可爱的南瓜灯

    利用Matlab绘制一个可爱的南瓜灯

    这篇文章主要为大家介绍了如何利用Matlab绘制一个可爱的南瓜灯!文中的示例代码讲解详细,对我们学习Matlab有一定帮助,需要的可以参考一下
    2022-02-02
  • 用C# 实现鼠标框选效果的实现代码

    用C# 实现鼠标框选效果的实现代码

    本篇文章是对用C#实现鼠标框选效果的实现代码进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++内存泄漏及检测工具详解

    C++内存泄漏及检测工具详解

    最简单的方法当然是借助于专业的检测工具,比较有名如BoundsCheck,功能非常强大,相信做C++开发的人都离不开它。此外就是不使用任何工具,而是自己来实现对内存泄露的监控
    2013-10-10

最新评论