目录
首先我们需要为扫雷游戏写个主函数,这样我们的代码才能跑起来,方便测试
然后,重头戏来啦,我们要实现game函数了
初始化数组
打印棋盘
按照顺序的话,我们现在应该实现设置雷这个项目了
那么现在,到了最激动人心的时刻啦,终于要开始排雷啦
学习了C语言,总想动手写点什么,扫雷就听不错,那么现在来实现扫雷
我们在主函数中需要实现什么功能呢?
我们要先打印菜单,所以需要在主函数中使用menu函数,然后玩家选择是否玩游戏,这时候,我们需要用到switch语句,在语句中使用game函数,所以有了如下代码:
int main()
{
int input = 0;
do
{
menu();//打印菜单
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1://玩游戏
printf("玩游戏\n");
game();
break;
case 0://退出
printf("退出\n");
break;
default:
printf("输入错误,请重新输入\n");
}
} while (input);//判断是否循环
return 0;
}
menu函数非常简单,只需要用到printf,代码如下:
void menu()
{
printf("***************************************\n");
printf("*************** 1. play **************\n");
printf("*************** 0. exit **************\n");
printf("***************************************\n");
}
现在,我们需要考虑一下,我们具体该怎么实现这个游戏啦。首先,我们实现行列分别为ROW、COL的扫雷棋盘,我们知道,当排除雷的时候,如果该位置没有雷,就显示周围雷的数量之和,所以我们需要应用行列分别为ROW+2,COL+2的二维数组,为了方便,我们定义ROWS为ROW+2,COLS为COL+2,并且,我们需要两个数组,一个用来存放放置雷的信息,另一个用来存放排除雷的信息,我们创建如下数组:
char mine[ROWS][COLS] = { 0 };//存放布置的雷的信息
char show[ROWS][COLS] = { 0 };//存放排除的雷的信息
所以现在,我们的需求是把两个数组分别初始化,讲show数组初始化为*,*更为神秘一点,mine数组内部是存放放置雷的信息的,所以我们用0表示没有雷,用1表示有雷,所以实现初始化数组的代码如下:
void InitBoard(char board[ROWS][COLS], int row, int col, char set)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = set;
}
}
}
初始化完成以后,我们需要打印一下棋盘,来看看我们初始化是否成功,并且,在游戏过程中,我们需要多次打印棋盘内容,因此,分装一个Display函数是有必要的,在打印棋盘的时候,我们最好顺便打印一下行号和列号
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
printf("-------扫雷游戏-------\n");
int i = 0;
int j = 0;
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");
}
那么我们应该怎么设置雷呢,显而易见,用随机数是最好的方式,这时候,我们就会用到rand和srand函数,srand函数是用来设置起点的,那么只需要使用一次,那我们把他放在main函数中是最合适的,所以main函数应该调整为
int main()
{
srand((unsigned int)time(NULL));//设置随机数起点
int input = 0;
do
{
menu();
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:
printf("玩游戏\n");
game();
break;
case 0:
printf("退出\n");
break;
default:
printf("输入错误,请重新输入\n");
}
} while (input);
return 0;
}
设置雷函数代码如下:
void SetMine(char board[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int count = EASY;
while (count)
{
x = rand() % row + 1;
y = rand() % col + 1;
if (x > 0 && x < ROWS && y>0 && y < COLS)
{
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
}
排雷需要排很多次,所以我们要用到循环,在循环内实现排雷才行。这个逻辑也很好理解,在此就不过多赘述了,直接上代码
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int count = 0;
int win = 0;
while (win < row * col - EASY)
{
printf("请输入要排查的坐标:>");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] != '*')
{
printf("该坐标已经被排查过啦!\n");
}
else
{
if (mine[x][y] == '1')
{
printf("很遗憾,被炸死了\n");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
win++;
count = get_mine_count(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
}
}
}
else
{
printf("输入坐标错误,请重新输入\n");
}
}
if (win == row * col - EASY)
{
printf("恭喜你,你赢了\n");
DisplayBoard(mine, ROW, COL);
}
}
如果仔细阅读我的代码,就会发现,这段代码里有一个函数,还没有实现,但是通过他的名字应该能猜出这个函数是干嘛的。对,就是用来实现显示周围雷的个数的。
那么我们如何显示出周围有多少雷呢?记得前面我们用0表示没有放置雷,用1来表示已经放置雷了,那么我们把这8个位置的内容相加不就得到了雷的个数啦,但是注意,我们初始化和设置雷的时候,用的是字符0和字符1,所以相加后返回的整数是很大的,因为返回的是ASCLL码值,所以我们需要减去8*‘0’;代码实现如下:
int get_mine_count(char board[ROWS][COLS], int x, int y)
{
return board[x - 1][y - 1] +
board[x][y - 1] +
board[x + 1][y - 1] +
board[x - 1][y] +
board[x + 1][y] +
board[x - 1][y + 1] +
board[x][y + 1] +
board[x + 1][y + 1] - 8 * '0';
}
到此为止,扫雷的基本版就算是完成啦。
扫雷小游戏基础版 · Gascsd/LitterGame - 码云 - 开源中国 (gitee.com)https://gitee.com/gascsd/litter-game/tree/master/%E6%89%AB%E9%9B%B7%E5%B0%8F%E6%B8%B8%E6%88%8F%E5%9F%BA%E7%A1%80%E7%89%88