当前位置:   article > 正文

C++实现经典扫雷游戏_c++扫雷

c++扫雷

目录

1、演示视频

2、思路解析

 3、份文件编写的源码:


1、演示视频

建议先看几遍视频在下文。

QQ录屏扫雷游戏

2、思路解析

这款游戏有三个难度(11,11,9,9,10)(18,18,16,16,40)(18,32,16,30,99)

一共有五个参数,意思是,棋盘大小为9*9,为了后续操作方便我们使用11*11的字符数组来存放棋盘,将棋盘放在数组的中间。九九八十一个格子中我们我安置10个雷,也就是第五个参数。

所以我们的game 函数就可以写为:(我们可以通过调节参数参数大小来调节游戏难度)

void game(int ROWS,int COLS,int ROW,int COL,int EASY_COUNT);

接下来,我们根据游戏规则开始设计,我们以简单模式为例进行详解(因为游戏难度只需调节参数即可),在棋盘中的隐藏这十枚炸弹,它们的位置我们并不知道,但是当我们选择一个坐标进行排雷是,棋盘又会时时给予我们信息反馈,很明显,我们至少需要两个字符数组,用来埋雷起名为mine[11][11],一个用来展示起名为show[11][11]。游戏开始十之初,这两个就已经初始化好了,先是把mine[11][11]全部初始化为字符零 '0',然后随机产生十个坐标埋下十颗炸弹,show[11][11]的元素全部初始化为星号 '*'。然后我们就可以开始输入坐标排雷了,哈哈哈。我们选择一个地方(x,y)排雷,如果这个地方就是炸弹,不好意思游戏结束,如果这个地方不是炸弹,那么就要统计这个位置周围一圈八个地方有几颗炸弹即get_num()操作,有几颗炸弹就把show[x][y]改为几,如果这八个位置没有炸弹,那么就把这个位置show[x][y]==' '设置为空格,并对其周围八个位置重复上述操作,这里我们是使用递归来实现的。

 3、份文件编写的源码:

重难点全在注释里面了

game.h

  1. #include <iostream>
  2. #include <time.h>
  3. using namespace std;
  4. #define MAXSIZE 50
  5. //#define ROW 9
  6. //#define COL 9
  7. //#define ROWS ROW+2
  8. //#define COLS COL+2
  9. //#define EASY_COUNT 10
  10. /*
  11. #define ROW 30
  12. #define COL 16
  13. #define ROWS ROW+2
  14. #define COLS COL+2
  15. #define EASY_COUNT 99
  16. */
  17. //#define ROW 9
  18. //#define COL 9
  19. //#define ROWS ROW+2
  20. //#define COLS COL+2
  21. //#define EASY_COUNT 10
  22. //初始化棋盘
  23. void Init_qipan(char board[MAXSIZE][MAXSIZE], int row, int col, char set);
  24. //打印棋盘
  25. void Display_qipan(char board[MAXSIZE][MAXSIZE], int rows, int cols);
  26. //布置雷
  27. void Set_zhadan(char board[MAXSIZE][MAXSIZE], int row, int col,int EASY_COUNT);
  28. //扫雷
  29. int Fine_zhadan3(char mine[MAXSIZE][MAXSIZE], char show[MAXSIZE][MAXSIZE], int row, int col, int x, int y,int *win);

