【游戏】C语言实现扫雷游戏(超详细备注和解释)
C语言实现扫雷游戏
求个赞求个赞求个赞求个赞 谢谢🙏
先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力 看完之后别忘记关注我哦!️️️
思路
首先,我们需要理清楚思路,我们创建三个.c源文件
game.h用来存放游戏的函数声明和一些头文件引用和一些常量的定义
game.c用来实现游戏里面的函数
test.c用来存放游戏整体思路和main函数。*
建议收藏后食用~
首先:
我们先编写一个选择菜单函数menu(),如果要进行游戏,选择1,退出游戏,选择0,同时,定义一个int input来接受
然后,游戏必须在一个循环里面,在循环里面,我们可以使用switch/case语句来执行我们的input,如果case 0:我们直接break,如果case1:我们进行游戏game(),default,我们重新选择。
void menu()
{
printf("************************\n");
printf("***********1.play*******\n");
printf("***********0.exit*******\n");
printf("************************\n");
}
int main()
{
int input = 0;
do
{
srand((unsigned int)time(NULL));
menu();
printf("please enter your input:\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("exit the game!!!!\n");
break;
default:
printf("err,please input again:\n");
break;
}
} while (input);
return 0;
}
接下来,最重要的,我们要开始写我们的game()函数。
游戏函数game()函数实现详解
定义两个二维数组
在实现游戏的时候,我们必须定义两个二维数组,一个是用来存放雷的信息,一个是用来展示给玩家看的
于此同时,我们的游戏是99的,但是,我们定义二维数组的时候要定义1111的,因为我们在后面排查雷的时候,边边角角的位置的排查,找一圈,如果不定义多一行,我们为了在访问数组的时候不越界访问导致程序崩溃,我们必须定义多一行。
#define ROWS 11
#define COLS 11
#define ROW ROWS-2
#define COL COLS-2
#define MINE 10//定义雷的个数
数组的初始化
//雷数组
char mine[ROWS][COLS] = { 0 };
//展示数组
char show[ROWS][COLS] = { 0 };
//初始化
Initboard(mine, ROWS, COLS, '0');
Initboard(show, ROWS, COLS, '*');
我们可以规定,在存放雷的信息的数组mine里面,我们规定,‘1’代表有雷,‘0’代表无雷
我们可以规定,在展示数组show里面,我们规定,还没排查的位置展示" * "
当然,我们使用for循环来初始化数组
头文件:
//初始化数组
void Initboard(char board[ROWS][COLS], int rows, int cols, char ch);
void Initboard(char board[ROWS][COLS], int rows, int cols, char ch)
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = ch;//把ch传过来,我们就可以一个函数两用了
}
}
}
在传参的时候,我们,必须也把我们要初始化的字符也传过去,这样的话,我们写一个Initboard函数就可以完成两个数组的初始化了。
打印数组函数
紧接着,我们当然是需要一个函数来把我们的数组打印一下,展示给玩家看
此处注意,show数组才需要打印,mine数组是不能给玩家看的,给玩家看了还得了
但是,我们在写程序的时候可以打印出来看看,看看自己有没有写好
//打印数组
//Displayboard(mine, ROW, COL);
Displayboard(show, ROW, COL);
//打印
void Displayboard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf("--------game-------\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("--------game-------\n");
}
此处注意,我们不只是需要打印那些*,我们还需要行号和列号,具体请看代码,不懂的伙伴可以私信留言
打印出来是这样的:
布置雷函数
接下来,我们需要布置雷,我们在game.h头文件里面已经定义了雷的个数是10个(当然我们可以改)
//布置
Setmine(mine, ROW, COL);
//Displayboard(mine, ROW, COL);
//当然,我们设置完雷,我们可以打印出来看看打印好没有
此时,我们需要rand函数,来随机生成坐标,我们rand的种子用srand函数,其中,我们把种子定义成时间,这样我们才能随机生成,而且每次打开游戏生成的位置不一样
srand((unsigned int)time(NULL));
注意,这个语句只需要执行一次,因此,我们放在main()函数里面,dowhile循环外面即可
//布置
void Setmine(char board[ROWS][COLS], int row, int col)
{
int count = 0;
while (1)
{
int x = rand() % row + 1;//这里的模然后加一可以控制生成x的范围控制在1<=x<=row这个范围内,有疑问的伙伴可以给我留言。
int y = rand() % col + 1;
if (board[x][y] == '0')//先判断这个坐标有雷没有,没有,才埋雷,如果有了,重新生成。
{
board[x][y] = '1';
count++;//计算已设置雷的个数
}
if (count == MINE)//如果搞够十个了,就break;
break;
}
}
设置完雷后我们可以打印出来看一下,看完记得屏蔽代码,别让玩家看到
排查雷函数
接下来,玩家就要开始操作了
//排查
Findmine(show, mine, ROW, COL);
//排查
static int get_mine(char mine[ROWS][COLS], int x, int y)
{
return mine[x][y - 1] + mine[x][y + 1] +
mine[x - 1][y - 1] + mine[x - 1][y] +
mine[x - 1][y + 1] + mine[x + 1][y] +
mine[x + 1][y - 1] + mine[x + 1][y + 1] - 8 * '0';//字符转整型
}
void Findmine(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int count = 0;
while (count<row*col-MINE)
{
printf("please input the location you want to search:\n");
scanf_s("%d %d", &x,&y);
//判断坐标合法性
if (x >= 1 && x <= 9 && y <= 9 && y >= 1)
{
if (mine[x][y]=='1')
{
Displayboard(mine, row, col);
printf("Your LOSE the GAME!!\n");
//输掉的时候,打印一下雷的数组给玩家看看
break;
}
else
{
int ret = get_mine(mine, x, y);//把坐标传过去,计算附近到底有多少个雷
//如果没有被炸死,计算附近雷的个数,并打印出来
show[x][y] = ret + '0';//整型转字符
Displayboard(show, row, col);//打印排查信息给玩家看
count++;//计算已排查坐标个数
}
}
else//如果玩家输入了不在范围内的坐标,重新输入
{
printf("err,please input again\n");
}
}
if (count == row * col - MINE)//判断是否赢,赢了才打印,输的情况跳出来是不用打印的
{
printf("YOU WIN!!!\n");
Displayboard(mine, row, col);
}
}
实现以下函数,用来计算玩家输入坐标xy附近的雷个数
static int get_mine(char mine[ROWS][COLS], int x, int y)
整体代码展示
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"game.h"
#include<time.h>
void game()
{
//雷数组
char mine[ROWS][COLS] = { 0 };
//展示数组
char show[ROWS][COLS] = { 0 };
//初始化
Initboard(mine, ROWS, COLS, '0');
Initboard(show, ROWS, COLS, '*');
//打印数组
//Displayboard(mine, ROW, COL);
Displayboard(show, ROW, COL);
//布置
Setmine(mine, ROW, COL);
//Displayboard(mine, ROW, COL);
//排查
Findmine(show, mine, ROW, COL);
}
void menu()
{
printf("*****************************\n");
printf("***********1.play************\n");
printf("***********0.exit************\n");
printf("*****************************\n");
}
int main()
{
int input = 0;
do
{
srand((unsigned int)time(NULL));
menu();
printf("please enter your input:\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("exit the game!!!!\n");
break;
default:
printf("err,please input again:\n");
break;
}
} while (input);
return 0;
}
game.h
#pragma once
#define ROWS 11
#define COLS 11
#define ROW ROWS-2
#define COL COLS-2
#define MINE 10
//初始化数组
void Initboard(char board[ROWS][COLS], int rows, int cols, char ch);
//打印
void Displayboard(char board[ROWS][COLS], int row, int col);
//布置
void Setmine(char board[ROWS][COLS], int row, int col);
//排查
void Findmine(char show[ROWS][COLS], char mine[ROWS][COLS], int rows, int cols);
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
#include<stdio.h>
//初始化棋盘
void Initboard(char board[ROWS][COLS], int rows, int cols, char ch)
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = ch;//把ch传过来,我们就可以一个函数两用了
}
}
}
//打印函数
void Displayboard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf("--------game-------\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("--------game-------\n");
}
//布置雷函数
void Setmine(char board[ROWS][COLS], int row, int col)
{
int count = 0;
while (1)
{
int x = rand() % row + 1;//这里的模然后加一可以控制生成x的范围控制在1<=x<=row这个范围内,有疑问的伙伴可以给我留言。
int y = rand() % col + 1;
if (board[x][y] == '0')//先判断这个坐标有雷没有,没有,才埋雷,如果有了,重新生成。
{
board[x][y] = '1';
count++;//计算已设置雷的个数
}
if (count == MINE)//如果搞够十个了,就break;
break;
}
}
//排查雷函数
static int get_mine(char mine[ROWS][COLS], int x, int y)//计算(x,y)坐标附近雷的总数
{
return mine[x][y - 1] + mine[x][y + 1] +
mine[x - 1][y - 1] + mine[x - 1][y] +
mine[x - 1][y + 1] + mine[x + 1][y] +
mine[x + 1][y - 1] + mine[x + 1][y + 1] - 8 * '0';//字符转整型
}
void Findmine(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int count = 0;
while (count < row * col - MINE)
{
printf("please input the location you want to search:\n");
scanf_s("%d %d", &x, &y);
//判断坐标合法性
if (x >= 1 && x <= 9 && y <= 9 && y >= 1)
{
if (mine[x][y] == '1')
{
Displayboard(mine, row, col);
printf("Your LOSE the GAME!!\n");
//输掉的时候,打印一下雷的数组给玩家看看
break;
}
else
{
int ret = get_mine(mine, x, y);
//如果没有被炸死,计算附近雷的个数,并打印出来
show[x][y] = ret + '0';//整型转字符
Displayboard(show, row, col);//打印排查信息给玩家看
count++;//计算已排查坐标个数
}
}
else//如果玩家输入了不在范围内的坐标,重新输入
{
printf("err,please input again\n");
}
}
if (count == row * col - MINE)//赢了才打印you win,否则不打印
{
printf("YOU WIN!!!\n");
Displayboard(mine, row, col);
}
}
尾声
以上就是本期博客的全部内容了,谢谢各位的耐心观看,如果对这个小游戏还有什么问题的话,可以在评论区留言哦!在划走之前点个赞支持下吧!!