电子商务网站系统规划 案例分析,做黑网站赚钱,做动漫短视频网站,建设一个微信小说网站说起扫雷游戏#xff0c;这应该是很多人童年的回忆吧#xff0c;中小学电脑课最常玩的必有扫雷游戏#xff0c;那么大家知道它是如何开发出来的吗#xff0c;扫雷游戏背后的原理是什么呢#xff1f;今天就让我们一探究竟#xff01;
扫雷游戏介绍
如下图#xff0c;简…说起扫雷游戏这应该是很多人童年的回忆吧中小学电脑课最常玩的必有扫雷游戏那么大家知道它是如何开发出来的吗扫雷游戏背后的原理是什么呢今天就让我们一探究竟
扫雷游戏介绍
如下图简单版本的扫雷游戏就是在一个9*9的方格阵中埋藏了10颗地雷而玩家就是根据这个方阵的反馈进行10颗地雷位置的排查。 具体的游戏规则如下玩家随机选择一个位置如果选取位置不是雷则显示数字。对于边缘的数字则显示图中数字周围临近的5个方格中含有的地雷个数例如下图红色圈起来的数字2则说明红框之中必有两个地雷即黑色×处。再看绿色框出来的数字2它处于方格阵的中间位置则看它周围临近的8个方格含有2个地雷也是黑色×处。 玩家可以根据数字的提示筛选出10颗雷的位置最终获得游戏胜利。反之如果不幸选取到雷(即踩雷)则游戏失败。 扫雷游戏设计方案
1. 创建两个两个二维数组一个作为埋雷地图另一个作为玩家视角的排雷视图。 2. 设计一个9*9的扫雷游戏但为了防止在统计坐标周围雷的个数的时候越界设定数组的大小为11*11。 3. 数组均为字符数组. 4. 此次游戏实现同样采用多文件的形式设计。 test.c —— 测试游戏功能是否完好的代码 game.c —— 实现游戏逻辑的核心代码 game.h —— 游戏变量及函数的声明
扫雷游戏具体实现
一game.h文件
#pragma once#includestdio.h
#includestdlib.h
#includetime.h#define ROW 9
#define COL 9#define ROWS 11
#define COLS 11#define EASY_MODEL 10void InitGame(char board[ROWS][COLS], int row, int col, char set);//初始化棋盘
void DisPlayBoard(char board[ROWS][COLS], int row, int col);//展示棋盘
void InitMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//初始化地雷
void StartGame(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
int GetMine(char mine[ROWS][COLS], int row, int col);
//int SearchMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int x, int y,int count);
void SearchMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y, int* num);二test.c文件
1.main函数 在实现游戏功能的时候一般都是在main函数中写出大体的框架当遇到需要实现一些功能时我们再去设计函数完成对应功能。 这里设定游戏可以玩多局即当游戏结束是不用退出可以继续选择是否进行下一局游戏所以这里使用循环。同时在第一局开始前询问玩家是否开始游戏则采用do....while()循环。 这里设置一个菜单来提醒玩家是否进行游戏。同时玩家选择1时表示开始游戏选择0时表示游戏结束退出程序选择其他时要提示玩家输入非法并重新进行选择所以这里需要一个switch选择语句。同时设置随机种子方便每次开始扫雷游戏时地雷都能随机位置。
int main()
{int input 0;srand((unsigned int)(time(NULL)));//设置随机种子do {menu();scanf(%d, input);switch (input){default:printf(输入错误嗷请重新输入\n);break;case 1:printf(扫雷游戏启动....\n);game();break;case 0:printf(扫雷游戏结束咯....\n);break;}} while (input);return 0;
}
2.menu函数
void menu()
{printf(**************************\n);printf(******** 1. play *******\n);printf(******** 0. exit *******\n);printf(**************************\n);
}
3.game函数
当玩家开始玩游戏时game函数就是用来实现游戏整体框架并调用其他实现具体功能的函数具体代码如下。
void game()
{char mine[ROWS][COLS]; //埋雷地图char show[ROWS][COLS]; //玩家窗口InitGame(mine, ROW, COL, 0);InitGame(show, ROW, COL, *);//初始化棋盘InitMine(mine, show, ROW, COL);//埋雷DisPlayBoard(show, ROW, COL);StartGame(mine, show, ROW, COL);}
其中mine数组时用来存储埋雷信息show数组是用来存放排查出雷的信息。首先将mine数组的内容全都初始化为字符0show数组将内容初始化为*表示此时位置还未被排雷。初始化棋盘后开始埋雷将雷设置为1具体后面会说。mine数组的视图仅在程序开发时给程序员看方便进行游戏调试。当正式游戏时mine数组应该不给玩家看。 三 game.c文件
1.InitGame函数初始化棋盘
此为初始化棋盘函数由于需要确保函数的通用性并且考虑到有一个mine视图和一个show视图需要同时初始化而这两个视图初始化的内容也不同所以设定一个set参数每次调用函数的时候可以设置不同的初始化内容。
void InitGame(char board[ROWS][COLS], int row, int col, char set)
{for (int i 0; i ROWS; i){for (int j 0; j COLS; j){board[i][j] set;}}
}
2.DisPlayBoard函数显示棋盘
在实现DisPlayBoard函数时不仅仅需要把数组内容给打印出来还要考虑到玩家在玩游戏时输入地雷坐标方便需要将整个方阵的横纵坐标给显示出来便于玩家判断。同时还要提示玩家此局游戏中一共埋藏了多少颗雷。而雷的个数我们用一个全局变量EASY_COUNT来代替这样也方便后续修改雷的个数。打印代码具体如下
void DisPlayBoard(char board[ROWS][COLS], int row, int col)
{printf(------------------------------\n);printf(本场游戏一共有%d颗地雷\n, EASY_MODEL);for (int i 0; i col; i){printf(%d , i);//输出列号}printf(\n);for (int i 1; i row; i){printf(%d , i);//输出行号for (int j 1; j col; j){printf(%c , board[i][j]);}printf(\n);}printf(\n);
}
3.InitMine函数埋雷 本游戏设计10个雷即EASY_MODEL的值设置为10。test.c的main函数中设计了随机种子让雷的位置是随机的。使用rand函数来随机生成雷的位置的坐标同时需要保证10颗雷的位置不能重复。因此采用while循环如果成功布置雷就将count-1直至count的值为0时结束循环。 最后我们将放置雷的位置上的信息改为字符1而非雷的位置信息依旧为字符0(即修改mine数组中对应位置的内容)修改为1是为了方便后续统计一个坐标周围的8个位置中有多少颗雷。需要注意的是由于数组的下标是从0开始而玩家所看到的方格的坐标是从1开始因此我们在随机生成的雷的坐标中需要对xy进行1操作。代码如下
void InitMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{//初始化雷区int mine_num EASY_MODEL;while (mine_num){int x rand() % row 1;int y rand() % col 1;if (mine[x][y] 0){mine[x][y] 1;mine_num--;}}
}
4.GetMine函数统计方格四周雷的个数 统计一个坐标为xy位置周围雷的个数就是统计其周围8个位置的内容有多少个字符1。其余8个位置的坐标如下图 由于字符1和字符0的差距就是1所以我们统计八个位置的累计地雷数就是减8个字符0的ASCII值即可具体代码如下
int GetMine(char mine[ROWS][COLS], int x, int y)
{return mine[x - 1][y] mine[x 1][y] mine[x][y 1] mine[x][y - 1] mine[x - 1][y - 1] mine[x 1][y 1] mine[x - 1][y 1] mine[x 1][y - 1] - 8 * 0;
}
5.StartGame函数开始扫雷游戏排查雷 如果玩家未将所有雷排查完则需要继续排查因此必然需要一个循环且当排查的个数总数 - 雷的个数时循环结束。 每次需要判断玩家输入的雷坐标是否合法不合法则需重新输入合法才继续判断。需要判断两个条件。1当前位置是否为雷是雷则直接结束游戏。2若当前位置非雷但是排查过了需要提示玩家并重新输入排雷位置。3只有当前位置非雷并且排查过才可以。需要注意的是输入的非法坐标不计入排查的次数中。具体代码如下本代码实现了大片排雷
void StartGame(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x, y;int num EASY_MODEL;int count 0;while (count row * col - num){printf(请输入你要扫雷的坐标);scanf(%d %d, x, y);if (x 1 x row y 1 y col){if (mine[x][y] 0 show[x][y] ! *){printf(刚才排除此地咯请重新输入坐标\n);}else if (mine[x][y] 1){printf(你被炸了游戏结束\n);break;}else{//count;SearchMine(mine,show,row,col,x,y,count);//count SearchMine(mine, show, row, col, x, y, count);DisPlayBoard(show, 9, 9);}}else{printf(你输入的坐标不对嗷请重新输入\n);}}if (count row * col - num) {printf(恭喜你获胜啦\n);}
}6.SearchMine函数排查雷实现大片扫雷
使用GetMine函数获取周围8个坐标中雷的数量
1如果是0即周围8个坐标没有雷那么就将中间设置为空白在棋盘范围内对该八个坐标再次进行SearchMine(递归)递归时排除已经是空格的坐标防止陷入死循环。直至遇到一个坐标其范围为内有雷。
2如果不是零将该坐标设置为雷的数量注意是字符类型
void SearchMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y, int* num)
{if (x 1 || x row || y 1 || y col) return;//坐标不合法直接不继续(*num);//num变量传的是排查雷个数变量的位置*num是取出该变量位置上的具体值char tmp GetMine(mine, x, y) 0;//查看当前位置有几个地雷if (tmp 0){show[x][y] ;for (int i -1; i 1; i){for (int j -1; j 1; j){int nx x i;int ny y j;if (show[nx][ny] *) {SearchMine(mine, show, row, col, nx, ny, num);}}}}else{show[x][y] tmp;//return;}
}
实现效果 完整代码
1.test.c
#define _CRT_SECURE_NO_WARNINGS 1#include game.hvoid menu()
{printf(**************************\n);printf(******** 1. play *******\n);printf(******** 0. exit *******\n);printf(**************************\n);
}void game()
{char mine[ROWS][COLS]; //埋雷地图char show[ROWS][COLS]; //玩家窗口InitGame(mine, ROW, COL, 0);InitGame(show, ROW, COL, *);//初始化棋盘InitMine(mine, show, ROW, COL);//埋雷DisPlayBoard(mine, ROW, COL);DisPlayBoard(show, ROW, COL);StartGame(mine, show, ROW, COL);}int main()
{int input 0;srand((unsigned int)(time(NULL)));do {menu();scanf(%d, input);switch (input){default:printf(输入错误嗷请重新输入\n);break;case 1:printf(扫雷游戏启动....\n);game();break;case 0:printf(扫雷游戏结束咯....\n);break;}} while (input);return 0;
} 2.geme.h
#pragma once#includestdio.h
#includestdlib.h
#includetime.h#define ROW 9
#define COL 9#define ROWS 11
#define COLS 11#define EASY_MODEL 10void InitGame(char board[ROWS][COLS], int row, int col, char set);
void DisPlayBoard(char board[ROWS][COLS], int row, int col);
void InitMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
void StartGame(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
int GetMine(char mine[ROWS][COLS], int row, int col);
//int SearchMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int x, int y,int count);
void SearchMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y, int* num);3.game.c
#define _CRT_SECURE_NO_WARNINGS 1#include game.hvoid InitGame(char board[ROWS][COLS], int row, int col, char set)
{for (int i 0; i ROWS; i){for (int j 0; j COLS; j){board[i][j] set;}}
}void DisPlayBoard(char board[ROWS][COLS], int row, int col)
{printf(------------------------------\n);printf(本场游戏一共有%d颗地雷\n, EASY_MODEL);for (int i 0; i col; i){printf(%d , i);//输出列号}printf(\n);for (int i 1; i row; i){printf(%d , i);//输出行号for (int j 1; j col; j){printf(%c , board[i][j]);}printf(\n);}printf(\n);
}void InitMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{//初始化雷区int mine_num EASY_MODEL;while (mine_num){int x rand() % row 1;int y rand() % col 1;if (mine[x][y] 0){mine[x][y] 1;//show[x][y] #;mine_num--;}}
}int GetMine(char mine[ROWS][COLS], int x, int y)
{return mine[x - 1][y] mine[x 1][y] mine[x][y 1] mine[x][y - 1] mine[x - 1][y - 1] mine[x 1][y 1] mine[x - 1][y 1] mine[x 1][y - 1] - 8 * 0;
}void SearchMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y, int* num)
{if (x 1 || x row || y 1 || y col) return;(*num);char tmp GetMine(mine, x, y) 0;if (tmp 0){show[x][y] ;for (int i -1; i 1; i){for (int j -1; j 1; j){int nx x i;int ny y j;if (show[nx][ny] *) {SearchMine(mine, show, row, col, nx, ny, num);}}}}else{show[x][y] tmp;//return;}
}//int SearchMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y, int count)
//{
// if (x 1 || x row || y 1 || y col || show[x][y] ! *)
// return count;
//
// int tmp GetMine(mine, x, y);
// count;
// show[x][y] tmp 0;
//
// if (tmp 0)
// {
// for (int i -1; i 1; i)
// {
// for (int j -1; j 1; j)
// {
// int nx x i;
// int ny y j;
// if (nx 1 nx row ny 1 ny col)
// {
// count SearchMine(mine, show, row, col, nx, ny, count);
// }
// }
// }
// }
//
// return count;
//}void StartGame(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x, y;int num EASY_MODEL;int count 0;//排查的雷个数while (count row * col - num){printf(请输入你要扫雷的坐标);scanf(%d %d, x, y);if (x 1 x row y 1 y col){if (mine[x][y] 0 show[x][y] ! *){printf(刚才排除此地咯请重新输入坐标\n);}else if (mine[x][y] 1){printf(你被炸了游戏结束\n);break;}else{//count;SearchMine(mine,show,row,col,x,y,count);//count SearchMine(mine, show, row, col, x, y, count);DisPlayBoard(show, 9, 9);}}else{printf(你输入的坐标不对嗷请重新输入\n);}}if (count row * col - num) {printf(恭喜你获胜啦\n);}
}总结
程序开发整体上不是流程和逻辑还是比较容易实现的难点在于实现大片扫雷的功能。大片扫雷功能主要是递归的实现容易使程序崩溃还需多多练习递归实现。附上程序运行部分效果图