凡科做网站关键词,国内国外重大新闻,深圳专业制作网站技术,深圳设计公司 电话目录
主函数test.c
菜单函数
选择循环
扫雷游戏实现分析
整体思路
问题1
问题2
问题3
问题4
游戏函数#xff08;函数调用#xff09;
创建游戏盘数组mine
创建游戏盘数组show
初始化游戏盘数组InitBoard
展示游戏盘DisplayBoard
游戏盘置雷SetMine
游戏…目录
主函数test.c
菜单函数
选择循环
扫雷游戏实现分析
整体思路
问题1
问题2
问题3
问题4
游戏函数函数调用
创建游戏盘数组mine
创建游戏盘数组show
初始化游戏盘数组InitBoard
展示游戏盘DisplayBoard
游戏盘置雷SetMine
游戏盘排雷FindMine
test.c总代码
头文件函数声明game.h
头文件的包含
游戏符号声明
游戏函数声明
game.h总代码
游戏函数game.c
初始化游戏盘InitBoard
展示游戏盘DisplayBoard
优化1
优化2
游戏盘置雷SetMine
游戏盘排雷FindMine
雷炸死
非雷计算
找完雷
总循环
game.c总代码 今天我们接着来讲扫雷游戏的实现。
主函数test.c
菜单函数
void menu()
{printf(*******************\n);printf(*******Play.1******\n);printf(*******Over.2******\n);printf(*******************\n);
}
选择循环
#define _CRT_SECURE_NO_WARNINGS 1
#includegame.h
void menu()
{printf(*******************\n);printf(*******Play.1******\n);printf(*******Over.2******\n);printf(*******************\n);
}
void game()
{printf(开始扫雷游戏\n);
}
int main()
{int input 0;srand((unsigned int)time(NULL));do{printf(欢迎来到扫雷游戏!\n);menu();printf(请输入您的选择\n);scanf(%d, input);switch (input){case 1:game();break;case 0:printf(游戏结束\n);break;default:printf(输入选择有误请重新选择\n);break;}} while (input);
}
以上代码我们已经写过三遍了相信大家都非常熟悉了不在过多阐述。
扫雷游戏实现分析
整体思路 首先游戏盘9✖9游戏盘上布置了10个雷如果游戏盘的某处坐标不是雷就计算这个位置的周围3✖3的8个坐标有几个雷且显示雷个数如果游戏盘的某处坐标是雷就炸死了显示游戏结束如果把游戏盘上所有非雷的位置全部找出来了显示排雷成功游戏结束。 两个完全贴合的字符数组游戏盘
问题1
我们用字符0表示非雷1表示是雷。 但是格子里还要显示周围3✖3的各自雷的个数数字1与字符1会容易搞混怎么办 所以我们需要两个游戏盘 mine游戏盘。游戏盘初始化为字符0和1。随机循环的布置10个雷的位置。玩家在扫雷的时候计算雷的个数。show游戏盘。游戏盘的展示。游戏盘初始化为字符*。玩家扫雷的时候显示周围3✖3的8个坐标的雷的个数。特别提醒二者必须完全无缝贴合 问题2
刚刚我们提到mine游戏盘是扫雷时计算某个坐标的周围3✖3的8个坐标的雷的个数那如果时周围的坐标该怎么办如果计算已经数组越界了 所以我们要拓展我们的游戏盘我们创建一个11✖11的游戏盘但我们只访问9✖9的游戏盘 特别提醒为了我们的便捷的实现我们的扫雷游戏我们的两个游戏盘必须无缝贴合所以我们的show显示游戏盘也要拓展到11✖11。 问题3
我们扫雷游戏的实现涉及初始化游戏盘的展示等都需要用到循环 那循环条件条件的控制 特别提醒 特别需要注意循环条件数组的下标是从0开始。 初始化数组就是0~10 访问数组就是1~9 问题4
当玩家输入坐标没有输入雷被炸死这时我们需要显示雷的坐标那怎样去计算雷的个数 游戏盘数组mine和show都初始化为字符。现在我们要将字符转化为数字。 根据字符和数字的ASCII码值。我们知道0数值为481数值为49。 所以我们知道 1-01 0-00 所以我们可以将x,y)周围8个字符坐标分别减去0可以得到数字再全加到一起得总数字。 或者我们也可以先将x,y周围8个坐标字符坐标 加到一起再一起减去8*0得到总数字。 游戏函数函数调用
创建游戏盘数组mine
char mine[ROWS][COLS]{0};
创建游戏盘数组show
char show[ROWS][COLS]{0};
初始化游戏盘数组InitBoard
创建一个InitBoard函数去分别初始化两个数组mine和show 初始化内容不一样所以把初始化内容当作参数分别传给函数InitBoard初始化时传参时11✖11为了后面计算游戏盘某坐标 周围8个坐标 里雷的个数
InitBoard(mine, ROWS, COLS, 0);//初始化是11✖11
InitBoard(show, ROWS, COLS, *);
展示游戏盘DisplayBoard
展示游戏盘只需要访问9✖9的游戏盘。
DisplayBoard(mine, ROW, COL);//多余的//访问是9✖9
DisplayBoard(mine, ROW, COL);
游戏盘置雷SetMine
SetMine(mine, ROW, COL);
DisplayBoard(mine, ROW, COL);//多余的
游戏盘排雷FindMine
FindMine(mine, show, ROW, COL);
//传mine数组过去计算雷
//传show数组展示计算雷的结果
test.c总代码
//扫雷游戏的实现
#define _CRT_SECURE_NO_WARNINGS 1
#includegame.h
void menu()
{printf(*******************\n);printf(*******Play.1******\n);printf(*******Over.2******\n);printf(*******************\n);
}
void game()
{printf(开始扫雷游戏\n);char mine[ROWS][COLS] { 0 };char show[ROWS][COLS] { 0 };InitBoard(mine, ROWS, COLS, 0);//InitBoard(show, ROWS, COLS, *);//DisplayBoard(mine, ROW, COL);//多余的//访问是9✖9DisplayBoard(show, ROW, COL);//布置雷SetMine(mine, ROW, COL);//DisplayBoard(mine, ROW, COL);//多余的//排除雷——扫雷FindMine(mine, show, ROW, COL);//传mine数组过去计算雷//传show数组展示计算雷的结果}
int main()
{int input 0;srand((unsigned int)time(NULL));do{printf(欢迎来到扫雷游戏!\n);menu();printf(请输入您的选择\n);scanf(%d, input);switch (input){case 1:game();break;case 0:printf(游戏结束\n);break;default:printf(输入选择有误请重新选择\n);break;}} while (input);
}
头文件函数声明game.h
头文件的包含 在我们写代码的过程中会调用库函数需要包含头文件和声明函数。 所以我们将所有函数声明和头文件放到我们.h 文件中。 当然在其他.c文件需要使用时我们只需要包含 我们创造的 头文件game.h 即可。 //#includegame.h
#includestdio.h
#includetime.h
#includestdlib.h
游戏符号声明
#define ROW 9
#define COL 9
#define ROWS ROW2
#define COLS COL2
#define EASY_COUNT 10
游戏函数声明
void InitBoard(char board[ROWS][COLS],int rows,int cols,char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row,int col);
//不能board重复参数名
game.h总代码
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#includestdio.h
#includestdlib.h
#includetime.h
#define ROW 9
#define COL 9
#define ROWS ROW2
#define COLS COL2
#define EASY_COUNT 10
void InitBoard(char board[ROWS][COLS],int rows,int cols,char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row,int col);
//不能board重复参数名
游戏函数game.c
初始化游戏盘InitBoard
数组下标是从0开始的所以初始化i是0~10
#includegame.h
#define _CRT_SECURE_NO_WARNINGS 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)//i0~10{for (j 0; j cols; j)//j0~10{board[i][j] set;}}
}
展示游戏盘DisplayBoard 数组下标是从0开始所以访问是0~9
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{int i 0;int j 0;for (i 1; i row; i){for (j 1; j col; j){printf(%c , board[i][j]);}printf(\n);}
}
当然我们的mine函数是不会展示的。当玩家输入坐标时还要去数,所以以上代码还能不能优化
优化1
玩家输入坐标时还是几行几列去寻找所以我们选择直接把号码打印出来。
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{int i 0;int j 0;//打印列号for (i 0; i col; i)//i从0开始因为行占用了一格{printf(%d , i);}printf(\n);//打印数字for (i 1; i row; i){printf(%d , i);//打印行号for (j 1; j col; j){printf(%c , board[i][j]);}printf(\n);}
}
优化2
上下文的文字显得眼花缭乱所以我们加上分割线就不会缭乱了。
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{int i 0;int j 0;//打印列号printf(--------------扫雷--------------\n);for (i 0; i col; i){printf(%d , i);}printf(\n);//打印数字for (i 1; i row; i){printf(%d , i);//打印行号for (j 1; j col; j){printf(%c , board[i][j]);}printf(\n);}printf(--------------扫雷--------------\n);
}
优化之后 游戏盘置雷SetMine
关于随机数rand先调用srand随机数rand()%row的范围0~8随机数rand()%row1的范围1~9关于布置雷需要在mine函数里面去实现while循环的次数肯定不止EASY_COUNT
void SetMine(char board[ROWS][COLS], int row, int col)
{//布置雷——循环随机数直到布置完10个雷停止int count EASY_COUNT;while (count)//直到10个雷布置完毕退出循环{int x rand() % row 1;int y rand() % col 1;//产生的坐标就是00~99if (board[x][y] 0)//条件设置不能重复计算已经设置过的地方即为1的地方{board[x][y] 1;count--;}}
} 游戏盘排雷FindMine
雷炸死 坐标为雷就炸死游戏结束
printf(请输入要查找的雷\n);
scanf(%d %d, x, y);
if (x 1 x row y 1 y col)//输入的坐标要合法
{if (mine[x][y] 1)//被炸死的条件{printf(很遗憾你被炸死了\n);DisplayBoard(mine, ROW, COL);break;}
}
else//玩家输入非法坐标重新输入
{printf(坐标非法请重新输入\n);
}
非雷计算 坐标不为雷mine计算雷show展示雷 计算l雷个数的函数GetMineCount
//统计雷的个数
int GetMineCount(char mine[ROWS][COLS], int x, int y)
{return mine[x - 1][y - 1] mine[x - 1][y] mine[x - 1][y 1] mine[x][y - 1] mine[x][y 1] mine[x 1][y - 1] mine[x 1][y] mine[x 1][y 1]-8*0;
}int win0;
if (x 1 x row y 1 y col)
{if{}else//没有被炸死显示雷的个数{//不是雷就统计x,y坐标周围有几个雷int c GetMineCount(mine, x, y);show[x][y] c 0;//数字0字符数字放置到字符数组里去DisplayBoard(show, ROW, COL);//展示字符数字——雷的个数每排查一次都要显示雷的个数win;//每排查一次雷雷的个数减少一次距离循环结束一次}
}
else//玩家输入非法坐标重新输入
{printf(坐标非法请重新输入\n);
}
找完雷 坐标找完雷游戏结束
//炸死和排排完雷都跳出循环
if (win row * col - EASY_COUNT)//设置条件只有排完雷才通关
{printf(恭喜你排雷成功游戏通关\n);DisplayBoard(mine, ROW, COL);
}
总循环
int GetMineCount(char mine[ROWS][COLS], int x, int y)
{return mine[x - 1][y - 1] mine[x - 1][y] mine[x - 1][y 1] mine[x][y - 1] mine[x][y 1] mine[x 1][y - 1] mine[x 1][y] mine[x 1][y 1]-8*0;
}void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x 0;int y 0;int win 0;while (winrow*col-EASY_COUNT){printf(请输入要查找的雷\n);scanf(%d %d, x, y);if (x 1 x row y 1 y col)//输入的坐标要合法{if (mine[x][y] 1)//被炸死的条件{printf(很遗憾你被炸死了\n);DisplayBoard(mine, ROW, COL);break;}else//没有被炸死显示雷的个数{//不是雷就统计x,y坐标周围有几个雷int c GetMineCount(mine, x, y);show[x][y] c 0;//数字0字符数字放置到字符数组里去DisplayBoard(show, ROW, COL);//展示字符数字——雷的个数//每排查一次都要显示雷的个数win;//每排查一次雷雷的个数减少一次距离循环结束一次}}else//玩家输入非法坐标重新输入{printf(坐标非法请重新输入\n);}}//炸死和排排完雷都跳出循环if (win row * col - EASY_COUNT)//设置条件只有排完雷才通关{printf(恭喜你排雷成功游戏通关\n);DisplayBoard(mine, ROW, COL);}
}
game.c总代码
#includegame.h
#define _CRT_SECURE_NO_WARNINGS 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)//i0~10{for (j 0; j cols; j)//j0~10{board[i][j] set;}}
}
//分别传两个数组初始化自己想要初始化的字符void DisplayBoard(char board[ROWS][COLS], int row, int col)
{int i 0;int j 0;//打印列号printf(--------------扫雷--------------\n);for (i 0; i col; i){printf(%d , i);}printf(\n);//打印数字for (i 1; i row; i){printf(%d , i);//打印行号for (j 1; j col; j){printf(%c , board[i][j]);}printf(\n);}printf(--------------扫雷--------------\n);
}void SetMine(char board[ROWS][COLS], int row, int col)
{//布置雷——循环随机数直到布置完10个雷停止int count EASY_COUNT;while (count)//直到10个雷布置完毕退出循环{int x rand() % row 1;int y rand() % col 1;//产生的坐标就是00~99if (board[x][y] 0)//条件设置不能重复计算已经设置过的地方即为1的地方{board[x][y] 1;count--;}}
}
int GetMineCount(char mine[ROWS][COLS], int x, int y)
{return mine[x - 1][y - 1] mine[x - 1][y] mine[x - 1][y 1] mine[x][y - 1] mine[x][y 1] mine[x 1][y - 1] mine[x 1][y] mine[x 1][y 1]-8*0;
}void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x 0;int y 0;int win 0;while (winrow*col-EASY_COUNT){printf(请输入要查找的雷\n);scanf(%d %d, x, y);if (x 1 x row y 1 y col)//输入的坐标要合法{if (mine[x][y] 1)//被炸死的条件{printf(很遗憾你被炸死了\n);DisplayBoard(mine, ROW, COL);break;}else//没有被炸死显示雷的个数{//不是雷就统计x,y坐标周围有几个雷int c GetMineCount(mine, x, y);show[x][y] c 0;//数字0字符数字放置到字符数组里去DisplayBoard(show, ROW, COL);//展示字符数字——雷的个数//每排查一次都要显示雷的个数win;//每排查一次雷雷的个数减少一次距离循环结束一次}}else//玩家输入非法坐标重新输入{printf(坐标非法请重新输入\n);}}//炸死和排排完雷都跳出循环if (win row * col - EASY_COUNT)//设置条件只有排完雷才通关{printf(恭喜你排雷成功游戏通关\n);DisplayBoard(mine, ROW, COL);}
} ✔✔✔✔✔最后感谢大家的阅读后续可能会函数递归优化若有错误和不足欢迎指正
迎来新的学期希望大家继续坚持在每天敲代码的路上。学习的小伙伴
代码---------→【gitee:https://gitee.com/TSQXG】
联系---------→【邮箱2784139418qq.com】