十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
目录
成都创新互联公司专注为客户提供全方位的互联网综合服务,包含不限于成都网站制作、网站建设、通江网络推广、小程序设计、通江网络营销、通江企业策划、通江品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们大的嘉奖;成都创新互联公司为所有大学生创业者提供通江建站搭建服务,24小时服务热线:18982081108,官方网址:www.cdcxhl.com前言
一,游戏构思
二,游戏实现
2.1 游戏框架
2.2 game.h头文件
2.3 game()的实现
2.4 每个函数的实现
2.5 周围雷的数目(around_num)
三,游戏总代码
这次我们练习一个扫雷小游戏,这次涉及的知识主要是二维数组(当然如果对数组不熟悉的话可以看我之前写的有关数组的文章)扫雷游戏相信我们大家都很熟悉吧,多练习这样的小游戏,小项目都有助于提高我们的代码能力。话不多说,先来张美图,直接开始!
一,游戏构思我们需要两个棋盘,一个用来存放雷,一个向我们展示雷的数量。每个棋盘我们可以用二数维组实现,也就是需要两个二维数组。这个游戏我们还分为三个文件,test.c里放游戏框架,game.c里放函数的实现过程,game.h里放头文件和函数声明。游戏效果如下:
二,游戏实现 2.1 游戏框架游戏框架我们还是采用之前的do while 结构,再加上switch分支语句。菜单我们用printf打印实现,代码如下
//test.c文件里
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h" //把#include放在game.h中
void menu()
{
printf("************************************************\n");
printf("********************** 1.play ******************\n");
printf("********************** 0.exit ******************\n");
printf("************************************************\n");
}
int main()
{
int input = 0;
do
{
menu(); //菜单
printf("请选择:\n");
scanf("%d", &input);
switch (input)
{
case 1:
game(); //游戏实现放在这这函数里
break;
case 0:
break;
default:
printf("选择错误,重新选择\n");
}
} while (input);
return 0;
}
2.2 game.h头文件我们创建一个头文件,将所用到的库函数和全局变量放在里面,这个扫雷的棋盘的大小我们用9*9,但是创建的时候我们得用11*11。因为我们扫雷游戏时输入坐标后,如果那个坐标不是雷,它会进行一个周围坐标的计算,如果输入的坐标是棋盘最外面的一圈,它会越界访问。所以我们创建11*11,但打印的时候我们可以打印成9*9(最外圈不打印)。创建一个全局变量row用来表示行,col用来表示列,用#define将row,col定义为9,ROW,COL定义为11。用mine_num表示雷的数量,暂且为10个雷。用头文件创建全局变量还有一个实用的好处,就是想改变行和列和累的数量时可以直接在game.h头文件中改。代码如下:
//game.h
#define _CRT_SECURE_NO_WARNINGS 1
//row 行
//col 列
#include#define row 9 //row = 9
#define col 9 //col = 9
#define ROW row+2 //ROW = row + 2 = 11
#define COL col+2 //COL = 11
#define mine_num 10 //雷的数量
2.3 game()的实现将游戏的主要实现过程放在game()中,这里面我们首先创建两个二维数组,一个用来防雷(mine),一个用来展示(show)。然后我们再初始化(init_board)这两个数组,数组mine我们把它全部初始化为0,在mine中放置雷的时候,我们用字符 '1' 表示雷,这样到时候利用加法方便计算雷的数量,数组show我们全部初始化为 ‘ * ’,到时候输入坐标的位置用mine计算出的数字代替 ‘ * ’。接下来我们在mine中放置雷(set_mine),做完这一切后我们就开始排雷,(函数的具体实现在下面讲)最将排雷的实现放在clear_mine中,代码如下:
//test.c
void game()
{
char show[ROW][COL] = { 0 }; //show 展示的棋盘
char mine[ROW][COL] = { 0 }; //mine 放雷的棋盘
init_board(show, ROW, COL, '*'); //初始化棋盘show
init_board(mine, ROW, COL, '0'); //初始化棋盘mine
set_mine(mine,ROW,COL,mine_num); //放置雷
clear_mine(show,mine,ROW,COL); //排雷
}
2.4 每个函数的实现我们把每个游戏过程的函数放在game.c中讲,我们先把函数一一在game.h头文件中进行声明,然后在game.c中也包含game.c中,这样就能将game.c和test.c里建立联系。
//game.h
#define _CRT_SECURE_NO_WARNINGS 1
//row 行
//col 列
#include#define row 9
#define col 9
#define ROW row+2
#define COL col+2
#define mine_num 10
void init_board(char board[ROW][COL], int rows, int cols, char ret); //初始化函数
void prin_board(char board[ROW][COL], int rows, int cols); //打印函数
void set_mine(char board[ROW][COL], int rows, int cols, int num); //随机放置雷的函数
void clear_mine(char show[ROW][COL], char mine[ROW][COL], int rows, int cols);//扫雷的函数
我们先实现初始化函数init_board。用两个for循环将数组一一赋值。代码如下:
//game.c
void init_board(char board[ROW][COL], int rows, int cols, char ret) //初始化棋盘
{
int i = 0;
for (i = 0; i< rows; i++)
{
int j = 0;
for (j = 0; j< cols; j++)
{
board[i][j] = ret;
}
}
}
接着实现打印函数prin_board。这里先将列数打印出来,然后用两个for打印棋盘,在第一个for中先打印行的数字,然后打印这一行的棋盘。代码如下:
//game.c
void prin_board(char board[ROW][COL], int rows, int cols) //打印棋盘
{
int i = 0;
printf("----------扫雷———————\n");
for (i = 0; i< cols + 1; i++) //打印列数0,1,2,3...
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i<= rows; i++) //只把11*11棋盘中间的9*9打印出来,因为要把雷随机放在这中间9*9中
{
int j = 0;
printf("%d ", i); //打印行数1,2,3...
for (j = 1; j<= cols; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("----------扫雷———————-\n");
}
效果如下:
接着我们实现放雷的函数set_mine,这里因为需要随机放置雷的数量,所以需要随机函数rand(),随机的起点我们用上时间戳放在test.c中的main中,时间戳所需要的库函数
代码如下:
//game.c
void set_mine(char board[ROW][COL], int rows, int cols, int num) //放雷
{
while (num)
{
int x = rand() % 9 + 1; //随机坐标1 - 9,最外层不放雷,这样计算周围一圈雷不会数组越界
int y = rand() % 9 + 1; //rand()得到的值余9+1可以得到1—9的数
if (board[x][y] == '0')
{
board[x][y] = '1'; //在mine棋盘中 雷 用 ‘1’表示,方便计算周围雷的数量
num--;
}
}
}
最后是排雷函数clear_mine,我们用while循环,如果没踩到雷,需要循环展现的棋盘数量减去雷的数量(9*9 - 10),然后打印棋盘,输入排雷的坐标,然后用两个if语句进行坐标筛选,是否合法?是否没被排过?如果坐标都满足,进入最后一个if进行判断坐标是否为雷,如果为雷,游戏结束,跳出循环,如果非雷,将坐标周围雷的数量(around_num)替换掉那个坐标的 ‘ * ’(赋值在show[i][j])代码如下:
//game.h
void clear_mine(char show[ROW][COL], char mine[ROW][COL], int rows, int cols) //扫雷
{
int input = row*col - mine_num; //如果每次都没踩到雷,需要排9*9-10个坐标。
while (input)
{
int i = 0;
int j = 0;
prin_board(show, row, col); //打印棋盘
printf("请输入坐标:\n"); //输入排雷的坐标
scanf("%d %d", &i, &j);
if (i >0 && i<= 9 && j >0 && j<= 9) //坐标的范围必须在1到9(包含9和1)之间
{
if (show[i][j] == '*')
{
if (mine[i][j] == '0')
{
show[i][j] = around_num(mine, i, j) + '0'; //周围雷的数量赋值到所选的坐标中
prin_board(show, row, col);
input--;
}
else
{
prin_board(mine, row, col);
printf("很遗憾,你被炸死了\n");
break;
}
}
else
{
printf("该坐标已排过雷,请重新输入\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
int i = 0;
while ((i = getchar()) != '\n') //清楚缓存区
{
;
}
}
}
}
这里面的
show[i][j] = around_num(mine, i, j) + '0'; //周围雷的数量赋值到所选的坐标中
around_num返回值是 int 型,所以加上字符 ‘ 0 ’,在赋值给char型棋盘show中,它也随之转化为char型。
2.5 周围雷的数目(around_num)实现过程如下:
//game.c
static int around_num(char board[ROW][COL], int i, int j) //周围雷的数目
{
return (board[i - 1][j - 1] + board[i - 1][j] + board[i - 1][j + 1] + board[i][j - 1] + board[i][j + 1] + board[i + 1][j - 1] + board[i + 1][j] + board[i + 1][j + 1] - 8 * '0');
}
该函数实现过程是将输入坐标周围一圈的字符 ‘ 1 ’相加(正如前面所讲的mine棋盘初始化为字符 ‘ 0 ’,雷用 字符‘ 1 ’表示,这也是用 ‘1’表示雷的好处,方便计算),然后作为函数的返回值。
这里static作用是将around_num变为静态函数,静态函数只能在声明它的文件可见,其他文件不能引用该函数。意思是该函数只有在game.c可用,其他文件不可用。
around_num返回值是 int 型,因为数组board为char型,所以要减去字符‘ 0 ’(由ASCII表可以看出字符任意数字减去字符0的值为十进制的该任意字符的值),总共有8个char值,最后要减去8个字符‘0’。
三,游戏总代码//test.c代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
printf("************************************************\n");
printf("********************** 1.play ******************\n");
printf("********************** 0.exit ******************\n");
printf("************************************************\n");
}
void game()
{
char show[ROW][COL] = { 0 }; //show 展示的棋盘
char mine[ROW][COL] = { 0 }; //mine 放雷的棋盘
init_board(show, ROW, COL, '*'); //初始化棋盘
init_board(mine, ROW, COL, '0');
set_mine(mine,ROW,COL,mine_num); //放雷
clear_mine(show,mine,ROW,COL); //扫雷
}
int main()
{
int input = 0;
srand((unsigned)time(NULL)); //随机值的起点
do
{
menu(); //游戏菜单
printf("请选择:\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
break;
default:
printf("选择错误,重新选择\n");
}
} while (input);
return 0;
}
//game.h代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
//row 行
//col 列
#include#include#define row 9
#define col 9
#define ROW row+2
#define COL col+2
#define mine_num 10
void init_board(char board[ROW][COL], int rows, int cols, char ret);
void prin_board(char board[ROW][COL], int rows, int cols);
void set_mine(char board[ROW][COL], int rows, int cols, int num);
void clear_mine(char show[ROW][COL], char mine[ROW][COL], int rows, int cols);
//game.c代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
static int around_num(char board[ROW][COL], int i, int j) //周围雷的数目
{
return (board[i - 1][j - 1] + board[i - 1][j] + board[i - 1][j + 1] + board[i][j - 1] + board[i][j + 1] + board[i + 1][j - 1] +
board[i + 1][j] + board[i + 1][j + 1] - 8 * '0');
}
void init_board(char board[ROW][COL], int rows, int cols, char ret) //初始化棋盘
{
int i = 0;
for (i = 0; i< rows; i++)
{
int j = 0;
for (j = 0; j< cols; j++)
{
board[i][j] = ret;
}
}
}
void prin_board(char board[ROW][COL], int rows, int cols) //打印棋盘
{
int i = 0;
printf("----------扫雷———————\n");
for (i = 0; i< cols + 1; i++) //打印列数
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i<= rows; i++) //只把11*11棋盘中间的9*9打印出来,因为要把雷随机放在这中间9*9中
{
int j = 0;
printf("%d ", i); //打印行数
for (j = 1; j<= cols; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("----------扫雷———————-\n");
}
void set_mine(char board[ROW][COL], int rows, int cols, int num) //放雷
{
while (num)
{
int x = rand() % 9 + 1; //随机坐标1 - 9,最外层不放雷,这样计算周围一圈雷不会数组越界
int y = rand() % 9 + 1;
if (board[x][y] == '0')
{
board[x][y] = '1'; //在mine棋盘中 雷 用 ‘1’表示,方便计算周围雷的数量
num--;
}
}
}
void clear_mine(char show[ROW][COL], char mine[ROW][COL], int rows, int cols) //扫雷
{
int input = row*col - mine_num;
while (input)
{
int i = 0;
int j = 0;
prin_board(show, row, col); //打印棋盘
printf("请输入坐标:\n");
scanf("%d %d", &i, &j);
if (i >0 && i<= 9 && j >0 && j<= 9)
{
if (show[i][j] == '*')
{
if (mine[i][j] == '0')
{
show[i][j] = around_num(mine, i, j) + '0'; //周围雷的数量赋值到所选的坐标中
prin_board(show, row, col);
input--;
}
else
{
prin_board(mine, row, col);
printf("很遗憾,你被炸死了\n");
break;
}
}
else
{
printf("该坐标已排过雷,请重新输入\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
int i = 0;
while ((i = getchar()) != '\n') //清楚缓存区
{
;
}
}
}
}
如果不方便的话,源码还可以在gitee中获取:csdn-game3 · 雨天code/1 - 码云 - 开源中国 (gitee.com)
好了,到这里就结束了,如果对你有帮助,不如留个足迹再走。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