扫雷C语言(具体步骤和代码)

目录

一、扫雷游戏介绍

 二、代码实现思路

 三、步骤

1.菜单界面

2.初始化棋盘

4.打印棋盘

5.排查雷

5.排查空

四、代码实现

一、扫雷游戏介绍

 二、代码实现思路

1.菜单界面选择开始或者退出游戏。
2.创建棋盘并布雷。
3.打印棋盘。
4.玩家扫雷(玩家输入行列坐标的方式来扫雷)。
5.不是雷游戏继续,是雷游戏结束。
6.重复步骤 4 5

 三、步骤

1.菜单界面

        1.play 玩游戏       0.exit 退出游戏

void menu()
{
	printf("##########################\n");
	printf("#######   1. play   ######\n");
	printf("#######   0. exit   ######\n");
	printf("##########################\n");
}

2.初始化棋盘

棋盘:使用row行col列的二维数组来表示,元素类型是char。
使用宏定义的原因:提高扩展性,如果将来要修改棋盘尺寸,代码修改会很方便。

void InitBoard(char board[ROWS][COLS], int rows, int  cols, char set)//初始化棋盘 
{
	for (int i = 0; i < rows; ++i)
	{
		for (int j = 0; j < cols; ++j)
		{
			board[i][j] = set;
		}
	}
}

4.打印棋盘

void DisplayBoard(char board[ROWS][COLS], int row, int  col)//打印棋盘 
{
	printf("---------扫雷游戏----------\n");
	//打印第一行 行数字 
	printf("   ");
	for (int i = 1; i <= row; ++i)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 1; i <= row; ++i)
	{
		printf("%d: ", i);//打印列号 

		for (int j = 1; j <= col; ++j)//打印每行元素 
		{
			if (board[i][j] == '0')  printf("  ");//如果这个地方周围没有雷,则打印空格
			else  printf("%c ", board[i][j]);
			if (board[i][j] == '*')  win++;
			//最后扫雷成功的时候如果棋盘上的*和雷数量相等则可判断获胜
		}
		printf("\n");
	}
	printf("---------扫雷游戏----------\n");
}

5.排查雷

void FindBoard(char mine[ROWS][COLS], char show[ROWS][COLS], char newmine[ROWS][COLS], int row, int col)
{//排查雷
	int x = 0, y = 0;
	while (1)
	{
		printf("请输入要排查的坐标:>");
		scanf_s("%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//不为雷,则打印该格数字并且延申棋盘
			{
				int flag = 1;
				MakeBoard(mine, show, newmine, x, y, row, col, 1);
				DisplayBoard(show, ROW, COL);//打印展示用棋盘
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
			break;
		}
		if (win == EASY_COUNT)//判断胜负
		{
			printf("你赢了\n");
			DisplayBoard(mine, ROW, COL);
		}
		else//重新赋值win
		{
			win = 0;
		}
	}
}

5.排查空

void MakeBoard(char mine[ROWS][COLS], char show[ROWS][COLS], char newmine[ROWS][COLS], int x, int y, int row, int col, int flag)
{
	show[x][y] = GetMine(mine, x, y) + '0';//给该坐标赋值,周围雷的个数 
	newmine[x][y] = '6';//更改复制的棋盘,防止后续错误
	if (GetMine(mine, x, y) != 0)//如果这个位置周围没有雷,则将flag变为0,
		flag = 0;
	if (flag != 0)
	{//flag为0则不会继续延申//判断空格周围
		if (x > 1 && newmine[x - 1][y] == '0')
			MakeBoard(mine, show, newmine, x - 1, y, row, col, flag);
		if (x < row && newmine[x + 1][y] == '0')
			MakeBoard(mine, show, newmine, x + 1, y, row, col, flag);
		if (y < col && newmine[x][y + 1] == '0')
			MakeBoard(mine, show, newmine, x, y + 1, row, col, flag);
		if (y > 1 && newmine[x][y - 1] == '0')
			MakeBoard(mine, show, newmine, x, y - 1, row, col, flag);
	}
}

四、代码实现

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//棋盘大小
#define ROW 9
#define COL 9
//防止越界访问用
#define ROWS ROW+2
#define COLS COL+2
//雷的数量
#define EASY_COUNT 10
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int  cols, char set);
//打印棋盘,用q变量判断打印0的时候是正常打印还是打印空格
void DisplayBoard(char board[ROWS][COLS], int row, int  col);
//布置雷
void SetMine(char board[ROWS][COLS], int row, int  col);
//排查雷
void FindBoard(char mine[ROWS][COLS], char show[ROWS][COLS], char newmine[ROWS][COLS], int row, int col);
//找对应坐标附近有几个雷
int  GetMine(char mine[ROWS][COLS], int x, int y);
//判断周围有多少雷
//因为要延申打印,并且第一次碰到非空非雷时仍然打印,这里用flag判断,
void MakeBoard(char mine[ROWS][COLS], char show[ROWS][COLS], char newmine[ROWS][COLS], int x, int y, int row, int col, int flag);
//复制棋盘
void CopyBoard(char mine[ROWS][COLS], char newmine[ROWS][COLS], int row, int col);

