• 快进来看看!!!C语言——扫雷小游戏(递归展开无雷区)


    目录

    🐽前言

    🐽一、扫雷游戏规则 

    🐽二、展示效果

    🐽三、 游戏设计思路

    四、代码展示

    🐽一、游戏交互界面

    🐽二、游戏主体

    二、扫雷代码实现

    🐽1.游戏框架搭建

    🐽2.初始化雷盘

    🐽3.打印雷盘

    🐽4.放置雷

    🐽5.遍历获取坐标周围八个雷的个数

    🐽6.遍历打开不是雷的地方

    🐽7.寻找雷

    完整代码

    game.h

    game.c

    test.c


    🐽前言

    说起扫雷,相信大家应该都不陌生吧。windows系统里的小游戏,扫雷有着不可撼动的地位。

    今天我们就用c语言来复刻扫雷小游戏!

    🐽一、扫雷游戏规则 

    玩家需要排查出格子中的雷,点开一个方块后,显示数字,数字是几就表示它周围的八个方块有几个雷。

    比如说这个红色的方框里面就存在一个雷。

    🐽二、展示效果

     

    🐽三、 游戏设计思路

    雷盘相当于一个二维的数组

    一、游戏交互界面

    1. 创建游戏菜单
    2. 创建游戏逻辑主体

    二、扫雷游戏实现

    1. 创建扫雷棋盘
    2. 初始化扫雷棋盘
    3. 布置雷
    4. 打印扫雷棋盘
    5. 用户排查雷
    6. 判断输赢

    1.设计扫雷游戏的时候,二维数组的行数和列数需要比真正想要得到的棋盘多两行和多两列

    为什么呢?

    因为我们排查雷的时候,需要遍历坐标走位八个格子是否有雷,当输入坐标为雷盘边界坐标时,遍历周围的雷就会出现越界的问题!

     2.创建两个雷盘,一个用于显示,一个用于存放地雷

    只创建一个棋盘,那么这一个棋盘上就要放置3种信息。分别为雷、非雷、排查出周围雷的信息。虽然这种方法也没太大的问题,但是一个棋盘上放置3种信息会给之后打印棋盘时造成麻烦,不易打印。
     

     3.使用宏常量

    方便雷盘大小的修改,不会写死程序,提高代码的灵活性。

    四、代码展示

    🐽一、游戏交互界面

    1. void menu()
    2. {
    3. printf("**************************\n");
    4. printf("********1.开始游戏********\n");
    5. printf("********0.退出游戏********\n");
    6. printf("**************************\n");
    7. }

    🐽二、游戏主体

    1. int main()
    2. {
    3. srand((unsigned int)time(NULL));
    4. int intput = 0;
    5. again:
    6. menu();
    7. scanf("%d", &intput);
    8. do
    9. {
    10. switch (intput)
    11. {
    12. case 1:
    13. printf("游戏开始\n");
    14. game();
    15. goto again;
    16. case 0:
    17. printf("退出游戏\n");
    18. break;
    19. default:
    20. printf("输入错误请重新输入\n");
    21. break;
    22. }
    23. } while(intput);
    24. return 0;
    25. }

    二、扫雷代码实现

    🐽1.游戏框架搭建

    1. void game()
    2. {
    3. //设置两个数组,mine数组用来存放设置雷的信息,show数组用来存放排查雷的信息
    4. char mine[ROWS][COLS] = {0};
    5. char show[ROWS][COLS] = {0};
    6. init_board(show,ROWS,COLS,'*');
    7. init_board(mine, ROWS, COLS, '0');
    8. //display_board(mine, ROW, COL);
    9. display_board(show, ROW, COL);
    10. set_mine(mine,ROW,COL);
    11. //display_board(mine, ROW, COL);
    12. find_mine(mine,show,ROW,COL);
    13. }

    🐽2.初始化雷盘

    1. void init_board(char board[][COLS],int rows,int cols,char set)//初始化雷盘,set是需要初始化成什么字符
    2. {
    3. int i = 0;
    4. int j = 0;
    5. for (i = 0; i < rows; i++)
    6. {
    7. for (j = 0; j < cols; j++)
    8. {
    9. board[i][j] = set;
    10. }
    11. }
    12. }

    🐽3.打印雷盘

    1. void display_board(char board[][COLS], int row, int col)
    2. {
    3. printf("---------扫雷游戏-------------\n");
    4. printf(" ");
    5. for (int n = 1; n <= col; n++)
    6. {
    7. printf("%d ",n);
    8. }
    9. printf("\n");
    10. printf("------------------------------\n");
    11. for (int i = 1; i <= row; i++)
    12. {
    13. printf("%d |",i);
    14. for (int j = 1; j <= col; j++)
    15. {
    16. printf("%c ",board[i][j]);
    17. }
    18. printf("|");
    19. printf("\n");
    20. }
    21. printf("-----------------------------\n");
    22. }

    🐽4.放置雷

    1. void set_mine(char board[][COLS], int row, int col)
    2. {
    3. int count = MINENUMS;
    4. while (count)
    5. {
    6. int x = rand() % row + 1;
    7. int y = rand() % col + 1;//设置1~9随机数布置雷
    8. if (board[x][y] != '1')
    9. {
    10. board[x][y] = '1';
    11. count--;
    12. }
    13. }
    14. }

    🐽5.遍历获取坐标周围八个雷的个数

    1. //获取坐标周围的雷数目(八个格子)
    2. int get_minecount(char mine[][COLS], int x, int y)
    3. {
    4. int n = mine[x - 1][y - 1] +
    5. mine[x - 1][y] +
    6. mine[x - 1][y + 1] +
    7. mine[x][y - 1] +
    8. mine[x][y + 1] +
    9. mine[x + 1][y - 1] +
    10. mine[x + 1][y] +
    11. mine[x + 1][y + 1] - 8 * '0';//减去八个字符零是因为八个字符相加,要转换成数字得到和
    12. return n;
    13. }

    🐽6.遍历打开不是雷的地方

    1. void ergodic(char mine[][COLS],char show[][COLS],int x,int y,int *w)//遍历打开不是雷的区域
    2. {
    3. int mine_num = get_minecount(mine, x, y);
    4. if (mine_num == 0)
    5. {
    6. show[x][y] = ' ';//如果这个坐标周围都没有雷的话,显示为空格
    7. (*w)++;
    8. system("cls");
    9. display_board(show, ROW, COL);
    10. /*display_board(mine, ROW, COL);*/
    11. if ((x - 1 >= 1 && x - 1 <= ROW) && (y - 1 >= 1 && y - 1 <= COL) && show[x - 1][y - 1] == '*')
    12. {
    13. ergodic(mine,show,x-1,y-1,w);
    14. }
    15. if ((x - 1 >= 1 && x - 1 <= ROW) && (y >= 1 && y <= COL) && show[x - 1][y] == '*')
    16. {
    17. ergodic(mine, show, x - 1, y,w );
    18. }
    19. if ((x - 1 >= 1 && x - 1 <= ROW) && (y +1>= 1 && y+1 <= COL) && show[x - 1][y+1] == '*')
    20. {
    21. ergodic(mine, show, x - 1, y+1,w);
    22. }
    23. if((x>=1&&x<=ROW)&&(y - 1 >= 1 && y - 1 <= COL) && show[x ][y - 1] == '*')
    24. {
    25. ergodic(mine, show, x , y - 1,w);
    26. }
    27. if ((x >= 1 && x <= ROW) && (y + 1 >= 1 && y + 1 <= COL) && show[x][y + 1] == '*')
    28. {
    29. ergodic(mine, show, x, y + 1,w);
    30. }
    31. if ((x + 1 >= 1 && x + 1 <= ROW) && (y - 1 >= 1 && y - 1 <= COL) && show[x + 1][y - 1] == '*')
    32. {
    33. ergodic(mine, show, x + 1, y - 1,w);
    34. }
    35. if ((x + 1 >= 1 && x + 1 <= ROW) && (y >= 1 && y <= COL) && show[x + 1][y] == '*')
    36. {
    37. ergodic(mine, show, x + 1, y,w);
    38. }
    39. if ((x + 1 >= 1 && x + 1 <= ROW) && (y + 1 >= 1 && y + 1 <= COL) && show[x + 1][y + 1] == '*')
    40. {
    41. ergodic(mine, show, x + 1, y + 1,w);
    42. }
    43. }
    44. else
    45. {
    46. show[x][y] = mine_num + '0';
    47. ///* display_board(mine, ROW, COL);*/
    48. (*w)++;
    49. }
    50. }

    🐽7.寻找雷

    1. void find_mine(char mine[][COLS],char show[][COLS],int row,int col)//寻找雷
    2. {
    3. int x = 0;
    4. int y = 0;
    5. int win = 0;
    6. int* w = &win;
    7. while (win < (row * col - MINENUMS))//判断是否已经排查完毕,win相当于一个计数器
    8. {
    9. printf("请输入需要排雷的坐标: ");
    10. scanf("%d %d", &x, &y);
    11. if (x >= 1 && x <= row && y >= 1 && y <= col)
    12. {
    13. if (show[x][y] == '*')
    14. {
    15. if (mine[x][y] == '1')
    16. {
    17. printf("你被炸死了!\n");
    18. display_board(show,row,col);
    19. break;
    20. }
    21. else
    22. {
    23. /* int count = get_minecount(mine,x,y);
    24. show[x][y] = count + '0';*/
    25. ergodic(mine,show,x,y,w);
    26. system("cls");
    27. display_board(show, ROW, COL);
    28. /*display_board(mine, ROW, COL);*/
    29. /*win++;*/
    30. }
    31. }
    32. else
    33. {
    34. printf("坐标已经被排查过啦!\n");
    35. }
    36. }
    37. else
    38. {
    39. printf("输入的坐标有误!\n");
    40. }
    41. }
    42. if (win == row * col - MINENUMS)
    43. {
    44. printf("恭喜你,排雷成功!\n\n\n\n");
    45. display_board(show, ROW, COL);
    46. }
    47. }

    这里的win相当于计数器,排一个格子,win就加一,作为判断输赢的条件

    完整代码

    game.h

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #define ROW 9
    8. #define COL 9//雷盘大小
    9. #define ROWS ROW+2
    10. #define COLS COL+2
    11. #define MINENUMS 10//布置雷数
    12. void game();
    13. void init_board(char board[][COLS], int rows, int cols, char set);
    14. void display_board(char board[][COLS], int row, int col);
    15. void set_mine(char board[][COLS], int row, int col);
    16. void find_mine(char mine[][COLS], char show[][COLS], int row, int col);

    game.c

    1. #include"game.h"
    2. void game()
    3. {
    4. //设置两个数组,mine数组用来存放设置雷的信息,show数组用来存放排查雷的信息
    5. char mine[ROWS][COLS] = {0};
    6. char show[ROWS][COLS] = {0};
    7. init_board(show,ROWS,COLS,'*');
    8. init_board(mine, ROWS, COLS, '0');
    9. //display_board(mine, ROW, COL);
    10. display_board(show, ROW, COL);
    11. set_mine(mine,ROW,COL);
    12. //display_board(mine, ROW, COL);
    13. find_mine(mine,show,ROW,COL);
    14. }
    15. void init_board(char board[][COLS],int rows,int cols,char set)//初始化雷盘,set是需要初始化成什么字符
    16. {
    17. int i = 0;
    18. int j = 0;
    19. for (i = 0; i < rows; i++)
    20. {
    21. for (j = 0; j < cols; j++)
    22. {
    23. board[i][j] = set;
    24. }
    25. }
    26. }
    27. //打印雷盘,制作的是9x9的雷盘
    28. //把雷盘看成一个二维数组打印,为了防止数组越界,我们数组的行和列分别要比想要棋盘的行和列多2
    29. void display_board(char board[][COLS], int row, int col)
    30. {
    31. printf("---------扫雷游戏-------------\n");
    32. printf(" ");
    33. for (int n = 1; n <= col; n++)
    34. {
    35. printf("%d ",n);
    36. }
    37. printf("\n");
    38. printf("------------------------------\n");
    39. for (int i = 1; i <= row; i++)
    40. {
    41. printf("%d |",i);
    42. for (int j = 1; j <= col; j++)
    43. {
    44. printf("%c ",board[i][j]);
    45. }
    46. printf("|");
    47. printf("\n");
    48. }
    49. printf("-----------------------------\n");
    50. }
    51. void set_mine(char board[][COLS], int row, int col)
    52. {
    53. int count = MINENUMS;
    54. while (count)
    55. {
    56. int x = rand() % row + 1;
    57. int y = rand() % col + 1;//设置1~9随机数布置雷
    58. if (board[x][y] != '1')
    59. {
    60. board[x][y] = '1';
    61. count--;
    62. }
    63. }
    64. }
    65. //获取坐标周围的雷数目(八个格子)
    66. int get_minecount(char mine[][COLS], int x, int y)
    67. {
    68. int n = mine[x - 1][y - 1] +
    69. mine[x - 1][y] +
    70. mine[x - 1][y + 1] +
    71. mine[x][y - 1] +
    72. mine[x][y + 1] +
    73. mine[x + 1][y - 1] +
    74. mine[x + 1][y] +
    75. mine[x + 1][y + 1] - 8 * '0';//减去八个字符零是因为八个字符相加,要转换成数字得到和
    76. return n;
    77. }
    78. void ergodic(char mine[][COLS],char show[][COLS],int x,int y,int *w)//遍历打开不是雷的区域
    79. {
    80. int mine_num = get_minecount(mine, x, y);
    81. if (mine_num == 0)
    82. {
    83. show[x][y] = ' ';//如果这个坐标周围都没有雷的话,显示为空格
    84. (*w)++;
    85. system("cls");
    86. display_board(show, ROW, COL);
    87. /*display_board(mine, ROW, COL);*/
    88. if ((x - 1 >= 1 && x - 1 <= ROW) && (y - 1 >= 1 && y - 1 <= COL) && show[x - 1][y - 1] == '*')
    89. {
    90. ergodic(mine,show,x-1,y-1,w);
    91. }
    92. if ((x - 1 >= 1 && x - 1 <= ROW) && (y >= 1 && y <= COL) && show[x - 1][y] == '*')
    93. {
    94. ergodic(mine, show, x - 1, y,w );
    95. }
    96. if ((x - 1 >= 1 && x - 1 <= ROW) && (y +1>= 1 && y+1 <= COL) && show[x - 1][y+1] == '*')
    97. {
    98. ergodic(mine, show, x - 1, y+1,w);
    99. }
    100. if((x>=1&&x<=ROW)&&(y - 1 >= 1 && y - 1 <= COL) && show[x ][y - 1] == '*')
    101. {
    102. ergodic(mine, show, x , y - 1,w);
    103. }
    104. if ((x >= 1 && x <= ROW) && (y + 1 >= 1 && y + 1 <= COL) && show[x][y + 1] == '*')
    105. {
    106. ergodic(mine, show, x, y + 1,w);
    107. }
    108. if ((x + 1 >= 1 && x + 1 <= ROW) && (y - 1 >= 1 && y - 1 <= COL) && show[x + 1][y - 1] == '*')
    109. {
    110. ergodic(mine, show, x + 1, y - 1,w);
    111. }
    112. if ((x + 1 >= 1 && x + 1 <= ROW) && (y >= 1 && y <= COL) && show[x + 1][y] == '*')
    113. {
    114. ergodic(mine, show, x + 1, y,w);
    115. }
    116. if ((x + 1 >= 1 && x + 1 <= ROW) && (y + 1 >= 1 && y + 1 <= COL) && show[x + 1][y + 1] == '*')
    117. {
    118. ergodic(mine, show, x + 1, y + 1,w);
    119. }
    120. }
    121. else
    122. {
    123. show[x][y] = mine_num + '0';
    124. ///* display_board(mine, ROW, COL);*/
    125. (*w)++;
    126. }
    127. }
    128. void find_mine(char mine[][COLS],char show[][COLS],int row,int col)//寻找雷
    129. {
    130. int x = 0;
    131. int y = 0;
    132. int win = 0;
    133. int* w = &win;
    134. while (win < (row * col - MINENUMS))//判断是否已经排查完毕,win相当于一个计数器
    135. {
    136. printf("请输入需要排雷的坐标: ");
    137. scanf("%d %d", &x, &y);
    138. if (x >= 1 && x <= row && y >= 1 && y <= col)
    139. {
    140. if (show[x][y] == '*')
    141. {
    142. if (mine[x][y] == '1')
    143. {
    144. printf("你被炸死了!\n");
    145. display_board(show,row,col);
    146. break;
    147. }
    148. else
    149. {
    150. /* int count = get_minecount(mine,x,y);
    151. show[x][y] = count + '0';*/
    152. ergodic(mine,show,x,y,w);
    153. system("cls");
    154. display_board(show, ROW, COL);
    155. /*display_board(mine, ROW, COL);*/
    156. /*win++;*/
    157. }
    158. }
    159. else
    160. {
    161. printf("坐标已经被排查过啦!\n");
    162. }
    163. }
    164. else
    165. {
    166. printf("输入的坐标有误!\n");
    167. }
    168. }
    169. if (win == row * col - MINENUMS)
    170. {
    171. printf("恭喜你,排雷成功!\n\n\n\n");
    172. display_board(show, ROW, COL);
    173. }
    174. }

    test.c

    1. #include"game.h"
    2. void menu()
    3. {
    4. printf("**************************\n");
    5. printf("********1.开始游戏********\n");
    6. printf("********0.退出游戏********\n");
    7. printf("**************************\n");
    8. }
    9. int main()
    10. {
    11. srand((unsigned int)time(NULL));
    12. int intput = 0;
    13. again:
    14. menu();
    15. scanf("%d", &intput);
    16. do
    17. {
    18. switch (intput)
    19. {
    20. case 1:
    21. printf("游戏开始\n");
    22. game();
    23. goto again;
    24. case 0:
    25. printf("退出游戏\n");
    26. break;
    27. default:
    28. printf("输入错误请重新输入\n");
    29. break;
    30. }
    31. } while(intput);
    32. return 0;
    33. }

    制作不易,给博主一键3连吧!蟹蟹!!!

    制作不易,给博主一键3连吧!蟹蟹!!!

    制作不易,给博主一键3连吧!蟹蟹!!!

  • 相关阅读:
    Java之JDBC
    JMM(Java Memory Model)
    一个用Python将视频变为表情包的工具
    C#连接TaoS数据库错误:dotnet版本不匹配的问题
    【WAX链游】发布一个免费开源的MiningNetwork合约脚本BTK
    概率论的学习和整理8: 几何分布和超几何分布
    什么是神经元网络控制?,神经网络控制的应用
    Linux第七章
    大数据学习——linux操作系统(Centos)安装mysql(Hive的元数据库)
    Ubuntu安装redis详细教程
  • 原文地址:https://blog.csdn.net/weixin_61638178/article/details/126697164