C语言简单实现扫雷

首先还是先来看一下效果

棋盘中的格子用“*”表示,字符1表示地雷,玩家输入坐标,如果是地雷,提示玩家失败并显示地雷在格子的分布,如果不是地雷,此格显示数字,数字表示周围的地雷的个数

同井字棋游戏一样,扫雷依旧是分三个文件game.h声明函数,game.c实现函数功能,test.c测试

目录

1.创建开始菜单

2.打印棋盘

2.1建立棋盘

2.2棋盘初始化

2.3放地雷

2.4打印棋盘

 3.判断输赢


1.创建开始菜单

逻辑和上一篇的井字棋相同便不再过多阐述,代码如下:

//test.c代码
void menu()
{
	printf("++++++++++++++++++\n");
	printf("+     1.play     +\n");
	printf("+     0.exit     +\n");
	printf("++++++++++++++++++\n");
	printf("请输入:\n");
}
void test()

{
	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:printf("START\n"); game(); break;
		case 0:printf("END\n"); break;
		default:printf("输入错误\n"); break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

 我们的重点依旧是game函数的实现

2.打印棋盘

2.1建立棋盘

棋盘依旧是用二维数组来建立,但在初始化棋盘之前我们需要思考要建立多大的棋盘

游戏中的棋盘大小为10*10的大小,那么char board[10][10]?

但这个大小在后续函数功能实现的时候会很麻烦,如图:

 如果边界处的坐标元素不是地雷,那么它就要显示周围的地雷的个数,函数会访问周围8个坐标元素,但显然边界周围的元素不足8个,这就会造成越界访问,那么函数就要添加判断条件坐标是否处于边界,处于边界后又是不是处于四个角落中,这样工作量又增加了

索性在建立棋盘的时候在实际棋盘大小周围再加一圈大小,即12*12。在使用时只使用中间的棋盘,这样写函数时也就不需要写过多的判断条件了

在建立棋盘的时候创建两个数组mine和show,功能如下:

 代码:

//game.h文件代码
#include<stdio.h>
#define ROW 10
#define COL 10
#define ROWS ROW+2
#define COLS COL+2

game函数代码
void game()
{
    char mine[ROWS][ROWS] = { 0 };
	char show[ROWS][COLS] = { 0 };
}

2.2棋盘初始化

创建函数init,棋盘mine初始化成字符“0”,show初始化成“*”,那函数返回值类型应该为char,参数有数组名、行数、列数以及想要设置的字符,实现逻辑依旧是嵌套的for循环

//game.h文件代码
void init(char board[ROWS][COLS], int rows, int cols, char set);


//game.c文件代码
void init(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0, j = 0;
	for ( i = 0; i < rows; ++i)
	{
		for ( j = 0; j < cols; ++j)
		{
			board[i][j] = set;
		}
	}
}

//test.c代码
void game()
{
    char mine[ROWS][ROWS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	init(mine, ROWS,COLS,'0');
	init(show, ROWS,COLS,'*');
}

2.3放地雷

创建函数set_mine,需要确定放置地雷的个数,且地雷都需要放置mine中心的10*10大小内,地雷的位置需随机放置

//game.h
void set_mine(char mine[ROWS][COLS], int row, int col,int number);//注意这里是row和col,和定义的ROW和COL对应,二者的值为10

因为地雷位置需随机放置,那么就又要使用rand(),在使用之前依旧是要设置srand()

//game.c
void set_mine(char mine[ROWS][COLS], int row, int col, int number)
{
	
	int i = number;
	while (i)
	{
		int x = rand() % row + 1;//因为是12*12大小使用中间的10*10大小作为棋盘
		int y = rand() % col + 1;//所以值需要从1开始,从0开始地雷就放置在棋盘外了
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			i--;
		}
	}
}
//test函数中do...while循环外添加  srand((unsigned int)time(NULL));
//在game.h中引用头文件<stdlib.g>和<time.h>

2.4打印棋盘

需要打印的是数组show中间的10*10大小的元素,使用时注意参数

//game.h
void set_mine(char mine[ROWS][COLS], int row, int col,int number);

//game.c
void display(char board[ROWS][COLS], int row, int col)
{
	for (int i = 1; i <=row; ++i)
	{
		for (int j = 1; j <=col; ++j)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

 3.判断输赢

创建函数find_mine,玩家输入坐标,如果该坐标藏有地雷,提示玩家失败,显示地雷分布后结束游戏,否则显示该坐标周围的地雷的个数,当棋盘除地雷之外的所有位置都被玩家找出来后提示玩家获胜

建立棋盘时创建了两个数组,所以find_mine参数也需要两个数组

//game.h
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

那么在坐标元素不是地雷时如何显示周围地雷个数?

我们用“1”来表示地雷,“0”表示没有,那么周围的数字加起来就正好是地雷的个数,但“1”和“0”都是字符型数据,所以需要在后面-‘0’使其变成int型数据,之后显示时+'0'改回字符

//game.c
int mine_count(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 find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0, y = 0;
	printf("输入坐标\n");
	scanf("%d%d", &x, &y);
	int count = 0;
	while (count < row * col - NUMBER)
	{
		if (mine[x][y] == '1')
		{
			printf("you lose\n");
			display(mine, ROW, COL);
			break;
		}
		else
		{
			int n = mine_count(mine, x, y);
			show[x][y] = n + '0';//函数返回类型为int,+'0'改为字符型
			count++;
			display(show, ROW, COL);
		}
	}
	if (count == row * col - NUMBER)
	{
		printf("you win\n");
		display(mine, ROW, COL);
	}
		
}

到这扫雷的代码基本上完成了,感谢观看,完

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星鸦wyk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值