• C语言——扫雷游戏


            本篇文章主要为大家介绍C语言如何实现扫雷游戏,感兴趣的小伙伴们可以参考一下 

    一、问题的描述

            雷区中随机布置一定数量的地雷,玩家需要尽快找出所有不是地雷的方块,但不许踩到地雷。玩家标记所有地雷后,选择排雷结束,然后游戏判断玩家是否完成扫雷。

     二、游戏设计的基本流程

    1、创建游戏菜单。
    2、创建和初始化雷区。
    3、打印排雷雷区。
    4、玩家选择相关操作,并输入坐标。

    5、玩家选择排雷完成。

    6、判断扫雷是否完成。

    三、程序的具体实现

    1. 菜单界面

    用户选择 1 开始游戏, 选择 0 退出游戏。

    1. void menu() {
    2. printf("*************************\n");
    3. printf("****** 1. play *****\n");
    4. printf("****** 0. exit *****\n");
    5. printf("*************************\n\n");
    6. }
    7. void test() {
    8. int input = 0;
    9. srand((unsigned int)time(NULL));
    10. menu();
    11. do
    12. {
    13. printf("请输入你的选择:");
    14. scanf("%d", &input);
    15. switch (input)
    16. {
    17. case 1:
    18. system("cls");
    19. game();
    20. menu();
    21. break;
    22. case 0:
    23. break;
    24. default:
    25. printf("您的输入有误,请重新输入");
    26. Sleep(200);
    27. system("cls");
    28. menu();
    29. break;
    30. }
    31. } while (input);
    32. system("cls");
    33. printf("欢迎下次使用!!!\n\n");
    34. Sleep(300);
    35. }
    36. int main() {
    37. test();
    38. return 0;
    39. }

    2. 创建雷区

    要进行游戏,我们首先要创建一个雷区。
    雷区:使用11行11列的二维数组来表示,元素类型是char。

    使用宏定义:
    1.推高代码可读性。
    2.提高扩展性,便于修改雷区尺寸和地雷数量。

    1. #ifndef __HEAD_H__
    2. #define __HEAD_H__
    3. #define _CRT_SECURE_NO_WARNINGS 1
    4. #include
    5. #include
    6. #include
    7. #include
    8. #define ROW 9
    9. #define COL 9
    10. #define ROWS ROW+2
    11. #define COLS COL+2
    12. #define EASY_COUNT 10
    13. #endif
    1. // 1. 布置好的雷的信息
    2. char mine[ROWS][COLS] = { 0 };
    3. // 2. 排查雷的信息
    4. char show[ROWS][COLS] = { 0 };

    3. 初始化雷区

    用 * 来初始化排雷区,隐藏雷区上面的地雷。

    用 1 来初始化雷的位置,设置雷区的地雷。

    1. void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) {
    2. for (int i = 0; i < rows; i++) {
    3. for (int j = 0; j < cols; j++) {
    4. board[i][j] = set;
    5. }
    6. }
    7. }

    4. 随机布雷

    电脑随机设置地雷:

    1.使用 随机数种子 srand((unsigned int)time(NULL))。
    2.要在雷区空的地方布雷。

    1. void SetMine(char board[ROWS][COLS], int row, int col) {
    2. int count = EASY_COUNT;
    3. while (count)
    4. {
    5. int x = rand() % row + 1;
    6. int y = rand() % col + 1;
    7. if (board[x][y] == '0') {
    8. board[x][y] = '1';
    9. count--;
    10. }
    11. }
    12. }

    5. 打印雷区

    用户在玩游戏的时候,要看到雷区。

    1. void DisplayBoard(char board[ROWS][COLS], int row, int col) {
    2. for (int i = 0; i <= row; i++) {
    3. printf(" %d ",i);
    4. if(i < row)
    5. printf("|");
    6. }
    7. printf("\n");
    8. for (int i = 0; i <= row; i++) {
    9. printf("---");
    10. if (i < row)
    11. printf("|");
    12. }
    13. printf("\n");
    14. for (int i = 1; i <= row; i++) {
    15. printf(" %d |", i);
    16. for(int j = 1; j <= col; j++) {
    17. printf(" %c ", board[i][j]);
    18. if (j < col) {
    19. printf("|");
    20. }
    21. }
    22. printf("\n");
    23. if (i < row) {
    24. for (int j = 0; j <= row; j++) {
    25. printf("---");
    26. if (j < row)
    27. printf("|");
    28. }
    29. printf("\n");
    30. }
    31. }
    32. printf("\n");
    33. }

    6. 玩家排雷

    1. void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
    2. int x = 0;
    3. int y = 0;
    4. int ck = 0;
    5. char ch = ' ';
    6. while (1) {
    7. DisplayBoard(show, ROW, COL);
    8. printf("-----------------------\n");
    9. printf("--> p. 排雷 \n");
    10. printf("--> b. 标记 \n");
    11. printf("--> e. 标记完成 \n");
    12. printf("-----------------------\n\n");
    13. Flag:
    14. printf("请输入您的操作: ");
    15. getchar();
    16. scanf("%c", &ch);
    17. switch (ch)
    18. {
    19. case 'p':
    20. { P_1:
    21. printf("请输入坐标: ");
    22. scanf("%d", &x);
    23. scanf("%d", &y);
    24. if (x <= row && x >= 1 && y <= col && y >= 1) {
    25. if (mine[x][y] == '1') // 踩雷
    26. {
    27. system("cls");
    28. printf("\nT_T T_T T_T T_T T_T T_T\n");
    29. printf("很遗憾,你被炸死了!!!\n");
    30. printf("T_T T_T T_T T_T T_T T_T\n\n");
    31. DisplayBoard(mine, ROW, COL);
    32. printf("\n\n按任意键结束!\n\n");
    33. getchar();
    34. getchar();
    35. system("cls");
    36. goto End;
    37. }
    38. else // 不是雷
    39. {
    40. // 计算x,y 周围有几个雷?
    41. get_mine_count(mine, show, x, y);
    42. //DisplayBoard(show, ROW, COL);
    43. system("cls");
    44. }
    45. }
    46. else
    47. {
    48. printf("您输入坐标有误, 请重新输入^_^\n");
    49. goto P_1;
    50. }
    51. }
    52. break;
    53. case 'b':
    54. { B_1:
    55. printf("请输入坐标: ");
    56. scanf("%d", &x);
    57. scanf("%d", &y);
    58. if (x <= row && x >= 1 && y <= col && y >= 1) {
    59. MarkMine(mine, show, x, y);
    60. system("cls");
    61. }
    62. else
    63. {
    64. printf("您输入坐标有误, 请重新输入^_^\n");
    65. goto B_1;
    66. }
    67. }
    68. break;
    69. case 'e':
    70. // 检查玩家的扫雷状态
    71. ck = judge(mine, show);
    72. if (ck == 1) {
    73. system("cls");
    74. printf("^_^^_^^_^^_^^_^^_^^_^^_^\n");
    75. printf("恭喜你,扫雷完成!!!\n");
    76. printf("^_^^_^^_^^_^^_^^_^^_^^_^\n");
    77. printf("\n\n按任意键结束!\n\n");
    78. getchar();
    79. getchar();
    80. system("cls");
    81. goto End;
    82. }
    83. else
    84. {
    85. system("cls");
    86. printf("\nT_T T_T T_T T_T T_T T_T\n");
    87. printf("很遗憾,扫雷失败!!!\n");
    88. printf("T_T T_T T_T T_T T_T T_T\n\n\n");
    89. DisplayBoard(mine, ROW, COL);
    90. printf("\n\n按任意键结束!\n\n");
    91. getchar();
    92. getchar();
    93. system("cls");
    94. goto End;
    95. }
    96. break;
    97. default:
    98. printf("您输入操作有误, 请重新输入^_^\n");
    99. goto Flag;
    100. break;
    101. }
    102. }
    103. End:
    104. ;
    105. }

    7. 查看周围地雷数量

    1. // 展开功能的实现,递归
    2. int get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
    3. {
    4. if (x <= ROW && x >= 1 && y <= COL && y >= 1)
    5. {
    6. if (show[x][y] == ' ')
    7. {
    8. return 0;
    9. }
    10. int n = mine[x - 1][y] +
    11. mine[x - 1][y - 1] +
    12. mine[x - 1][y + 1] +
    13. mine[x][y - 1] +
    14. mine[x][y + 1] +
    15. mine[x + 1][y] +
    16. mine[x + 1][y - 1] +
    17. mine[x + 1][y + 1] - 8 * '0';
    18. if (n == 0) {
    19. show[x][y] = ' ';
    20. get_mine_count(mine, show, x - 1, y);
    21. get_mine_count(mine, show, x-1, y-1);
    22. get_mine_count(mine, show, x-1, y+1);
    23. get_mine_count(mine, show, x, y-1);
    24. get_mine_count(mine, show, x, y+1);
    25. get_mine_count(mine, show, x+1, y);
    26. get_mine_count(mine, show, x+1, y-1);
    27. get_mine_count(mine, show, x+1, y+1);
    28. }
    29. else
    30. {
    31. show[x][y] = '0' + n;
    32. return 0;
    33. }
    34. }
    35. return 0;
    36. }

    8. 标记地雷

    1. int MarkMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) {
    2. if (show[x][y] == '$') {
    3. show[x][y] = '*';
    4. }
    5. else
    6. {
    7. show[x][y] = '$';
    8. }
    9. return 0;
    10. }

    9. 判断成败

    1. int judge(char mine[ROWS][COLS], char show[ROWS][COLS]) {
    2. int count = 0;
    3. for (int i = 1; i <= ROW; i++) {
    4. for (int j = 1; j <= COL; j++) {
    5. if (show[i][j] == '$') {
    6. if (mine[i][j] == '1') {
    7. count++;
    8. }
    9. }
    10. }
    11. }
    12. if (count == EASY_COUNT) {
    13. return 1;
    14. }
    15. return 0;
    16. }

    四、完整代码

    1. head.h

    1. #ifndef __HEAD_H__
    2. #define __HEAD_H__
    3. #define _CRT_SECURE_NO_WARNINGS 1
    4. #include
    5. #include
    6. #include
    7. #include
    8. #define ROW 9
    9. #define COL 9
    10. #define ROWS ROW+2
    11. #define COLS COL+2
    12. #define EASY_COUNT 10
    13. void game();
    14. void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
    15. void DisplayBoard(char board[ROWS][COLS], int row, int col);
    16. void SetMine(char board[ROWS][COLS], int row, int col);
    17. void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
    18. int get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
    19. int MarkMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
    20. int judge(char mine[ROWS][COLS], char show[ROWS][COLS]);
    21. #endif // !__HEAD_H__

    2. game.c

    1. #include"head.h"
    2. void game() {
    3. // 雷的信息存储
    4. // 1. 布置好的雷的信息
    5. char mine[ROWS][COLS] = { 0 };
    6. // 2. 排查雷的信息
    7. char show[ROWS][COLS] = { 0 };
    8. // 初始化
    9. InitBoard(mine, ROWS, COLS, '0');
    10. InitBoard(show, ROWS, COLS, '*');
    11. // 打印棋盘
    12. //DisplayBoard(mine, ROW, COL);
    13. // 布置雷
    14. SetMine(mine, ROW, COL);
    15. //DisplayBoard(mine, ROW, COL);
    16. // 扫雷
    17. FindMine(mine,show,ROW,COL);
    18. }
    19. void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) {
    20. for (int i = 0; i < rows; i++) {
    21. for (int j = 0; j < cols; j++) {
    22. board[i][j] = set;
    23. }
    24. }
    25. }
    26. void DisplayBoard(char board[ROWS][COLS], int row, int col) {
    27. for (int i = 0; i <= row; i++) {
    28. printf(" %d ",i);
    29. if(i < row)
    30. printf("|");
    31. }
    32. printf("\n");
    33. for (int i = 0; i <= row; i++) {
    34. printf("---");
    35. if (i < row)
    36. printf("|");
    37. }
    38. printf("\n");
    39. for (int i = 1; i <= row; i++) {
    40. printf(" %d |", i);
    41. for(int j = 1; j <= col; j++) {
    42. printf(" %c ", board[i][j]);
    43. if (j < col) {
    44. printf("|");
    45. }
    46. }
    47. printf("\n");
    48. if (i < row) {
    49. for (int j = 0; j <= row; j++) {
    50. printf("---");
    51. if (j < row)
    52. printf("|");
    53. }
    54. printf("\n");
    55. }
    56. }
    57. printf("\n");
    58. }
    59. void SetMine(char board[ROWS][COLS], int row, int col) {
    60. int count = EASY_COUNT;
    61. while (count)
    62. {
    63. int x = rand() % row + 1;
    64. int y = rand() % col + 1;
    65. if (board[x][y] == '0') {
    66. board[x][y] = '1';
    67. count--;
    68. }
    69. }
    70. }
    71. void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
    72. int x = 0;
    73. int y = 0;
    74. int ck = 0;
    75. char ch = ' ';
    76. while (1) {
    77. DisplayBoard(show, ROW, COL);
    78. printf("-----------------------\n");
    79. printf("--> p. 排雷 \n");
    80. printf("--> b. 标记 \n");
    81. printf("--> e. 标记完成 \n");
    82. printf("-----------------------\n\n");
    83. Flag:
    84. printf("请输入您的操作: ");
    85. getchar();
    86. scanf("%c", &ch);
    87. switch (ch)
    88. {
    89. case 'p':
    90. { P_1:
    91. printf("请输入坐标: ");
    92. scanf("%d", &x);
    93. scanf("%d", &y);
    94. if (x <= row && x >= 1 && y <= col && y >= 1) {
    95. if (mine[x][y] == '1') // 踩雷
    96. {
    97. system("cls");
    98. printf("\nT_T T_T T_T T_T T_T T_T\n");
    99. printf("很遗憾,你被炸死了!!!\n");
    100. printf("T_T T_T T_T T_T T_T T_T\n\n");
    101. DisplayBoard(mine, ROW, COL);
    102. printf("\n\n按任意键结束!\n\n");
    103. getchar();
    104. getchar();
    105. system("cls");
    106. goto End;
    107. }
    108. else // 不是雷
    109. {
    110. // 计算x,y 周围有几个雷?
    111. get_mine_count(mine, show, x, y);
    112. //DisplayBoard(show, ROW, COL);
    113. system("cls");
    114. }
    115. }
    116. else
    117. {
    118. printf("您输入坐标有误, 请重新输入^_^\n");
    119. goto P_1;
    120. }
    121. }
    122. break;
    123. case 'b':
    124. { B_1:
    125. printf("请输入坐标: ");
    126. scanf("%d", &x);
    127. scanf("%d", &y);
    128. if (x <= row && x >= 1 && y <= col && y >= 1) {
    129. MarkMine(mine, show, x, y);
    130. system("cls");
    131. }
    132. else
    133. {
    134. printf("您输入坐标有误, 请重新输入^_^\n");
    135. goto B_1;
    136. }
    137. }
    138. break;
    139. case 'e':
    140. // 检查玩家的扫雷状态
    141. ck = judge(mine, show);
    142. if (ck == 1) {
    143. system("cls");
    144. printf("^_^^_^^_^^_^^_^^_^^_^^_^\n");
    145. printf("恭喜你,扫雷完成!!!\n");
    146. printf("^_^^_^^_^^_^^_^^_^^_^^_^\n");
    147. printf("\n\n按任意键结束!\n\n");
    148. getchar();
    149. getchar();
    150. system("cls");
    151. goto End;
    152. }
    153. else
    154. {
    155. system("cls");
    156. printf("\nT_T T_T T_T T_T T_T T_T\n");
    157. printf("很遗憾,扫雷失败!!!\n");
    158. printf("T_T T_T T_T T_T T_T T_T\n\n\n");
    159. DisplayBoard(mine, ROW, COL);
    160. printf("\n\n按任意键结束!\n\n");
    161. getchar();
    162. getchar();
    163. system("cls");
    164. goto End;
    165. }
    166. break;
    167. default:
    168. printf("您输入操作有误, 请重新输入^_^\n");
    169. goto Flag;
    170. break;
    171. }
    172. }
    173. End:
    174. ;
    175. }
    176. // 展开功能的实现,递归
    177. int get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
    178. {
    179. if (x <= ROW && x >= 1 && y <= COL && y >= 1)
    180. {
    181. if (show[x][y] == ' ')
    182. {
    183. return 0;
    184. }
    185. int n = mine[x - 1][y] +
    186. mine[x - 1][y - 1] +
    187. mine[x - 1][y + 1] +
    188. mine[x][y - 1] +
    189. mine[x][y + 1] +
    190. mine[x + 1][y] +
    191. mine[x + 1][y - 1] +
    192. mine[x + 1][y + 1] - 8 * '0';
    193. if (n == 0) {
    194. show[x][y] = ' ';
    195. get_mine_count(mine, show, x - 1, y);
    196. get_mine_count(mine, show, x-1, y-1);
    197. get_mine_count(mine, show, x-1, y+1);
    198. get_mine_count(mine, show, x, y-1);
    199. get_mine_count(mine, show, x, y+1);
    200. get_mine_count(mine, show, x+1, y);
    201. get_mine_count(mine, show, x+1, y-1);
    202. get_mine_count(mine, show, x+1, y+1);
    203. }
    204. else
    205. {
    206. show[x][y] = '0' + n;
    207. return 0;
    208. }
    209. }
    210. return 0;
    211. }
    212. int MarkMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) {
    213. if (show[x][y] == '$') {
    214. show[x][y] = '*';
    215. }
    216. else
    217. {
    218. show[x][y] = '$';
    219. }
    220. return 0;
    221. }
    222. int judge(char mine[ROWS][COLS], char show[ROWS][COLS]) {
    223. int count = 0;
    224. for (int i = 1; i <= ROW; i++) {
    225. for (int j = 1; j <= COL; j++) {
    226. if (show[i][j] == '$') {
    227. if (mine[i][j] == '1') {
    228. count++;
    229. }
    230. }
    231. }
    232. }
    233. if (count == EASY_COUNT) {
    234. return 1;
    235. }
    236. return 0;
    237. }

    3. main.c

    1. #include "head.h"
    2. void menu() {
    3. printf("*************************\n");
    4. printf("****** 1. play *****\n");
    5. printf("****** 0. exit *****\n");
    6. printf("*************************\n\n");
    7. }
    8. void test() {
    9. int input = 0;
    10. srand((unsigned int)time(NULL));
    11. menu();
    12. do
    13. {
    14. printf("请输入你的选择:");
    15. scanf("%d", &input);
    16. switch (input)
    17. {
    18. case 1:
    19. system("cls");
    20. game();
    21. menu();
    22. break;
    23. case 0:
    24. break;
    25. default:
    26. printf("您的输入有误,请重新输入");
    27. Sleep(200);
    28. system("cls");
    29. menu();
    30. break;
    31. }
    32. } while (input);
    33. system("cls");
    34. printf("欢迎下次使用!!!\n\n");
    35. Sleep(300);
    36. }
    37. int main() {
    38. test();
    39. return 0;
    40. }

    五、游戏演示

    1. 菜单界面

    2. 游戏界面

    3. 完成界面

     

     

  • 相关阅读:
    网络安全“三保一评”深度解析
    rust vscode Fetching: metadata 一直
    grpc、https、oauth2等认证专栏实战13:oauth2认证方式之客户端凭证式介绍
    数据分析---主要工作
    大数据在金融行业的深度应用与未来展望
    Springboot+Rabbitmq消费者注解详解、改序列化方式
    【学习笔记】各类基于决策单调性的dp优化
    生鲜配送公司面临的几大痛点,你知道多少?
    Ubuntu上安装MySQL
    数据结构与算法 | 二叉树(Binary Tree)
  • 原文地址:https://blog.csdn.net/qq_53436105/article/details/125886220