小言_互联网的博客

C语言版扫雷——从0到1实现扫雷小游戏

386人阅读  评论(0)

🐒博客名:平凡的小苏

📚学习格言:有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。

 

 扫雷思维导图

目录

 扫雷思维导图

 前言

 初始化棋盘函数实现:

 打印棋盘函数实现:

布置雷的函数实现:

排查雷函数的实现:

完整源代码:

game1.c

 text.c

game1.h


 

 前言

        相信我们再电脑上都玩过扫雷小游戏,每次排查一个位置时都会显示雷周围的个数,如果周围没有雷则进行展开一片。那么我们如何利用代码来实现扫雷呢?由我细细道来: 

      首先,我们应该实现测试函数,至少进行一次菜单选择,所以用do.......while语句。选择1则进行玩游戏,选择0则退出游戏,输入其他数字则显示输入错误   


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

         然后根据思维导图将需要包含的头文件写在头源文件中,利用宏定义常量是为了以后修改方便,我们这次需要实现的是9*9的扫雷棋盘,当我们将数字改动,就可以实现任意*任意的棋盘


  
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<time.h>//时间戳头文件
  4. #define ROW 9//行
  5. #define COL 9//列
  6. #define ROWS ROW+2
  7. #define COLS COL+2
  8. #define MINE_COUNT 10//雷的个数
  9. void InitBoard(char board[ROWS][COLS], int rows, int cols, char set); //初始化棋盘
  10. void DisplayBoard(char board[ROWS][COLS], int row, int col); //打印棋盘
  11. void Set_mine(char mine[ROWS][COLS], int row, int col); //布置雷
  12. void Fine_mine(char mine [ROWS][COLS],char show[ROWS][COLS], int row, int col); //排查雷

 初始化棋盘函数实现:

因为需要布置雷和排查雷,所以需要初始化两个数组,所以设置了set,需要初始化哪个,就把需要初始化的字符传过去即可。 


  
  1. void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)//初始化棋盘
  2. {
  3. int i = 0;
  4. for (i = 0; i < rows; i++)
  5. {
  6. int j = 0;
  7. for (j = 0; j < cols; j++)
  8. {
  9. board[i][j] = set;
  10. }
  11. }
  12. }

 打印棋盘函数实现:

如果我们初始化好棋盘,我们需要将它打印出来棋盘。或者我们排查一次雷也需要打印棋盘出来给玩家看到。当被炸死也需要打印棋盘给玩家知道在哪里被炸死了


  
  1. void DisplayBoard(char board[ROWS][COLS], int row, int col)//打印棋盘
  2. {
  3. printf( "--------扫雷--------\n");
  4. for ( int j = 0; j <= col; j++)
  5. {
  6. printf( "%d ", j);
  7. }
  8. printf( "\n");
  9. for ( int i = 1; i <= row; i++)
  10. {
  11. printf( "%d ",i);
  12. for ( int j = 1; j <= col; j++)
  13. {
  14. printf( "%c ", board[i][j]);
  15. }
  16. printf( "\n");
  17. }
  18. printf( "--------扫雷--------\n");
  19. }

布置雷的函数实现:

利用生成随机数的库函数来让电脑随机放置雷,并且放置在符合所设置的坐标,如果生成的随机数相同则会重新生成随机数


  
  1. void Set_mine(char mine[ROWS][COLS], int row, int col)//布置雷
  2. {
  3. //布置雷的个数
  4. int count = MINE_COUNT;
  5. while (count)
  6. {
  7. int x = rand() % row + 1;
  8. int y = rand() % col + 1;
  9. if (mine[x][y] == '0')
  10. {
  11. mine[x][y] = '1';
  12. count--;
  13. }
  14. }
  15. }

排查雷函数的实现:

首先需要进行判断输入的坐标是否符合合法性,然后再判断该坐标是否被排查过,在判断是否被炸死,如果该坐标不是雷则继续排查。

