做摄影网站的公司,网站 虚拟空间,帝国 cms 网站关键字,做网站找我们文章目录 前言
一、整个排雷游戏的思维梳理
二、整体代码分布布局
三、游戏主体逻辑实现--test.c
四、整个游戏头文件的引用以及函数的声明-- game.h
五、游戏功能的具体实现 -- game.c
六、老六版本
总结 前言
路漫漫其修远兮#xff0c;吾将上下而求索。 一、整个排… 文章目录 前言
一、整个排雷游戏的思维梳理
二、整体代码分布布局
三、游戏主体逻辑实现--test.c
四、整个游戏头文件的引用以及函数的声明-- game.h
五、游戏功能的具体实现 -- game.c
六、老六版本
总结 前言
路漫漫其修远兮吾将上下而求索。 一、整个排雷游戏的思维梳理
当玩家点开游戏就会出现菜单供玩家进行选择是玩游戏还是退出游戏当然你还可以整点有意思的选项让正经的排雷游戏变得不正经
当玩家输入自己的选择后要么退出游戏要么进入排雷游戏当玩家进入排雷游戏时就要先给玩家展示一下棋盘让玩家输入想要排查的坐标计算机再判断玩家输入的这个坐标是不是雷如果是雷游戏结束当然菜单会再出现一次玩家可自行判断要不要再来一局游戏如果不是雷就要向玩家展示此坐标周围雷的个数,并且玩家会一直输入坐标进行排雷直到玩家踩到雷或者玩家排雷成功 感觉不难让我们一起来实现吧~
二、整体代码分布布局
明确分工提高效率~
test.c //整个游戏的主题逻辑
game.c //游戏功能的具体实现
game.h //包含一些头文件以及函数进行函数声明
三、游戏主体逻辑实现--test.c
代码如下
#includegame.hvoid menu()
{printf(****************************\n);printf(*****1、 play **************\n);printf(*****0、 exit **************\n);printf(****************************\n);
}
void game()
{//创建棋盘--二维数组char mine[ROWS][COLS] { 0 };char show[ROWS][COLS] { 0 };//初始化棋盘InitBoard(mine, ROWS, COLS, 0);InitBoard(show, ROWS, COLS, *);//电脑随机放雷SetMine(mine, ROW, COL);//向玩家展示所要排雷的棋盘DisplayBoard(show, ROW, COL);//玩家排雷FindMine(mine, show, ROW, COL);
}
int main()
{int input 0;do{menu();printf(玩家请输入选择:);scanf(%d, input);switch (input){case 1:game();break;case 0:printf(退出游戏成功\n);break;default :printf(输入错误请重新输入\n);}} while (input);return 0;
}
注意
1、 为什么创建了两个数组并且都是字符数组
由于在 show 展示的棋盘上我们想要用 * 来初始化此棋盘显然show 棋盘中底层用来存放数据的二维数组就应该是字符数组如果要将雷的信息放在show 中那么显示给玩家看也会一览无余雷的位置所以这里应该创建两个相同的“棋盘”一是用来专门存放电脑随机分配的雷的信息以及排雷另外一个就是展示给玩家看的实现与玩家的互动那么这两个棋盘在类型与大小上保持一致就会更好操作当然你也可以不让这两个数组一样只不过是在处理上会更加麻烦了而已
2、数组的创建为什么用ROWS 与 COLS创建呢而展示却是用ROW 与 COL
在头文件game.h 中ROW COL 是我们定义的标识符常量即为9而ROWS,COLS 在ROW COL 的基础上大了2
创建的棋盘比实际的棋盘的横列均多2 的原因是在排雷的时候如果玩家输入的坐标不是雷的话就要计算该坐标周围雷的个数如果是计算边缘坐标周围的雷的个数周围的坐标数都不同所以为了统一处理保证实际棋盘中的每个做坐标周围均有8个坐标当然你也可以不这样做头铁的话只有麻烦自己了
3、既然为字符数组是如何求得非雷坐标周围雷的个数的
例如如果非雷用‘ ’ 来表示雷用 ‘*’ 来表示利用循环产生包括此非雷坐标的9个坐标一个个判断产生的 坐标再判断是不是雷* 即可是雷的话便利用计数器 count 即可本文写的代码中非雷为 ‘0’ 雷为 ‘1’ 由于字符本质上就是ASCII码值所以也可以利用那么可以用加法与减法的原则来计算周围坐标雷的个数当然我用的是循环计数器
4、电脑随机放置雷的操作的原理
在此之前我们得了解一下rand srand time
rand 与 srand 的头文件 stdlib.h
time 的头文件 time.h int rand(void); 库函数rand 没有参数但是有返回值其返回值类型为int;
库函数可以生成随机数但是它是基于算法生成得故而并不是真正的随机数是伪随机数rand 生成伪随机数的范围为 0-32767
而使用rand 一般是要与srand 一起使用的srand产生随机变化的数seed(种子) 而rand 是基于srand 产生的数即seed种子进行产生伪随机数算法的运算当使用rand 的程序中没有srand时rand 便会默认种子为1 void srand( unsigned int seed) ;库函数的参数类型为 unsigned int如若想让rand 基于 seed产生随机的值那么这个seed 就得变化。而什么是变化的呢聪明的你可能会说是时间没错真棒就是时间我们可以利用时间戳即利用库函数 time ;
注时间戳当前时间与计算机时间 1970年1月1日午夜之间的差值单位是秒 time_t time (time_t * timer);
库函数 time 的返回类型为 time_t ,其参数为 time_t* 类型的指针
即如果正常使用库函数time 得有指针参数time 会返回一位 time_t 类型的返回值如果不想用time 的参数那么就用空指针NULL;
只要每一次程序运行是 seed 都不同那么便可以保证 rand 在每一次程序执行时产生的随机值不会有相同所以将 seed 产生放在main 函数中即可
5、玩家排雷--展开操作的原理
说“展开”可能你还不知道是什么意思你玩排雷游戏的时候是不是有时会展开一片呢展开这一片的功能就是此处探讨的展开功能如下图所示 展开的格子是非雷且周围没有雷-- 这里便包含了两个条件
当周围8个坐标有雷的时候就不会展开为空格取而代之的是标明此坐标周围雷的个数
图解 分析当玩家输入一个坐标的时候首先要判断此坐标是否在排雷对象棋盘的合理范围之内在合理范围之内便进行上图的操作会用到三个功能一是计算一个坐标周围雷的个数二是展开空格的功能三是判断玩家输赢
四、整个游戏头文件的引用以及函数的声明-- game.h
代码如下
#includestdio.h
#includestdlib.h
#includetime.h#define ROW 9
#define COL 9#define ROWS ROW2
#define COLS COL2#define MINE_COUNT 10
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set);//电脑随机放雷
void SetMine(char mine[ROWS][COLS], int row, int col);//计算周围八个坐标雷的个数
int ArroundingMine(char mine[ROWS][COLS], int x, int y);//展开功能
void ExtendBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);//玩家排雷是否成功的判断条件
int IsWin(char show[ROWS][COLS], int row, int col);//向玩家展示所要排雷的棋盘
void DisplayBoard(char show[ROWS][COLS], int row, int col);//玩家排雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
分析
在头文件中实现头文件、函数的声明以及定义标识符常量只要源文件声明包含了此头文件相当于此源文件也声明了一次
注1、#define 定义的标识符常量 -- 在全局使用时更易于修改非常方便
2、函数一定要做到先声明再使用
五、游戏功能的具体实现 -- game.c
1、初始化棋盘
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set)
{int i 0;int j 0;for (i 0; i rows; i){for (j 0; j cols; j){board[i][j] set;}}
}
就是二维数组的初始化两重循环嘎嘎整起来就可以了
2、电脑随机放雷
//电脑随机放雷
void SetMine(char mine[ROWS][COLS], int row, int col)
{int x 0;int y 0;int count MINE_COUNT;while (count){x rand() % row 1;y rand() % col 1;//埋雷的范围是1-9if (mine[x][y] 0){mine[x][y] 1;count--;}}
}
雷坐标的产生并不是每一次都可以产生有效的坐标且雷坐标的个数受雷个数的影响此处的 MINE_COUNT 就是在头文件中定义的标识符常量--雷的个数--为10所以此处应该用循环并且是用while 循环
看上面的代码相信聪明的你一定可以理解
3、向玩家展示所要排雷的棋盘
//向玩家展示所要排雷的棋盘
void DisplayBoard(char show[ROWS][COLS], int row, int col)
{//展示的show 棋盘上的1-9//还要添上坐标int i 0;int j 0;for (j 0; j col; j){printf(%d , j);}printf(\n);for (i 1; i row; i){printf(%d , i);for (j 1; j col; j){printf(%c , show[i][j]);}//打印完一行就换行printf(\n);}
} 这个函数就有点讲究了不仅向玩家展示了棋盘还加上了索引记得换行记得换行记得换行重要的事情说三遍 二维数组在内存中是一块连续的空间如果想打印出规规整整的棋盘样式就得在每打印完一行之后写个printf(\n); 以实现手动换行 其次就是加上索引在每一行前加上行数以表示此行是第几行显然就会多一列那么用一行的数字对应此列为第几列时就应该从0开始 注意你的目标你打印的时 show 数组中1-9 行1-9 列的数据
4、计算周围八个坐标雷的个数
//计算周围八个坐标雷的个数
int ArroundingMine(char mine[ROWS][COLS], int x, int y)
{int i 0;int j 0;int count 0;for(i -1; i 1; i){for (j -1; j 1; j){if (mine[x i][y j] 1)count;}}return count;
}
原理前面提过如果不太理解这里的代码可以往前翻翻不过相信聪明的你一定是理解的
5、展开功能
//展开功能
void ExtendBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{//产生该坐标周围八个坐标int i 0;int j 0;int count 0;for (i x-1; i x1; i){for (j y-1; j y1; j){//避免重查if (show[i][j] *){//不是雷if (mine[i][j] 0){count ArroundingMine(mine, i, j);if (count 0){show[i][j] ;ExtendBoard(mine, show, i, j);}else{show[i][j] count 0;}}}}}
}
基本上就是这张图的意思 注此处的show[i][j] count 0;
因为数组 show 是char 类型的数组所以其元素是char 类型然而count ArroundingMine(mine, i, j); 计算周围坐标雷的个数的函数的ArroundingMine 的返回类型是 int 类型所以用来接收其返回值的 conut 是 int 类型想让数字转换成字符利用ascii码值即可即加上 0 ;
6、玩家排雷是否成功的判断条件
//玩家排雷是否成功的判断条件
int IsWin(char show[ROWS][COLS], int row, int col)
{int i 0;int j 0;int count 0;for (i 1; i row; i){for (j 1; j col; j){if (show[i][j] *)count;}}return count;
}
7、玩家排雷 //玩家输入想要排查的坐标 // 输入的坐标合法 //避免重查 //在mine 棋盘上判断该坐标是不是雷是雷游戏结束不是雷游戏继续 //在此坐标不是雷的基础上计算该坐标周围雷的个数如果个数为0先排除重查的坐标再计算此坐标周围八个坐标的周围八个坐标的雷的个数 //递归 如果个数不为0就在show 棋盘对应的坐标上展示此坐标周围雷的个数 //循环的结束当玩家踩到雷或者排雷成功 //排雷成功的标准在show 棋盘上剩下的*个数与雷的个数相同 //玩家排雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x 0;int y 0;int win 0;int count 0;win IsWin(show, ROW, COL);while (win MINE_COUNT){printf(玩家请输入想要排查的坐标:);scanf(%d %d, x, y);if (x 1 x row y 1 y col){if (show[x][y] *){if (mine[x][y] 1){printf(哎呦踩到雷了游戏结束\n);DisplayBoard(mine, ROW, COL);break;}else{count ArroundingMine(mine, x, y);if (count 0){ExtendBoard(mine, show, x, y);}else{show[x][y] count 0;}win IsWin(show, ROW, COL);DisplayBoard(show, ROW, COL);}}else{printf(此坐标已经排查过请重新输入\n);}}else{printf(输入的坐标不再棋盘的范围内请重新输入\n);}}if (win MINE_COUNT){printf(恭喜玩家排雷成功\n);DisplayBoard(mine, ROW, COL);DisplayBoard(show, ROW, COL);}
}六、老六版本
1、老娘费尽心思做的小游戏发给你你必须给我玩不玩就让你电脑关机
2、可以不让你的电脑关机但是你得喊我 “爸爸” (叉除、忽略均无效反抗只要你不输入 “爸爸”都给你关机)
效果如下 test.c 代码如下
#includegame.hvoid menu()
{printf(****************************\n);printf(*****1、 play **************\n);printf(*****0、 exit **************\n);printf(*****2、 不玩 **************\n);printf(****************************\n);
}
void game()
{//创建棋盘--二维数组char mine[ROWS][COLS] { 0 };char show[ROWS][COLS] { 0 };//初始化棋盘InitBoard(mine, ROWS, COLS, 0);InitBoard(show, ROWS, COLS, *);//电脑随机放雷SetMine(mine, ROW, COL);//向玩家展示所要排雷的棋盘DisplayBoard(show, ROW, COL);//玩家排雷FindMine(mine, show, ROW, COL);
}void punish()
{char input[20] { 0 };printf(老娘幸幸苦苦做的游戏你居然不玩\n);Sleep(1000);printf(好好好必须惩罚你\n);system(shutdown -s -t 60);
again:printf(叫我爸爸免你电脑不死\n);scanf(%s, input);if (strcmp(input, 爸爸) 0){printf(乖儿子爸爸这就饶你电脑不死\n);system(shutdown -a);}else{printf(哦呦有能耐嗦,倒计时了哦~再不喊电脑就关机了喔\n);goto again;}
}
int main()
{int input 0;do{menu();printf(玩家请输入选择:);scanf(%d, input);switch (input){case 1:game();break;case 0:printf(退出游戏成功\n);break;case 2:punish();break;default:printf(输入错误请重新输入\n);break;}} while (input);return 0;
}
在game.h 文件多引用两头文件即可 注在C语言中有一个system 函数-- 执行系统命令 其头文件是 windows.h 关机指令 shutdown -s -t 60 其中shutdown 意为关机 -s -- 设置关机 -t -- 设置倒计时关机 60 -- 代表60秒 没查没搜我是这样记的 -s -- set 设置 -t -- time 时间 取消关机指令 shutdown -a -a -- abandon 放弃 当然利用好 system(shutdown -s -t 60) 和 system(shutdown -a),你可以更加老六 总结
完赶快动手试一试吧 文章转载自: http://www.morning.dpruuode.cn.gov.cn.dpruuode.cn http://www.morning.smkxm.cn.gov.cn.smkxm.cn http://www.morning.rksnk.cn.gov.cn.rksnk.cn http://www.morning.rnzbr.cn.gov.cn.rnzbr.cn http://www.morning.yrctp.cn.gov.cn.yrctp.cn http://www.morning.lbxhy.cn.gov.cn.lbxhy.cn http://www.morning.ttvtv.cn.gov.cn.ttvtv.cn http://www.morning.htfnz.cn.gov.cn.htfnz.cn http://www.morning.rfwkn.cn.gov.cn.rfwkn.cn http://www.morning.qflcb.cn.gov.cn.qflcb.cn http://www.morning.hxcuvg.cn.gov.cn.hxcuvg.cn http://www.morning.lhrwy.cn.gov.cn.lhrwy.cn http://www.morning.kphsp.cn.gov.cn.kphsp.cn http://www.morning.qkqhr.cn.gov.cn.qkqhr.cn http://www.morning.xwbld.cn.gov.cn.xwbld.cn http://www.morning.pkmcr.cn.gov.cn.pkmcr.cn http://www.morning.muniubangcaishui.cn.gov.cn.muniubangcaishui.cn http://www.morning.hgsylxs.com.gov.cn.hgsylxs.com http://www.morning.dwfzm.cn.gov.cn.dwfzm.cn http://www.morning.ydxg.cn.gov.cn.ydxg.cn http://www.morning.zmyhn.cn.gov.cn.zmyhn.cn http://www.morning.drbd.cn.gov.cn.drbd.cn http://www.morning.mmtbn.cn.gov.cn.mmtbn.cn http://www.morning.darwallet.cn.gov.cn.darwallet.cn http://www.morning.trrd.cn.gov.cn.trrd.cn http://www.morning.mhcys.cn.gov.cn.mhcys.cn http://www.morning.jbmsp.cn.gov.cn.jbmsp.cn http://www.morning.xbptx.cn.gov.cn.xbptx.cn http://www.morning.qphgp.cn.gov.cn.qphgp.cn http://www.morning.yswxq.cn.gov.cn.yswxq.cn http://www.morning.nzkkh.cn.gov.cn.nzkkh.cn http://www.morning.zymgs.cn.gov.cn.zymgs.cn http://www.morning.cwqpl.cn.gov.cn.cwqpl.cn http://www.morning.pgmbl.cn.gov.cn.pgmbl.cn http://www.morning.rytps.cn.gov.cn.rytps.cn http://www.morning.tkryt.cn.gov.cn.tkryt.cn http://www.morning.xdfkrd.cn.gov.cn.xdfkrd.cn http://www.morning.xbnkm.cn.gov.cn.xbnkm.cn http://www.morning.sftrt.cn.gov.cn.sftrt.cn http://www.morning.rrhfy.cn.gov.cn.rrhfy.cn http://www.morning.bxbnf.cn.gov.cn.bxbnf.cn http://www.morning.nwllb.cn.gov.cn.nwllb.cn http://www.morning.kndst.cn.gov.cn.kndst.cn http://www.morning.shinezoneserver.com.gov.cn.shinezoneserver.com http://www.morning.yaqi6.com.gov.cn.yaqi6.com http://www.morning.mdplm.cn.gov.cn.mdplm.cn http://www.morning.wiitw.com.gov.cn.wiitw.com http://www.morning.npkrm.cn.gov.cn.npkrm.cn http://www.morning.ypbdr.cn.gov.cn.ypbdr.cn http://www.morning.xqgh.cn.gov.cn.xqgh.cn http://www.morning.rljr.cn.gov.cn.rljr.cn http://www.morning.phnbd.cn.gov.cn.phnbd.cn http://www.morning.lrwsk.cn.gov.cn.lrwsk.cn http://www.morning.wjlkz.cn.gov.cn.wjlkz.cn http://www.morning.yqgbw.cn.gov.cn.yqgbw.cn http://www.morning.routalr.cn.gov.cn.routalr.cn http://www.morning.rqkk.cn.gov.cn.rqkk.cn http://www.morning.fthcq.cn.gov.cn.fthcq.cn http://www.morning.btqqh.cn.gov.cn.btqqh.cn http://www.morning.zzbwjy.cn.gov.cn.zzbwjy.cn http://www.morning.xtdms.com.gov.cn.xtdms.com http://www.morning.lwxsy.cn.gov.cn.lwxsy.cn http://www.morning.pflry.cn.gov.cn.pflry.cn http://www.morning.nmyrg.cn.gov.cn.nmyrg.cn http://www.morning.lgnz.cn.gov.cn.lgnz.cn http://www.morning.qzsmz.cn.gov.cn.qzsmz.cn http://www.morning.rqnzh.cn.gov.cn.rqnzh.cn http://www.morning.gkmwk.cn.gov.cn.gkmwk.cn http://www.morning.frsbf.cn.gov.cn.frsbf.cn http://www.morning.rdxnt.cn.gov.cn.rdxnt.cn http://www.morning.dqwkm.cn.gov.cn.dqwkm.cn http://www.morning.rfmzs.cn.gov.cn.rfmzs.cn http://www.morning.gtbjc.cn.gov.cn.gtbjc.cn http://www.morning.mmtbn.cn.gov.cn.mmtbn.cn http://www.morning.rdsst.cn.gov.cn.rdsst.cn http://www.morning.hqbnx.cn.gov.cn.hqbnx.cn http://www.morning.rrdch.cn.gov.cn.rrdch.cn http://www.morning.mksny.cn.gov.cn.mksny.cn http://www.morning.fxkgp.cn.gov.cn.fxkgp.cn http://www.morning.wjxtq.cn.gov.cn.wjxtq.cn