void menu()
{
	printf("##########################\n");
	printf("#######   1. play   ######\n");
	printf("#######   0. exit   ######\n");
	printf("##########################\n");
}
void game()
{
	char mine[ROWS][COLS] = { 0 };//存放雷的信息
	char newmine[ROWS][COLS] = { 0 };//用于对于周围没有雷的打印
	char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息
	//初始化棋盘
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');
	//布置雷
	SetMine(mine, ROW, COL);
	CopyBoard(mine, newmine, ROWS, COLS);
	DisplayBoard(show, ROW, COL);
	//搜查雷
	FindBoard(mine, show, newmine, ROW, COL);
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));//设置随机值
	do
	{
		menu();
		printf("请选择:>");
		scanf_s("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}
int win = 0;//设置全局变量用于i判断输赢
void InitBoard(char board[ROWS][COLS], int rows, int  cols, 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("   ");
	for (int i = 1; i <= row; ++i)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 1; i <= row; ++i)
	{
		printf("%d: ", i);//打印列号 

		for (int j = 1; j <= col; ++j)//打印每行元素 
		{
			if (board[i][j] == '0')  printf("  ");//如果这个地方周围没有雷,则打印空格
			else  printf("%c ", board[i][j]);
			if (board[i][j] == '*')  win++;
			//最后扫雷成功的时候如果棋盘上的*和雷数量相等则可判断获胜
		}
		printf("\n");
	}
	printf("---------扫雷游戏----------\n");
}

void SetMine(char board[ROWS][COLS], int row, int  col)//布置雷 
{
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;//生成随机下标
		int y = rand() % col + 1;
		if (board[x][y] != '1')
		{
			board[x][y] = '1';//1代表雷
			count--;
		}
	}
}

int  GetMine(char mine[ROWS][COLS], int x, int y)//判断该坐标周围有几个雷
{
	//如果是雷则为字符'1',累计数量再减去8*‘0’则可得到周围雷的数量
	return (mine[x - 1][y] + mine[x - 1][y - 1] +
		mine[x][y - 1] + mine[x + 1][y - 1] +
		mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] +
		mine[x - 1][y + 1] - 8 * '0');
}

void CopyBoard(char mine[ROWS][COLS], char newmine[ROWS][COLS], int row, int col)
{//复制棋盘
	for (int i = 0; i < row; ++i)
		for (int j = 0; j < col; ++j)
			newmine[i][j] = mine[i][j];
}

void FindBoard(char mine[ROWS][COLS], char show[ROWS][COLS], char newmine[ROWS][COLS], int row, int col)
{//排查雷
	int x = 0, y = 0;
	while (1)
	{
		printf("请输入要排查的坐标:>");
		scanf_s("%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//不为雷,则打印该格数字并且延申棋盘
			{
				int flag = 1;
				MakeBoard(mine, show, newmine, x, y, row, col, 1);
				DisplayBoard(show, ROW, COL);//打印展示用棋盘
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
			break;
		}
		if (win == EASY_COUNT)//判断胜负
		{
			printf("你赢了\n");
			DisplayBoard(mine, ROW, COL);
		}
		else//重新赋值win
		{
			win = 0;
		}
	}
}

//排查空(递归) 
void MakeBoard(char mine[ROWS][COLS], char show[ROWS][COLS], char newmine[ROWS][COLS], int x, int y, int row, int col, int flag)
{
	show[x][y] = GetMine(mine, x, y) + '0';//给该坐标赋值,周围雷的个数 
	newmine[x][y] = '6';//更改复制的棋盘,防止后续错误
	if (GetMine(mine, x, y) != 0)//如果这个位置周围没有雷,则将flag变为0,
		flag = 0;
	if (flag != 0)
	{//flag为0则不会继续延申//判断空格周围
		if (x > 1 && newmine[x - 1][y] == '0')
			MakeBoard(mine, show, newmine, x - 1, y, row, col, flag);
		if (x < row && newmine[x + 1][y] == '0')
			MakeBoard(mine, show, newmine, x + 1, y, row, col, flag);
		if (y < col && newmine[x][y + 1] == '0')
			MakeBoard(mine, show, newmine, x, y + 1, row, col, flag);
		if (y > 1 && newmine[x][y - 1] == '0')
			MakeBoard(mine, show, newmine, x, y - 1, row, col, flag);
	}
}

以上就是关于扫雷全部解析啦。如果对你有帮助,记得点赞👍+关注哦!
我的主页还有其他文章,欢迎学习指点。
关注我,让我们一起学习,一起成长吧!  

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值