当前位置:   article > 正文

【C语言 】扫雷小程序代码实现_c语言游戏小程序

c语言游戏小程序

                                                               START

我们平时玩的扫雷小游戏,可以通过C语言简易实现,当然,设计这个小游戏,需要具备严谨的逻辑,一步接一步的思维引领。

文章目录

  1. 思考扫雷步骤(思路)

  2. 多文件进行处理

  3. 设置菜单

  4. main函数中布置游戏实现框架

  5. 对游戏主体进行编写(game.c) + 声明自定义函数(game.h)


1. 思考扫雷步骤(思路)

          首先,扫雷这个小程序,我们分析游戏规则得知:当我们排查雷的时候,如果所排查位置是雷的话,那我们就被炸死了;如果所排查处不是雷,为了降低游戏难度,我们可以显示所排查之处周围有多少个雷。


2. 多文件进行处理

          由于扫雷代码偏长,为了使程序员编写条理井然有序,并可以多人进行对一个项目的编写,后续维修、检查Bug方便,因此分装成多个文件处理:main.c 扫雷小程序的主体框架)、game.c(扫雷游戏功能的实现)、game.h(扫雷游戏功能中自定义函数的声明)。


3. 设置菜单

          扫雷小程序面向用户,美观且通俗易懂的菜单当然是必不可少的,由于菜单并不是很复杂,我们将菜单(menu)函数放在主函数中也是可以的。                 

  1. void menu()
  2. {
  3. printf(" +---+---+---+---+---+---+---+---+---+\n");
  4. printf(" | <欢迎使用扫雷游戏> |\n");
  5. printf(" +---+---+---+---+---+---+---+---+---+\n");
  6. printf(" * * * * * * * * * * * * * * * * * * *\n");
  7. printf(" +---+---+---+---+---+---+---+---+---+\n");
  8. printf(" | 请选择你要执行的操作>> |\n");
  9. printf(" +---+---+---+---+---+---+---+---+---+\n");
  10. printf(" | 【1】开始游戏 |\n");
  11. printf(" +---+---+---+---+---+---+---+---+---+\n");
  12. printf(" | 【0】退出游戏 |\n");
  13. printf(" +---+---+---+---+---+---+---+---+---+\n");
  14. }

通过这个菜单,我们将“1"设置为 开始游戏,并将”0“作为退出游戏


4. 在main函数中布置游戏实现框架


Procedure_1 ——与菜单功能相结合


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

        当我们选择”1“的时候,进入游戏主体,若当我们选择”0“的时候,将退出游戏,如果选择其他数时,将提示”选择错误,请重新选择。通过while循环,将我们输入的数字进行反馈。


 Procedure_2 ——主函数中调用game函数


1 . 定义两个棋盘

        首先,我们想,在一个扫雷的棋盘中,棋盘里的数据用什么存储是“雷”和“非雷”,很容易会想到:“1"表示是”雷“,”0“表示"非雷”,但是问题来了,如果我们想呈现所排查的坐标周围有多少个雷的时候,数字逻辑就相互矛盾了,但是我们可以创建两个数组分开进行操作。

  1. #define ROW 9
  2. #define COL 9

        由于我们在排查时,发现当排查坐标在边缘角落时,有一些数据越界了,因此,我们将棋盘加个“边框”就能很好地解决这个问题。 

  1. #define ROWS ROW+2
  2. #define COLS COL+2

    通过宏定义ROW,COL方便后续进行修改

  1. char mine[ROWS][COLS];
  2. char show[ROWS][COLS];

   定义mine数组为布置雷的数组,show数组为展示排查的数组


2 .初始化两个棋盘

       自定义Initboard为初始化函数,将mine和show两个数组中数据分别初始化为“0”、“*”。主函数调用Initboard函数时,传数组时,记得传的是数组名(即首元素地址)。

  1. Initboard(mine, ROWS, COLS, '0');
  2. Initboard(show, ROWS, COLS, '*');

3 . 打印棋盘

       自定义Displayboard函数进行数组的打印,同时,主函数调用Displayboard函数时,传数组时,记得传的是数组名(即首元素地址)。

Displayboard(show, ROW, COL);

4 .  布置雷的位置

       自定义Setmine函数进行对mine数组布置雷的坐标,当然,主函数调用Setmine函数时,传数组时,记得传的是数组名(即首元素地址)。

Setmine(mine, ROW, COL);

5 .  排查雷的位置

           自定义Findmine函数,将从mine数组中排查中的数据通过show数组展现出来,因此,在调用Findmine函数时,应该传入mine和show这两个数组。

Findmine(mine, show, ROW, COL);

5. 对游戏主体进行编写(game.c) + 声明自定义函数(game.h)


  Procedure_1 ——游戏框架(game.c)


                     <  接下来,在game.c中我们将我们上述的自定义函数逐个实现 >

1 . 初始化数组函数——Initboard

        在Initboard函数中,形参有一个字符数组用于接收初始化的数组,行(rows)、(cols)以及想要初始化成的数据,即通过for循环嵌套for循环>>

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

