• C语言实现小游戏之扫雷


    目录

    前言

    一、主要实现功能

    二、程序流程(思路)

    主程序流程

    游戏部分流程

    三、源代码及运行截图

    源代码

    运行截图:

    总结

    前言

    相信大家都曾玩过一个经典的小游戏——扫雷,在学习了C语言有关于数组、循环语句、选择语句等知识后,我决定用C语言实现一个简易版的扫雷游戏,接下来我将在本篇文章中向大家介绍我的思路以及具体的实现过程。

    5144f6afe1964e0f8c6e3843ef9c6995.gif

    一、主要实现功能

    1.可控制棋盘的大小和雷的数量;

    2.判断输入的坐标是否正确;

    3.可以在棋盘中随机放置雷;

    4.显示非雷坐标周围雷的个数;

    5.展开功能(若所排查坐标周围没有雷,则展开一片,直到遇到雷或者棋盘边界等条件)

    6.判断游戏的输赢

    二、程序流程(思路)

    玩家输入坐标,系统判断是否为雷:

    如果是雷,则玩家被炸死,游戏结束;

    如果不是雷,又分为两种情况:

    该位置周围有雷,则显示周围雷的数量;

    该位置周围没有雷,则展开一片。

    如果所有非雷位置被玩家全部找到,则玩家胜利,游戏结束。

    主程序流程

    4a2bdcdae0954e9a8a030c510f080b06.png

    游戏部分流程

    5e5fcab5d7f44e2598619c2b2209e98f.png

    三、源代码及运行截图

    为了方便大家的学习和交流,我将这个小游戏的源代码放置在下方,同时还有我的运行截图。

    源代码

     初始化棋盘

    1. //初始化布置雷的棋盘和展示给玩家的棋盘
    2. void init_mine()
    3. {
    4. int i = 0;
    5. int j = 0;
    6. for (i = 0; i < ROW; i++)
    7. {
    8. for (j = 0; j < COL; j++)
    9. {
    10. real_mine[i][j] = '0';
    11. }
    12. }
    13. for (i = 0; i < ROW - 2; i++)
    14. {
    15. for (j = 0; j < COL - 2; j++)
    16. {
    17. show_mine[i][j] = '*';
    18. }
    19. }

     放置雷

    1. //放置雷
    2. void set_mine()
    3. {
    4. int row = 0;
    5. int col = 0;
    6. int mine = MINE;
    7. while (mine--)
    8. {
    9. row = (rand() % (ROW - 2)+1);//产生随机的行数
    10. col = (rand() % (COL - 2)+1);//产生随机的列数
    11. if (real_mine[row][col] != '1')
    12. {
    13. real_mine[row][col] = '1';
    14. }
    15. else
    16. {
    17. mine++;
    18. }
    19. }
    20. }

     打印放置雷的棋盘

    1. //打印放置雷的棋盘
    2. void print_mine()
    3. {
    4. int i = 0;
    5. int j = 0;
    6. for (i = 0; i < ROW; i++)
    7. {
    8. for (j = 0; j < COL; j++)
    9. {
    10. printf("%c ", real_mine[i][j]);
    11. }
    12. printf("\n");
    13. }
    14. }

     打印展示给玩家的棋盘

    1. //打印展示给玩家的棋盘
    2. void print_show()
    3. {
    4. int i = 0;
    5. int j = 0;
    6. printf("%2d ",0);
    7. for (j = 0; j < COL - 2; j++)
    8. {
    9. printf("%d ", j+1);
    10. }
    11. printf("\n");
    12. for (i = 0; i < ROW - 2; i++)
    13. {
    14. printf("%2d ", i+1);
    15. for (j = 0; j < COL - 2; j++)
    16. {
    17. printf("%c ", show_mine[i][j]);
    18. }
    19. printf("\n");
    20. }
    21. }

     统计周围雷的个数

    1. //统计周围雷的个数
    2. int count_mine(int n,int m)
    3. {
    4. int i = 0;
    5. int j = 0;
    6. int count = 0;
    7. for (i = n - 1; i <= n + 1; i++)
    8. {
    9. for (j = m - 1; j <= m + 1; j++)
    10. {
    11. if (real_mine[i][j] == '1')
    12. {
    13. count++;
    14. }
    15. }
    16. }
    17. return count;
    18. }

     判断输入的坐标是否已经被查询过

    1. //判断输入的坐标是否已经被查询过
    2. int has_queried(int n, int m)
    3. {
    4. if (show_mine[n - 1][m - 1] != '*')
    5. {
    6. return 0;
    7. }
    8. else
    9. {
    10. return 1;
    11. }
    12. }

     展开一片(展开该坐标周围的坐标,一直到限制条件)

    1. //展开一片(展开该坐标周围的坐标,一直到限制条件)
    2. void open_mine(int n, int m)
    3. {
    4. int i = 0;
    5. int j = 0;
    6. //结束标志:
    7. //1.坐标是雷
    8. //2.坐标越界
    9. //3.坐标已被查找
    10. if (n <= (ROW - 2) && n >= 1 && m <= (ROW - 2) && m >= 1 && show_mine[n - 1][m - 1] == '*' && real_mine[n][m] == '0')
    11. {
    12. real_mine[n][m] = '2';//将查找过的坐标进行标记
    13. if (!count_mine(n, m))
    14. {
    15. show_mine[n - 1][m - 1] = ' ';//把周围没有雷的坐标显示为空白
    16. for (i = n - 1; i <= n + 1; i++)
    17. {
    18. for (j = m - 1; j <= m + 1; j++)
    19. {
    20. open_mine(i, j);
    21. }
    22. }
    23. }
    24. else
    25. {
    26. show_mine[n - 1][m - 1] = count_mine(n, m) + '0';//加0x30或者加‘0’都可以将数值转为字符
    27. }
    28. }
    29. }

     扫雷函数

    1. //扫雷函数
    2. int sweep_mine(int n, int m)
    3. {
    4. if (real_mine[n][m] == '1')//踩到雷
    5. {
    6. return 0;
    7. }
    8. else
    9. {
    10. int count = count_mine(n, m);//没踩到,统计周围雷的个数
    11. if (count)
    12. {
    13. show_mine[n - 1][m - 1] = count + 0x30;//该坐标处应展示的值 (普通整数要转换为字符,需要加上‘0’的ASCII码值,即0x30)
    14. }
    15. else
    16. {
    17. open_mine(n, m);
    18. }
    19. return 1;
    20. }
    21. }

     判断是否赢得游戏

    1. //判断是否赢得游戏
    2. int is_win()
    3. {
    4. int i = 0, j = 0;
    5. int count = 0;
    6. for (i = 0; i < ROW - 2; i++)
    7. {
    8. for (j = 0; j < COL - 2; j++)
    9. {
    10. if (show_mine[i][j] == '*')
    11. {
    12. count++;
    13. }
    14. }
    15. }
    16. if (count == MINE)
    17. {
    18. return 0;
    19. }
    20. else
    21. {
    22. return 1;
    23. }
    24. }

     game.h文件

    1. //函数的声明
    2. #include
    3. #include
    4. #include
    5. #define COL 12
    6. #define ROW 12
    7. #define MINE 10
    8. char show_mine[ROW-2][COL-2];//展示给玩家的棋盘的数组
    9. char real_mine[ROW][COL];
    10. void init_mine();//初始化布置雷的棋盘和展示给玩家的棋盘
    11. void set_mine();//放置雷
    12. void print_mine(); //打印放置雷的棋盘
    13. void print_show();//打印展示给玩家的棋盘
    14. int count_mine();//统计周围雷的个数
    15. int has_queried(int n, int m);//判断输入的坐标是否已经被查询过
    16. int sweep_mine();//扫雷函数
    17. int is_win();//判断是否赢得游戏

     game.c文件

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include"saolei.h"
    3. //测试游戏逻辑
    4. void game()
    5. {
    6. int n = 0, m = 0;
    7. init_mine();//初始化布置雷的棋盘和展示给玩家的棋盘
    8. set_mine();//放置雷
    9. while (1)
    10. {
    11. print_mine(); //打印放置雷的棋盘(方便观察是否有错误,实现整个游戏后进行隐藏)
    12. printf("\n");
    13. print_show();//打印展示给玩家的棋盘
    14. printf("请输入您想排查雷的坐标:>");
    15. scanf("%d %d", &n, &m);
    16. if (n<1 || n>10 || m<1 || m>10)
    17. {
    18. printf("您输入的坐标无效,请重新输入\n");
    19. continue;
    20. }
    21. int ret1 = has_queried(n, m);//判断输入的坐标是否已经被查询过
    22. if (!ret1)
    23. {
    24. printf("该位置已经被查询,请重新输入\n");
    25. continue;
    26. }
    27. int ret2 = sweep_mine(n, m);//扫雷函数
    28. if (!ret2)
    29. {
    30. printf("您已被炸死!\n");
    31. break;
    32. }
    33. int ret3 = is_win();//判断是否赢得游戏
    34. if (!ret3)
    35. {
    36. printf("游戏胜利!\n");
    37. break;
    38. }
    39. }
    40. }
    41. void menu()
    42. {
    43. printf("*****************************\n");
    44. printf("******** 1. Play ********\n");
    45. printf("******** 0. Exit ********\n");
    46. printf("*****************************\n");
    47. }
    48. int main()
    49. {
    50. srand((unsigned int)time(NULL));//设置随机数的起始值
    51. int input = 0;
    52. do
    53. {
    54. menu();//主菜单
    55. printf("请输入您的操作:>");
    56. scanf("%d", &input);
    57. switch (input)
    58. {
    59. case 1:
    60. game();//进入游戏
    61. break;
    62. case 0:
    63. printf("退出游戏\n");
    64. break;
    65. default:
    66. printf("输入错误请重新输入:>");
    67. break;
    68. }
    69. } while (input);
    70. return 0;
    71. }

    运行截图:

    0e6a22fbfe4047f582e54d2317c2c966.png

    091e94fdb9d9486c8589ce90c9ef2681.png

    b42264f0d0fa43ab97aa9aa48e5f8e17.png

    由运行截图可以看出部分游戏的功能,为了方便大家的学习和交流,文中以及将所有代码都展示出来了,大家可以自行测试。

    总结

     以上就是今天要讲的内容,本文简单的介绍了用C语言实现扫雷小游戏的思路,还进一步展示了代码的运行结果验证了作者的思路。用学习到的知识来实现一个小游戏确实是一个成就感满满的事情,正在学习C语言的你也跟着一起来实现这个小游戏吧。

    本文的作者也只是一个正在学习C语言等编程知识的萌新,若这篇文章中有哪些不正确的内容,请在评论区向作者指出(也可以私信作者),欢迎大佬们指点,也欢迎其他正在学习C语言的萌新和作者进行交流。

    最后,如果本篇文章对你有所启发的话,也希望可以支持支持作者,后续作者也会定期更新学习记录。谢谢大家!

  • 相关阅读:
    GSAman | 我「玩着游戏」就把「科研做了」
    【MySQL进阶】--- 存储引擎的介绍
    糖友控糖是在控什么糖呢
    《Python进阶系列》二十九:append浅拷贝机制——你真的会用append函数吗?
    5.1 Ajax数据爬取之初介绍
    C++ 静态和运行时断言 assert, static_assert和 throw runtime_error
    传奇服务端MirServer文件有何作用
    SPI_OLED模块操作方法
    Vue知识点(4)
    acwing算法提高之图论--最小生成树的扩展应用
  • 原文地址:https://blog.csdn.net/xjjxjy_2021/article/details/127756159