【C语言】扫雷

整体来说比较简单

适合初学C语言的小白
需要你掌握以下知识:

掌握——分支switch、循环for、while语句
掌握——函数(传参,声明,创建)
掌握——数组(创建,传参)

阅读文章须知

此代码在VS2019软件中编写 (Visual Studio 2019)

文章顺序1.先说整体思路
2.写出部分代码
3.解析上述代码

布局

    1.打印菜单2.接收变量3.打印雷区4.接收坐标5.判断雷区周围包括坐标本身在内的 9个坐标内有几个雷6.  *为显示可排查区域7.  1为雷8.踩到雷结束游戏9.全部排查则游戏胜利*******************************  1.play  **************  0.exly  *******************************请选择输入开始游戏:> 1共有30个雷0 1 2 3 4 5 6 7 8 91 * * * * * * * * *2 * * * * * * * * *3 * * * * * * * * *4 * * * * * * * * *5 * * * * * * * * *6 * * * * * * * * *7 * * * * * * * * *8 * * * * * * * * *9 * * * * * * * * *//作弊 看到雷的布局0 1 2 3 4 5 6 7 8 91 0 0 1 1 1 0 0 1 02 1 0 0 1 1 0 0 0 13 0 0 0 1 1 0 0 1 04 1 1 0 1 1 0 0 0 05 0 0 1 1 0 1 1 1 16 0 0 0 1 0 0 0 0 07 1 1 0 1 0 0 1 0 08 0 0 0 0 0 0 0 0 09 0 0 1 1 1 0 0 0 1请输入坐标:5 50 1 2 3 4 5 6 7 8 91 * * * * * * * * *2 * * * * * * * * *3 * * * * * * * * *4 * * * * * * * * *5 * * * * 5 * * * *    显示周围雷的数量6 * * * * * * * * *7 * * * * * * * * *8 * * * * * * * * *9 * * * * * * * * *

游戏分为——两部分

  • 开始游戏
  • 结束游戏

开始游戏分为——四部分

  • 创建雷区
  • 初始化并打印
  • 生成雷
  • 排查雷

简单看一下整体布局 不至于从一开始就劝退初学者

全文共217行代码 整体代码在文章最后

下面跟随我的思路一起完成扫雷游戏吧!

首先创建三个文件

.c 文件是C语言文件
.h 文件是头文件

  • test.c :写主程序的.c文件
  • game.c : 写游戏主要代码的.c文件
  • game.h :引用 头文件 和 声明的.h头文件

在test.c文件中

创建main函数主体
主要思路是:

如在手机中观看 可左右滑动查看查处部分代码

    void emnu(){printf("************************\n");printf("*******  1.play  *******\n");printf("*******  0.exly  *******\n");printf("************************\n");}int main(){int input = 0;srand((unsigned int)time(NULL)); //后面创建随机数的函数do {//打印菜单emnu();printf("请选择输入开始游戏:> ");scanf("%d", &input);switch (input){case 1:game();//printf("游戏开始\n");break;case 0:printf("游戏结束\n");break;default:printf("输入错误,请重新选择!\n");break;}} while (input);return 0;}

srand((unsigned int)time(NULL)); 对于这句话后面会讲到

  • 上述代码分为 ——— 三部分

    1.打印菜单
    2.接收字符
    3.判断状态

    为了一打开程序就进入游戏状态
    所以用了 do{}while{} 循环

1.打印菜单调用 emnu()函数

        void emnu(){printf("************************\n");printf("*******  1.play  *******\n");printf("*******  0.exly  *******\n");printf("************************\n");}

2.接收字符

        我们在循环外部定义 int input = 0;  接收指令的变量scanf("%d",&input);  接收键盘输入的函数注意:%d后面不要加空格 & 符号不要忘记写

3.判断接收字符的状态

        switch(整形表达式) {case 整形常量表达式:break; //跳出switch 去下面的while中判断是否继续循环case 0:break;default://相当于if语句中的else的作用//当上面的语句都不满足时 执行此语句break;}while(input); //input为0时结束游戏输入1       继续游戏输入0       结束游戏输入错误    给出提示并从新输入
  • 当你想验证一下现在写的代码时
    • 可以在game.h中引入头文件
    • 并且在test.c中引入game.h头文件
    • 这样所有头文件都放在game.h中就可以了

    game.h

        #pragma once#include <stdio.h>
    
      在头文件中  第一行  写入#pragma once在其他文件中不管包含几次<stdio.h>都只拷贝一次是为了防止头文件重复 做无用功
    

    test.c

        #include "game.h"
    
经过上面的代码 可以在case 1: 中调用函数game()

ganme()分为——五部分

  • 1.创建雷区
  • 2.初始化
  • 3.打印初始化
  • 4.生成雷
  • 5.排查雷

1.创建雷区

test.c

 void game(){char LQu[ROWS][COLS]; 存放雷的信息char PCha[ROWS][COLS]; 排查雷的信息}
so easy 有没有 雷区创建好了

2.初始化雷区

    void game(){//创建雷区char LQu[ROWS][COLS]; //存放雷的信息char PCha[ROWS][COLS];//排查雷的信息//初始化CShi(LQu, ROWS, COLS,'0');//雷区CShi(PCha,ROWS, COLS,'*');//排查区//打印初始化//DY(LQu, ROW, COL);//雷区printf("共有%d个雷\n",LEI);DY(PCha, ROW, COL);//排查区//生成雷S_L(LQu, ROW, COL,LEI);printf("\n");//DY(LQu, ROW, COL);//雷区//排查雷P_C(LQu,PCha, ROW, COL);DY(PCha, ROW, COL);//排查区}
可以看到创建雷区 用到了两个数组 LQu PCha
先看下game.h中的代码

game.h

    #pragma once#include <stdio.h>#include <stdlib.h>#include <time.h>#include <string.h>#define ROW 9#define COL 9#define ROWS ROW+2  //ROW+2#define COLS COL+2  //COL+2#define LEI 10//初始化void CShi(char CShi[ROWS][COLS], int rows, int cols,char ret);//雷区
上述数组用到了两个 常量ROWS、COLS 怎么来的?
    这里用到5个变量,用#define定义#define 定义全局变量ROW 为用户可见区域 横坐标COL 为用户可见区域 纵坐标 ROWS  为底层排雷区域 横坐标COLS  为底层排雷区域 纵坐标LEI  为雷的个数为什么分为 ROW 和 ROWS 呢我们开头说到 比如是9*9 的格子在扫描雷的时候要扫描坐标在内的周围的9个格子如下:* * * * n ** * *整体的布局:(ROW,COL)0 1 2 3 4 5 6 7 8 91 * * * * * * * * *2 * * * * * * * * *3 * * * * * * * * *4 * * * * * * * * *5 * * * * * * * * *6 * * * * * * * * *7 * * * * * * * * *8 * * * * * * * * *9 * * * * * * * * *但是:左上(1,1),左下(1,9),右上(9,1),右下(9,9).....这几个坐标访问时就越界了所以:我们在底层代码扫描时 把上下左右都加上一行这时访问数组时就不会出现越界了也就有了ROWS、COLS 这两个变量#define ROW 9#define COL 9#define ROWS ROW+2  //ROW+2#define COLS COL+2  //COL+2
game.h 中下方还有一行代码——初始化 (下)

左右滑动查看代码

test.c

    char LQu[ROWS][COLS]; //存放雷的信息 定义数组char PCha[ROWS][COLS];//排查雷的信息 定义数组
//需要初始化的代码:CShi(LQu, ROWS, COLS,'0');//雷区CShi(PCha,ROWS, COLS,'*');//排查区这样设计用一个函数传参 就能给不同数组 初始化成不同的 字符

game.h

 //初始化void CShi(char CShi[ROWS][COLS], int rows, int cols,char ret);//雷区
        函数返回类型 不需要返回值 所以为 void数组传参 接收一个数组 用char CShi[][]数组接收ROWS COLS 是整形 用int 类型变量接收后面的 '0' '*' 用char 字符类型接收  因为排查雷需要更大的数组 所以用到了 ROWS COLStest.c      中定义函数game.h      声明函数game.c      实现代码

game.c

    #include "game.h"//初始化雷区void CShi (char CShi[ROWS][COLS], int rows, int cols,char ret){int i = 0;for (i = 0; i < rows; i++){int j = 0;for (j = 0; j < cols; j++){CShi[i][j] = ret;}}}
    用for循环将两个数组初始化成全0  全*CShi(LQu, ROWS, COLS,'0');0 1 2 3 4 5 6 7 8 9 a b1 0 0 0 0 0 0 0 0 0 0 02 0 0 0 0 0 0 0 0 0 0 03 0 0 0 0 0 0 0 0 0 0 04 0 0 0 0 0 0 0 0 0 0 05 0 0 0 0 0 0 0 0 0 0 06 0 0 0 0 0 0 0 0 0 0 07 0 0 0 0 0 0 0 0 0 0 08 0 0 0 0 0 0 0 0 0 0 09 0 0 0 0 0 0 0 0 0 0 0a 0 0 0 0 0 0 0 0 0 0 0b 0 0 0 0 0 0 0 0 0 0 0这一层布置雷 扫雷CShi(PCha,ROWS, COLS,'*');0 1 2 3 4 5 6 7 8 9 a b1 * * * * * * * * * * *2 * * * * * * * * * * *3 * * * * * * * * * * *4 * * * * * * * * * * *5 * * * * * * * * * * *6 * * * * * * * * * * *7 * * * * * * * * * * * 8 * * * * * * * * * * *9 * * * * * * * * * * *a * * * * * * * * * * *b * * * * * * * * * * *这一层打印出来给用户看 当然不是打印11*11  是打印9*9 后面会说到(16进制  a=10 b=11 c=12 d=13 e=14 f=15)

3.打印初始化

test.c

    //打印初始化DY(PCha, ROW, COL);//排查区printf("共有%d个雷\n",LEI); //告诉用户有几个雷

game.h

    //打印初始化void DY(char LQu[ROWS][COLS],int rows,int cols);//雷区
传参上面讲了 同理
这里要强调的是传参的时候用的是ROW COL
    因为打印出来的是要给用户观察的ROW COL 定义的为9所以要打印9*9 的个格子 聪明的你要问了:怎么才能在11*11 的数组中打印9*9 的格子呢?你: 我才没问呢  我都知道!你: 只要在数组下标为1 的地方打印到下标10就可以啦你真是个机灵鬼!!!

game.c

    //打印void DY(char LQu[ROWS][COLS], int row, int col){int i = 0;for (i = 0; i <= row; i++){printf("%d ", i);}printf("\n");for (i = 1; i <= row; i++){int j = 0;printf("%d ", i);for (j = 1; j <= col; j++){printf("%c ", LQu[i][j]);}printf("\n");}printf("\n");}
    上述代码 第一个循环 是打印出了每行的编号 为了方便观察下面的代码 也在每一行的首元素打印了编号最后for循环打印的数组初始化的内容打印结果如下:DY(PCha, ROW, COL);共有10个雷0 1 2 3 4 5 6 7 8 91 * * * * * * * * *2 * * * * * * * * *3 * * * * * * * * *4 * * * * * * * * *5 * * * * * * * * *6 * * * * * * * * *7 * * * * * * * * *8 * * * * * * * * *9 * * * * * * * * *

4.生成雷

test.c

    //生成雷S_L(LQu, ROW, COL,LEI); printf("\n");

game.h

    //生成雷void S_L(char LQu[ROWS][COLS], int row, int col,int lei);

game.c

    //生成雷void S_L(char LQu[ROWS][COLS], int row, int col,int lei){int i = lei;while(i){int x = rand() % row+1;int y = rand() % col+1;if (LQu[x][y] != '1'){LQu[x][y] = '1';i--;}}}
    思路:1.x y在规定坐标内 生成随机数一个随机数%10 则得到的结果不会大于10 也就是最大得到92.在随机产生的坐标中放入字符'1'
产生随机数rand()
    在主函数中调用srand()srand((unsigned int)time(NULL));接收time系统时间 强制准换成无符号整型(unsigned int)srand() 的头文件    <stdlib.h>time()  的头文件    <time.h>此时就可以在已经声明的范围内 使用rand()

还差一步就完成啦 ٩(๑>◡<๑)۶ 加油!

5.排查雷

败北:坐标 = ‘1’
胜利:输入坐标 = 坐标 - 雷

test.c

    //排查雷P_C(LQu,PCha, ROW, COL);DY(PCha, ROW, COL);//打印排查区

game.h

    //排查雷char P_C(char LQu[ROWS][COLS], char PCha[ROWS][COLS], int row, int col);

game.c

    //判断周围的雷数int LS(char LQu[ROWS][COLS], int x,int y){return (LQu[x-1][y]+ LQu[x - 1][y - 1]+ LQu[x][y - 1]+ LQu[x + 1][y - 1]+ LQu[x + 1][y]+ LQu[x + 1][y + 1]+ LQu[x][y + 1]+ LQu[x - 1][y + 1]- 8 * '0');}//排查char P_C(char LQu[ROWS][COLS], char PCha[ROWS][COLS], int row, int col){int x = 0;//横坐标int y = 0;//纵坐标int win = 0; //输入坐标次数//判断坐标合法while (win<row*col-LEI){printf("请输入坐标:");scanf("%d %d", &x, &y);//排查雷if ((x > 0 && x <=row) && (y > 0 && y <=col)){if (LQu[x][y] != '1'){//判断周围有几个雷int L = LS(LQu, x, y);PCha[x][y] = (L+'0');DY(PCha, ROW, COL);//打印排查区win++;}else{printf("很遗憾,你输了\n\n");DY(LQu, ROW, COL);//打印雷区break;}}else{printf("坐标非法,请重新输入!\n\n");}}if (win == ROW * COL - LEI){printf("恭喜你胜利了\n\n");}}

解释说明:

    x       横坐标y       纵坐标win     输入坐标数当输入坐标次数 < 雷区-雷接收坐标;如果: x y 符合要求如果:底层坐标xy != '1'则判断周雷数函数() - 下面单独讲假如返回数字 3打印时需要打印字符'3' - 下面单独讲打印雷区;win++;否则:游戏败北打印雷区跳出否则:重新输入当输入坐标次数 = 雷区-雷恭喜胜利!
首先是函数
    int LS(char LQu[ROWS][COLS], int x,int y){return (LQu[x-1][y]+ LQu[x - 1][y - 1]+ LQu[x][y - 1]+ LQu[x + 1][y - 1]+ LQu[x + 1][y]+ LQu[x + 1][y + 1]+ LQu[x][y + 1]+ LQu[x - 1][y + 1]- 8 * '0');}
    在ASCII码表中'0' = 48'1' = 49'2' = 50'3' = 51所以在字符'1' - 字符'0' = (59-48 = 1)用%d打印就能打印出数字1;计算雷的个数 因为雷用'1'表示所以将字符'1'转换为 数字1相加即可先把8个'1'相加  再减去(8个'0') 得到雷的个数传过来用int 接收加上'0' 转换成字符'3' 打印到屏幕上即可;int L = LS(LQu, x, y);PCha[x][y] = (L+'0');

恭喜你呀!٩(๑>◡<๑)۶ 完成了一个大项目

快来瓶快乐水庆祝一下!

完整代码如下

test.c

    #define _CRT_SECURE_NO_WARNINGS 1#include "game.h"void game(){//创建雷区char LQu[ROWS][COLS]; //存放雷的信息char PCha[ROWS][COLS];//排查雷的信息//初始化CShi(LQu, ROWS, COLS,'0');//雷区CShi(PCha,ROWS, COLS,'*');//排查区//打印初始化//DY(LQu, ROW, COL);//雷区printf("共有%d个雷\n",LEI);DY(PCha, ROW, COL);//排查区//生成雷S_L(LQu, ROW, COL,LEI);printf("\n");//DY(LQu, ROW, COL);//雷区//排查雷P_C(LQu,PCha, ROW, COL);DY(PCha, ROW, COL);//排查区}void emnu(){printf("************************\n");printf("*******  1.play  *******\n");printf("*******  0.exly  *******\n");printf("************************\n");}int main(){int input = 0;srand((unsigned int)time(NULL));do {//打印菜单emnu();printf("请选择输入开始游戏:> ");scanf("%d", &input);switch (input){case 1:game();//printf("游戏开始\n");break;case 0:printf("游戏结束\n");break;default:printf("输入错误,请重新选择!\n");break;}} while (input);return 0;}

game.h

    #pragma once#include <stdio.h>#include <stdlib.h>#include <time.h>#include <string.h>#define ROW 9#define COL 9#define ROWS ROW+2#define COLS COL+2#define LEI 10//初始化void CShi(char CShi[ROWS][COLS], int rows, int cols,char ret);//雷区//打印初始化void DY(char LQu[ROWS][COLS],int rows,int cols);//雷区//生成雷void S_L(char LQu[ROWS][COLS], int row, int col,int lei);//排查雷char P_C(char LQu[ROWS][COLS], char PCha[ROWS][COLS], int row, int col);

game.c

    #define _CRT_SECURE_NO_WARNINGS 1#include "game.h"//初始化雷区void CShi (char CShi[ROWS][COLS], int rows, int cols,char ret){int i = 0;for (i = 0; i < rows; i++){int j = 0;for (j = 0; j < cols; j++){CShi[i][j] = ret;}}}//打印void DY(char LQu[ROWS][COLS], int row, int col){int i = 0;for (i = 0; i <= row; i++){printf("%d ", i);}printf("\n");for (i = 1; i <= row; i++){int j = 0;printf("%d ", i);for (j = 1; j <= col; j++){printf("%c ", LQu[i][j]);}printf("\n");}printf("\n");}//生成雷void S_L(char LQu[ROWS][COLS], int row, int col,int lei){int i = lei;while(i){int x = rand() % row+1;int y = rand() % col+1;if (LQu[x][y] != '1'){LQu[x][y] = '1';i--;}}}//判断周围的雷数int LS(char LQu[ROWS][COLS], int x,int y){return (LQu[x-1][y]+ LQu[x - 1][y - 1]+ LQu[x][y - 1]+ LQu[x + 1][y - 1]+ LQu[x + 1][y]+ LQu[x + 1][y + 1]+ LQu[x][y + 1]+ LQu[x - 1][y + 1]- 8 * '0');}//排查char P_C(char LQu[ROWS][COLS], char PCha[ROWS][COLS], int row, int col){int x = 0;int y = 0;int win = 0;//判断坐标合法while (win<row*col-LEI){printf("请输入坐标:");scanf("%d %d", &x, &y);//排查雷if ((x > 0 && x <=row) && (y > 0 && y <=col)){if (LQu[x][y] != '1'){//判断周围有几个雷int L = LS(LQu, x, y);PCha[x][y] = (L+'0');DY(PCha, ROW, COL);//排查区win++;}else{printf("很遗憾,你输了\n\n");DY(LQu, ROW, COL);//雷区break;}}else{printf("坐标非法,请重新输入!\n\n");}}if (win == ROW * COL - LEI){printf("恭喜你胜利了\n\n");}}

如果与任何疑问 欢迎留言 我看到后随时为你 解答疑问

希望这篇文章对初学C语言的你有所帮助

如果喜欢的话 记得点赞收藏哦!

下次再见٩(๑>◡<๑)۶

【C语言】扫雷—初学者也能写的小游戏相关推荐

  1. C语言可以敲哪些小游戏,C语言可以写哪些小游戏?

    C语言可以写哪些小游戏? C语言可以编手机游戏.你叫他去死不过我这有贪吃蛇的代码,你倒可以看看(用TC编译一定过( #包括 #包括 #包括 #包括 #包括 #定义输入7181 #定义ESC 283 # ...

  2. flash编程可以用c语言,C语言写的小游戏和FLASH小游戏有何区别呢-c语言编程手机软件...

    C语言写的小游戏和FLASH小游戏有何区别呢-c语言编程手机软件 (2010-12-05 17:12:08) 标签: 杂谈 分类: 随笔 同题有大大的区分c语言写游戏可以直接挪用体系api举行编著,合 ...

  3. python写游戏脚本-使用Python写一个小游戏

    引言 最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,来感受下 ...

  4. python编程小游戏-使用Python写一个小游戏

    引言 最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,来感受下 ...

  5. 使用python制作聊天框解谜游戏_使用Python写一个小游戏alien invasion!

    最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,来感受下其中的 ...

  6. 手机版python3h如何自制游戏_教你如何用 Python 写一个小游戏

    教你如何用 Python 写一个小游戏 引言 最近 python 语言大火, 除了在科学计算领域 python 有用武之地之外, 在游戏后台等方面, python 也大放异彩, 本篇博文将按照正规的项 ...

  7. 关于python小游戏的毕业论文_使用Python写一个小游戏

    引言 最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,来感受下 ...

  8. 用python做一个简单的游戏,用python写一个小游戏

    大家好,本文将围绕如何用python做一个简单的小游戏展开说明,python编写的入门简单小游戏是一个很多人都想弄明白的事情,想搞清楚用python做一个简单的游戏需要先了解以下几个事情. 1.Pyt ...

  9. c语言扔骰子随机数的相加,C语言编程学习:制作掷骰子小游戏

    C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...

最新文章

  1. JavaMail学习之一-邮件传输协议
  2. [转]设计模式(22)-Strategy Pattern
  3. fseek linux 大文件_一文搞懂Linux系统开发
  4. 异常检测机器学习_使用机器学习检测异常
  5. 百度地图定位地址为空
  6. 动态规划——最大子段和(hdu1003,1231)
  7. 爱培科963方案GPS升级ROM过程以及SDK开发
  8. linux和windows下安装python拓展包及requirement.txt安装类库
  9. Android——从HellowWorld开始
  10. 初始化栈的代码_限定性数据结构-栈
  11. hprose php,hprose和swoole区别
  12. 光伏抢装潮:630的得与失
  13. 气象台发布的拼图重投影示例
  14. 实训一 古诗横竖输出
  15. VGA RGBHV 时序图
  16. 编程课python和c+对中高考_编程要进入高考了。
  17. 技术资料收集 技术大牛及网站推荐 待研究方向
  18. 量化交易 简易回测框架
  19. 14-HAL库之I2C通信
  20. 分享77个Java源码,总有一款适合您

热门文章

  1. 荧光染色切片病理分析算法(深度学习+机器学习)
  2. 新形势下国家医疗保障局信息化建设注意点(三)建设省级平台
  3. Fluent 时间步长【转载】
  4. python yaml dump_使用Python处理yaml格式的数据简单到爆!
  5. Hadoop 2.7 不停服升级到 3.2 在滴滴的实践
  6. 在学校游说开源和Linux
  7. 核酸扫码登记体验有感(如何提高OCR的文字正确识别率)
  8. Arduino STM32用NTC热敏电阻 OLED显示屏制作温度计
  9. 2023第三届人工智能与机器学习国际学术会议(ICMLAI 2023)
  10. 复数的加减乘除及开方乘方运算