2 . 呈现棋盘的函数——Displayboard

       在Displayboard函数中,形参传入一个字符数组,所展示的棋盘不需要包括边框,因此形参传的是row和col。为了外观更美观,我们也可以通过for循环将行、列号打印出来>>

  1. void Displayboard(char board[ROWS][COLS], int row, int col)
  2. {
  3. //呈现可以进行改善-美观!!!
  4. printf("<-------扫雷------>\n");
  5. for (int i = 0; i <= col; i++)
  6. {
  7. printf("%d ", i);
  8. }
  9. printf("\n");
  10. for (int i = 1; i <= row; i++)
  11. {
  12. printf("%d ", i);
  13. for (int j = 1; j <= row; j++)
  14. {
  15. printf("%c ", board[i][j]);
  16. }
  17. printf("\n");
  18. }
  19. }

3 . 布置雷的函数——Setmine

       同样,布置雷和展示雷一样,都不需要作用到边框,因此也是传row和col参数,现在,我们要布置雷的个数为NUMBER_MINE ,但是我们确保每次布置雷的位置都是随机的,这里我们需要使用随机种子数(rand),使用随机种子数,我们需要在game.h文件中定义#include<stdlib.h>、#include<time.h>这两个头文件,并且在main.c主体中添加srand((unsigned int)time(NULL));为了确保我们布置的雷满足我们设定的量,当我们布置一个雷的时候,可以做一个标记,即:count--

下面是代码展示>>

  1. #include<stdlib.h>
  2. #include<time.h>
srand((unsigned int)time(NULL));
  1. void Setmine(char board[ROWS][COLS], int row, int col)
  2. {
  3. int count = NUMBER_MINE;
  4. while (count)
  5. {
  6. int x = rand() % row + 1;
  7. int y = rand() % col + 1;
  8. if (board[x][y] == '0')
  9. {
  10. board[x][y] = '1';
  11. count--;
  12. }
  13. }
  14. }

Tips:  int x = rand() % row + 1; 即x的范围属于1~row


4 . 排查雷的函数——Findmine

       首先,调用mine数组,排查所输入的坐标是否是雷;(1)当踩中雷的时候,游戏结束,并展示雷的坐标(Displayboard(mine, ROW, COL); (2) 当没有踩中时,我们可以再自定义一个Getminecount函数将该点周围8个坐标的雷统计出来并打印出来;(3)为确保游戏严谨性,我们还可以将输入不合法的形式进行提示-重新输入。(4)为了游戏顺利结束,我们可以将循环条件设置成输入次数小于row*col-布置的雷数>>

  1. void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
  2. {
  3. int x = 0;
  4. int y = 0;
  5. int number = 0;
  6. while (number < row * col - NUMBER_MINE)
  7. {
  8. printf("请输入你要排查的坐标:例如:3 6\n");
  9. printf("\n");
  10. scanf("%d %d", &x, &y);
  11. //排查雷的时候,有合理与不合理之分
  12. //合理>
  13. if (x >=1 && x <= row && y >=1 && y <= col)
  14. {
  15. //当你踩中雷时
  16. if (mine[x][y] == '1')
  17. {
  18. printf("\a");
  19. printf("很遗憾,你被炸死了\n");
  20. Displayboard(mine, ROW, COL);
  21. break;
  22. }
  23. //当你踩的不是雷时
  24. else
  25. {
  26. int ret = Getminecount(mine, x, y);
  27. show[x][y] = ret + '0';
  28. Displayboard(show, ROW, COL);
  29. printf("加油,请继续排查!\n");
  30. printf("\n");
  31. printf("\a");
  32. number++;
  33. }
  34. }
  35. //当输入x,y不满足时,进行重新输入
  36. else
  37. {
  38. printf("输入非法,请重新输入\n");
  39. printf("\a");
  40. }
  41. }
  42. if (number == row * col - NUMBER_MINE)
  43. {
  44. printf("恭喜你,排雷成功!\n");
  45. printf("\a");
  46. Displayboard(mine, ROW, COL);
  47. }
  48. }

5 . 统计周围8个坐标的自定义函数——Getminecoun

       该函数设置有返回值,由于“0”的Ascall码是48,“2”的Ascall码是50.因此,两字符相减,所得之值即数字2 ,将周围8个数的Ascall码相减,所得之值便是所求值。

  1. int Getminecount(char mine[ROWS][COLS], int x, int y)
  2. {
  3. return (mine[x - 1][y - 1] + mine[x - 1][y]
  4. + mine[x - 1][y + 1] + mine[x][y - 1]
  5. + mine[x][y + 1] + mine[x + 1][y - 1]
  6. + mine[x + 1][y] + mine[x + 1][y + 1]
  7. - 8 * '0');
  8. }


 Procedure_2 ——函数头文件(game.h)


将game.c中的函数声明,并包含一些头文件

  1. #pragma once
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<time.h>
  5. //通过#define 定义行数,列数,方便后续快速修改
  6. #define ROW 9
  7. #define COL 9
  8. #define ROWS ROW+2
  9. #define COLS COL+2
  10. //定义雷的个数
  11. #define NUMBER_MINE 10
  12. //将数组进行初始化
  13. void Initboard(char board[ROWS][COLS], int rows, int cols, int set);
  14. //打印展示需要呈现的数组
  15. void Displayboard(char board[ROWS][COLS],int row, int col);
  16. //通过随机种子数随机布置雷
  17. void Setmine(char board[ROWS][COLS], int row, int col);
  18. //在mine数组中检测是否是雷,并在show数组中显示详情
  19. void Findmine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);
  20. //计算周围雷的个数
  21. int Getminecount(char mine[ROWS][COLS], int x, int y);

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/905060
推荐阅读
相关标签
  

闽ICP备14008679号