排查时进行调用递归展开函数,如果排查的坐标周围没有雷,则进行递归展开。递归展开时要进行边界条件判断,防止数组越界。如果该坐标周围没有雷则进行设置为空格。再判断没有排查过的才进行递归展开排查,防止死递归


  
  1. void Spread(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)//递归展开
  2. {
  3. int n = get_mine_count(mine, x, y);
  4. //边界条件,防止数组越界
  5. if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
  6. {
  7. if (n == 0) //需要展开
  8. {
  9. show[x][y] = ' '; //该点周围没有雷就设置为空格
  10. for ( int i = x - 1; i <= x + 1; i++) {
  11. for ( int j = y - 1; j <= y + 1; j++) {
  12. if (show[i][j] == '*') //为*则为没有排查过的,可以展开,防止死递归
  13. {
  14. Spread(mine, show, i, j);
  15. }
  16. }
  17. }
  18. }
  19. else {
  20. show[x][y] = n + '0'; //字符转为数字
  21. }
  22. }
  23. }
  24. void Fine_mine(char mine [ROWS][COLS],char show[ROWS][COLS], int row, int col)//排查雷
  25. {
  26. int x = 0;
  27. int y = 0;
  28. int win = 0;
  29. while (win<row * col - MINE_COUNT)
  30. {
  31. printf( "请输入要排查的坐标:>");
  32. scanf( "%d %d", &x, &y);
  33. if (x >= 1 && x <= row && y >= 1 && y <= col)
  34. {
  35. if (show[x][y] != '*')
  36. {
  37. printf( "该坐标已经被排查,请重新输入\n");
  38. continue;
  39. }
  40. if (mine[x][y] == '1')
  41. {
  42. printf( "很遗憾,您被炸死了\n");
  43. DisplayBoard(mine, ROW, COL);
  44. break;
  45. }
  46. else
  47. {
  48. Spread(mine, show, x, y);
  49. DisplayBoard(show, ROW, COL);
  50. win++;
  51. }
  52. }
  53. else
  54. {
  55. printf( "坐标非法,请重新输入\n");
  56. }
  57. }
  58. if (win == row * col - MINE_COUNT)
  59. {
  60. printf( "恭喜你,排雷成功\n");
  61. DisplayBoard(mine, ROW, COL);
  62. }
  63. }

完整源代码:

game1.c


  
  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include"game1.h"
  3. void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)//初始化棋盘
  4. {
  5. int i = 0;
  6. for (i = 0; i < rows; i++)
  7. {
  8. int j = 0;
  9. for (j = 0; j < cols; j++)
  10. {
  11. board[i][j] = set;
  12. }
  13. }
  14. }
  15. void DisplayBoard(char board[ROWS][COLS], int row, int col)//打印棋盘
  16. {
  17. printf( "--------扫雷--------\n");
  18. for ( int j = 0; j <= col; j++)
  19. {
  20. printf( "%d ", j);
  21. }
  22. printf( "\n");
  23. for ( int i = 1; i <= row; i++)
  24. {
  25. printf( "%d ",i);
  26. for ( int j = 1; j <= col; j++)
  27. {
  28. printf( "%c ", board[i][j]);
  29. }
  30. printf( "\n");
  31. }
  32. printf( "--------扫雷--------\n");
  33. }
  34. void Set_mine(char mine[ROWS][COLS], int row, int col)//布置雷
  35. {
  36. //布置雷的个数
  37. int count = MINE_COUNT;
  38. while (count)
  39. {
  40. int x = rand() % row + 1;
  41. int y = rand() % col + 1;
  42. if (mine[x][y] == '0')
  43. {
  44. mine[x][y] = '1';
  45. count--;
  46. }
  47. }
  48. }
  49. int get_mine_count(char mine[ROWS][COLS], int x, int y)
  50. {
  51. return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +
  52. mine[x ][y + 1] + mine[x + 1][y + 1] + mine[x + 1 ][y] +
  53. mine[x + 1][y - 1] + mine[x][y - 1] - 8 * '0';
  54. }
  55. void Spread(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)//递归展开
  56. {
  57. int n = get_mine_count(mine, x, y);
  58. //边界条件,防止数组越界
  59. if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
  60. {
  61. if (n == 0) //需要展开
  62. {
  63. show[x][y] = ' '; //该点周围没有雷就设置为空格
  64. for ( int i = x - 1; i <= x + 1; i++) {
  65. for ( int j = y - 1; j <= y + 1; j++) {
  66. if (show[i][j] == '*') //为*则为没有排查过的,可以展开,防止死递归
  67. {
  68. Spread(mine, show, i, j);
  69. }
  70. }
  71. }
  72. }
  73. else {
  74. show[x][y] = n + '0'; //字符转为数字
  75. }
  76. }
  77. }
  78. void Fine_mine(char mine [ROWS][COLS],char show[ROWS][COLS], int row, int col)//排查雷
  79. {
  80. int x = 0;
  81. int y = 0;
  82. int win = 0;
  83. while (win<row * col - MINE_COUNT)
  84. {
  85. printf( "请输入要排查的坐标:>");
  86. scanf( "%d %d", &x, &y);
  87. if (x >= 1 && x <= row && y >= 1 && y <= col)
  88. {
  89. if (show[x][y] != '*')
  90. {
  91. printf( "该坐标已经被排查,请重新输入\n");
  92. continue;
  93. }
  94. if (mine[x][y] == '1')
  95. {
  96. printf( "很遗憾,您被炸死了\n");
  97. DisplayBoard(mine, ROW, COL);
  98. break;
  99. }
  100. else
  101. {
  102. Spread(mine, show, x, y);
  103. DisplayBoard(show, ROW, COL);
  104. win++;
  105. }
  106. }
  107. else
  108. {
  109. printf( "坐标非法,请重新输入\n");
  110. }
  111. }
  112. if (win == row * col - MINE_COUNT)
  113. {
  114. printf( "恭喜你,排雷成功\n");
  115. DisplayBoard(mine, ROW, COL);
  116. }
  117. }

 text.c


  
  1. #include"game1.h"
  2. void game()
  3. {
  4. char mine[ROWS][COLS] = { 0 };
  5. char show[ROWS][COLS] = { 0 };
  6. InitBoard(mine, ROWS, COLS, '0');
  7. InitBoard(show, ROWS, COLS, '*');
  8. DisplayBoard(show, ROW, COL);
  9. Set_mine(mine, ROW, COL);
  10. Fine_mine(mine,show, ROW, COL);
  11. }
  12. void menu()
  13. {
  14. printf( "************************************\n");
  15. printf( "******* 1. play ******\n");
  16. printf( "******* 0. exit ******\n");
  17. printf( "************************************\n");
  18. }
  19. void test()
  20. {
  21. srand(( unsigned int) time( NULL));
  22. int input = 0;
  23. do
  24. {
  25. menu();
  26. printf( "请输入数字:>");
  27. scanf( "%d", &input);
  28. switch (input)
  29. {
  30. case 1:
  31. game();
  32. break;
  33. case 0:
  34. printf( "退出游戏\n");
  35. break;
  36. default:
  37. printf( "输入错误,请重新输入\n");
  38. break;
  39. }
  40. } while (input);
  41. }
  42. int main()
  43. {
  44. test();
  45. return 0;
  46. }

game1.h


  
  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<time.h>
  5. #define ROW 9
  6. #define COL 9
  7. #define ROWS ROW+2
  8. #define COLS COL+2
  9. #define MINE_COUNT 10
  10. void InitBoard(char board[ROWS][COLS], int rows, int cols, char set); //初始化棋盘
  11. void DisplayBoard(char board[ROWS][COLS], int row, int col); //打印棋盘
  12. void Set_mine(char mine[ROWS][COLS], int row, int col); //布置雷
  13. void Fine_mine(char mine [ROWS][COLS],char show[ROWS][COLS], int row, int col); //排查雷


转载:https://blog.csdn.net/VHhhbb/article/details/128515582
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场