源.cpp

  1. #include "game.h"
  2. using namespace std;
  3. void game(int ROWS,int COLS,int ROW,int COL,int EASY_COUNT)
  4. {
  5. //为了避免重复判断数组越界问题,为9*9的棋盘横纵各加两组空间
  6. char mine[MAXSIZE][MAXSIZE];//布置雷的隐藏棋盘
  7. char show[MAXSIZE][MAXSIZE];//展示给玩家的棋盘
  8. Init_qipan(mine, ROWS, COLS, '0');
  9. Init_qipan(show, ROWS, COLS, '*');
  10. Set_zhadan(mine, ROW, COL, EASY_COUNT);//布置雷
  11. //排查雷
  12. int win = 0;
  13. while (win<ROW*COL-EASY_COUNT)
  14. {
  15. Display_qipan(show, ROWS, COLS);
  16. cout << "请输入要排查的坐标(x,y)>";
  17. int x = 0, y = 0;
  18. cin >> x >> y;
  19. if (x>=1 && x<=ROW && y>=1 && y<=COL)//坐标合法
  20. {
  21. if (mine[x][y] == '#')
  22. {
  23. cout << "哈哈哈,你被炸死了!" << endl;
  24. cout << "给你看看地雷的位置,别让你死不瞑目!" << endl;
  25. Display_qipan(mine, ROWS, COLS);//让你死得瞑目
  26. cout << "扫雷失败,游戏结束!" << endl;
  27. break;
  28. }
  29. else if (show[x][y] != '*')
  30. {
  31. system("cls");
  32. cout << "该坐标已排查,请勿重复排查!" << endl;
  33. }
  34. else{
  35. system("cls");
  36. Fine_zhadan3(mine, show, ROW, COL, x, y, &win);
  37. cout << "排雷成功,请继续扫雷!游戏进度: " << win<<'/' << ROW * COL - EASY_COUNT << endl;
  38. }
  39. }
  40. else
  41. {
  42. system("cls");
  43. cout << "输入坐标不合法,请重新输入!" << endl;
  44. }
  45. }
  46. if (win == ROW * COL - EASY_COUNT)
  47. {
  48. cout << "扫雷成功,游戏胜利!" << endl;
  49. Display_qipan(mine, ROWS, COLS);//让你死得瞑目
  50. }
  51. }
  52. void caidan()
  53. {
  54. cout << "**************************************" << endl;
  55. cout << "******* 1.play( 9 * 9 ) ********" << endl;
  56. cout << "******* 2.play(16 * 16) ********" << endl;
  57. cout << "******* 3.play(30 * 30) ********" << endl;
  58. cout << "******* 0.exit ********" << endl;
  59. cout << "**************************************" << endl;
  60. }
  61. void test01()
  62. {
  63. int input = 0;
  64. do
  65. {
  66. srand((unsigned int)time(NULL));
  67. caidan();
  68. cout << "请选择:>";
  69. cin >> input;
  70. switch (input)
  71. {
  72. case 3:
  73. system("cls");
  74. cout << "扫雷游戏开始:" << endl;
  75. game(18,32,16,30,99);
  76. break;
  77. case 2:
  78. system("cls");
  79. cout << "扫雷游戏开始:" << endl;
  80. game(18,18,16,16,40);
  81. break;
  82. case 1:
  83. system("cls");
  84. cout << "扫雷游戏开始:" << endl;
  85. game(11,11,9,9,10);
  86. break;
  87. case 0:
  88. cout << "游戏已退出!" << endl;
  89. break;
  90. default:
  91. cout << "选择错误,请重新选择>" << endl;
  92. break;
  93. }
  94. } while (input);
  95. }
  96. int main() {
  97. test01();
  98. return 0;
  99. }

