【C语言】扫雷—初学者也能写的小游戏
【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函数主体
主要思路是:
先打印菜单: 1开始 / 0结束
选择并开始游戏
如在手机中观看 可左右滑动查看查处部分代码
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语言】扫雷—初学者也能写的小游戏相关推荐
- C语言可以敲哪些小游戏,C语言可以写哪些小游戏?
C语言可以写哪些小游戏? C语言可以编手机游戏.你叫他去死不过我这有贪吃蛇的代码,你倒可以看看(用TC编译一定过( #包括 #包括 #包括 #包括 #包括 #定义输入7181 #定义ESC 283 # ...
- flash编程可以用c语言,C语言写的小游戏和FLASH小游戏有何区别呢-c语言编程手机软件...
C语言写的小游戏和FLASH小游戏有何区别呢-c语言编程手机软件 (2010-12-05 17:12:08) 标签: 杂谈 分类: 随笔 同题有大大的区分c语言写游戏可以直接挪用体系api举行编著,合 ...
- python写游戏脚本-使用Python写一个小游戏
引言 最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,来感受下 ...
- python编程小游戏-使用Python写一个小游戏
引言 最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,来感受下 ...
- 使用python制作聊天框解谜游戏_使用Python写一个小游戏alien invasion!
最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,来感受下其中的 ...
- 手机版python3h如何自制游戏_教你如何用 Python 写一个小游戏
教你如何用 Python 写一个小游戏 引言 最近 python 语言大火, 除了在科学计算领域 python 有用武之地之外, 在游戏后台等方面, python 也大放异彩, 本篇博文将按照正规的项 ...
- 关于python小游戏的毕业论文_使用Python写一个小游戏
引言 最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,来感受下 ...
- 用python做一个简单的游戏,用python写一个小游戏
大家好,本文将围绕如何用python做一个简单的小游戏展开说明,python编写的入门简单小游戏是一个很多人都想弄明白的事情,想搞清楚用python做一个简单的游戏需要先了解以下几个事情. 1.Pyt ...
- c语言扔骰子随机数的相加,C语言编程学习:制作掷骰子小游戏
C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...
最新文章
- JavaMail学习之一-邮件传输协议
- [转]设计模式(22)-Strategy Pattern
- fseek linux 大文件_一文搞懂Linux系统开发
- 异常检测机器学习_使用机器学习检测异常
- 百度地图定位地址为空
- 动态规划——最大子段和(hdu1003,1231)
- 爱培科963方案GPS升级ROM过程以及SDK开发
- linux和windows下安装python拓展包及requirement.txt安装类库
- Android——从HellowWorld开始
- 初始化栈的代码_限定性数据结构-栈
- hprose php,hprose和swoole区别
- 光伏抢装潮:630的得与失
- 气象台发布的拼图重投影示例
- 实训一 古诗横竖输出
- VGA RGBHV 时序图
- 编程课python和c+对中高考_编程要进入高考了。
- 技术资料收集 技术大牛及网站推荐 待研究方向
- 量化交易 简易回测框架
- 14-HAL库之I2C通信
- 分享77个Java源码,总有一款适合您
热门文章
- 荧光染色切片病理分析算法(深度学习+机器学习)
- 新形势下国家医疗保障局信息化建设注意点(三)建设省级平台
- Fluent 时间步长【转载】
- python yaml dump_使用Python处理yaml格式的数据简单到爆!
- Hadoop 2.7 不停服升级到 3.2 在滴滴的实践
- 在学校游说开源和Linux
- 核酸扫码登记体验有感(如何提高OCR的文字正确识别率)
- Arduino STM32用NTC热敏电阻 OLED显示屏制作温度计
- 2023第三届人工智能与机器学习国际学术会议(ICMLAI 2023)
- 复数的加减乘除及开方乘方运算