game.cpp

  1. #include "game.h"
  2. void Init_qipan(char board[MAXSIZE][MAXSIZE], int row, int col, char set)
  3. {
  4. int i = 0;
  5. for (i = 0; i < row; i++)
  6. {
  7. int j = 0;
  8. for (j = 0; j < col; j++)
  9. {
  10. board[i][j] = set;
  11. }
  12. }
  13. }
  14. void Display_qipan(char board[MAXSIZE][MAXSIZE], int rows, int cols)
  15. {
  16. int i = 0;
  17. cout << "-------------扫雷-------------" << endl;
  18. for (i = 0; i < rows - 1; i++)
  19. {
  20. int j = 0;
  21. for (j = 0; j < cols - 1; j++)
  22. {
  23. if (i == 0 || j == 0)
  24. {
  25. cout <<' ' << "\033[36;1m" << (i + j)%10 << "\033[0m" << ' ';
  26. }
  27. else if (board[i][j] == '4')
  28. {
  29. cout << ' ' << "\033[31;1m" << board[i][j] << "\033[0m" << ' ';
  30. }
  31. else if (board[i][j] == '3')
  32. {
  33. cout << ' ' << "\033[34;1m" << board[i][j] << "\033[0m" << ' ';
  34. }
  35. else if (board[i][j] == '2')
  36. {
  37. cout << ' ' << "\033[33;1m" << board[i][j] << "\033[0m" << ' ';
  38. }
  39. else if (board[i][j] == '1')
  40. {
  41. cout << ' ' << "\033[32;1m" << board[i][j] << "\033[0m" << ' ';
  42. }
  43. else if (board[i][j] == '#')
  44. {
  45. cout << ' ' << "\033[31;1m" << board[i][j] << "\033[0m" << ' ';
  46. }
  47. else
  48. {
  49. cout << ' ' << board[i][j] << ' ';
  50. }
  51. }
  52. cout << endl;
  53. }
  54. }
  55. // 布置雷
  56. void Set_zhadan(char board[MAXSIZE][MAXSIZE], int row, int col,int EASY_COUNT)
  57. {
  58. //生成随机坐标
  59. int count = EASY_COUNT;
  60. int x = 0, y = 0;
  61. while (count)
  62. {
  63. x = rand() % row + 1;
  64. y = rand() % col + 1;
  65. if (board[x][y] == '0')
  66. {
  67. board[x][y] = '#';
  68. count--;
  69. }
  70. }
  71. }
  72. //
  73. int get_num(char mine[MAXSIZE][MAXSIZE], int x, int y)
  74. {
  75. int i = x - 1;//+3
  76. int j = y - 1;//+3
  77. int count = 0;
  78. for (i = x - 1; i < x - 1 + 3; i++)
  79. {
  80. for (j = y - 1; j < y - 1 + 3; j++)
  81. {
  82. if (mine[i][j] == '#')
  83. {
  84. count++;
  85. }
  86. }
  87. }
  88. return count;
  89. }
  90. int Fine_zhadan3(char mine[MAXSIZE][MAXSIZE], char show[MAXSIZE][MAXSIZE], int row, int col, int x, int y,int *win)//它的作用是只能排一次雷。
  91. {
  92. if (x<1 || x>row || y<1 || y>col)
  93. {
  94. return -1;//传入坐标非法(非法原因:数组越界)可以在函数外实现,该处仅用于维护递归,防止递归过度!!!,
  95. }
  96. if (show[x][y] != '*')
  97. {
  98. return 1;//传入坐标非法(非法原因:游戏规则不允许在已经成功排雷的地方继续排雷)
  99. }
  100. if (mine[x][y] != '#')//如果不是雷,就显示周围雷的个数,表示排雷成功!或者显示空格自动递归排雷
  101. {
  102. int num = get_num(mine, x, y);
  103. //排雷数加一
  104. (*win) += 1;
  105. if (num == 0)//如果周围没有雷,那么就要展开一片
  106. {
  107. show[x][y] = ' ';
  108. int i = x - 1;//+3
  109. int j = y - 1;//+3
  110. int count = 0;
  111. for (i = x - 1; i < x - 1 + 3; i++)
  112. {
  113. for (j = y - 1; j < y - 1 + 3; j++)
  114. {
  115. Fine_zhadan3(mine, show, row, col, i, j, win);
  116. }
  117. }
  118. }
  119. else
  120. {
  121. show[x][y] = '0' + num;
  122. return 1;//排雷成功,游戏继续,继续输入坐标
  123. }
  124. //Display_qipan(show, ROWS, COLS);
  125. }
  126. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号