可以连片展开的扫雷小游戏(可以同过宏定义改变扫雷的棋盘大小和雷的个数)

这个扫雷游戏最大的两个成功之处是

一可以宏定义更改ROW和COL以及EASY_COUNT的值,ROW和COL是扫雷棋盘的行和列大小,而EASY_COUNT修改的是雷的总个数

二可以实现一整片区域都没有雷的时候成片展开如下图:
可以连片展开的扫雷小游戏(可以同过宏定义改变扫雷的棋盘大小和雷的个数)_第1张图片
输入2 4坐标以(2 ,4)坐标处及周围没有雷便连片展开

InitBoard //初始化扫雷的棋盘全部初始化为字符’0’
SetMine //随机设置雷(用了srand函数以时间戳为srand函数的参数作为随机数种子的起点得到的随机值模上行和列便可得随机的行和列)
DisplayBoard //打印扫雷棋盘
FindMine //用户输入坐标,程序判断是否为雷,并在内部调用RecursionSpread函数(递归的方式)连片展开没有雷的地方,没有雷即用CountMine函数数出用户输入坐标周围8个格子中雷的个数放在给用户展示的格子中

在这#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 
#include 

#define ROW 12
#define COL 12

#define ROWS ROW+2
#define COLS COL+2

#define EASY_COUNT 30 //雷的总个数

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col, char set);
int FindMine(char board[ROWS][COLS], char show[ROWS][COLS], int x, int y);



void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)  //存放雷的信息的字符数组全部初始化为字符'0',表示没有雷
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = '0';
		}
	}

}

void DisplayBoard(char board[ROWS][COLS], int rows, int cols)//游戏失败时打印雷的布局
{
	int i = 0;
	int j = 0;
	printf("\n");
	for (i = 0; i < cols - 1; i++)
		printf("%2d", i);
	printf("\n");
	for (i = 1; i < rows - 1; i++)
	{
		printf("%2d ", i);
		for (j = 1; j < cols - 1; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

void SetMine(char board[ROWS][COLS], int rows, int cols, char set) //随机设置雷的布局,EASY_COUNT表示雷的总数
{
	int count = 0;
	int x = 0;
	int y = 0;
	while (count < EASY_COUNT)
	{
		do
		{
			x = rand() % (rows - 2) + 1;
			y = rand() % (cols - 2) + 1;
		} while (board[x][y] != '0');
		board[x][y] = set;
		count++;
	}
}

static int CountMine(char board[ROWS][COLS], int x, int y) //数出当前用户输入坐标周围8个坐标中的雷的总个数
{
	return
		board[x - 1][y - 1] +
		board[x - 1][y] +
		board[x - 1][y + 1] +
		board[x][y - 1] +
		board[x][y + 1] +
		board[x + 1][y - 1] +
		board[x + 1][y] +
		board[x + 1][y + 1] -
		8 * '0';
}
static void RecursionSpread(char board[ROWS][COLS], char show[ROWS][COLS], int x, int y) //以递归的方式展开
{
	if ((x >= 0) && (x <= ROW) && (y >= 0) && (y <= COL))
	{
		if (CountMine(board, x, y) == 0)
		{
			show[x][y] = ' ';
			if (show[x - 1][y - 1] == '*')
			{
				RecursionSpread(board, show, x - 1, y - 1);
			}
			if (show[x - 1][y] == '*')
			{
				RecursionSpread(board, show, x - 1, y);
			}
			if (show[x - 1][y + 1] == '*')
			{
				RecursionSpread(board, show, x - 1, y + 1);
			}
			if (show[x][y - 1] == '*')
			{
				RecursionSpread(board, show, x, y - 1);
			}
			if (show[x][y + 1] == '*')
			{
				RecursionSpread(board, show, x, y + 1);
			}
			if (show[x + 1][y - 1] == '*')
			{
				RecursionSpread(board, show, x + 1, y - 1);
			}
			if (show[x + 1][y] == '*')
			{
				RecursionSpread(board, show, x + 1, y);
			}
			if (show[x + 1][y + 1] == '*')
			{
				RecursionSpread(board, show, x + 1, y + 1);
			}
			
		}
		else
		{
			show[x][y] = CountMine(board, x, y)+ '0';
		}
	}
}

int FindMine(char board[ROWS][COLS], char show[ROWS][COLS], int x, int y)  //判断用户输入的坐标所在是不是有雷,有雷则返回0游戏结束,没有雷则展开并打印每个格子周围的雷的个数
{
	if (show[x][y] != '*')
		printf("此坐标处已排查过\n");
	else
	{
		if (board[x][y] == '1')
		{
			printf("游戏结束,您被炸死了\n");
			return 0;
		}
		else
		{
			//show[x - 1][y - 1] = CountMine(board, x, y) + '0';
			RecursionSpread(board, show, x, y); //递归展开

		}
	}
	return 1;
}


static void menu()
{
	printf("*****************\n");
	printf("**** 1.Play  ****\n");
	printf("****  0.Exit ****\n");
	printf("*****************\n");
	printf("请输入对应数字的选择:>\n");
}

void Initshow(char show[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			show[i][j] = set;
		}
	}
}

static void game(char show[ROWS][COLS], char board[ROWS][COLS], int rows, int cols)
{
	InitBoard(board, ROWS, COLS, '0');
	SetMine(board, ROWS, COLS, '1');//随机放置好雷
	//DisplayBoard(board, ROWS, COLS);

	int x = 0;
	int y = 0;
	int flag = 1;
	DisplayBoard(show, ROWS, COLS);

	do
	{
		printf("请输入要扫雷的坐标 :>\n");
		(void)scanf("%d%d", &x, &y);

		flag = FindMine(board, show, x, y);
		DisplayBoard(show, rows, cols);

	} while (flag);
	//游戏失败时
	//打印雷
	if (flag == 0)
		DisplayBoard(board, ROWS, COLS);

}

int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	char board[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	Initshow(show, ROWS, COLS, '*');
	//DisplayShow(show, ROWS, COLS);

	do
	{
		menu();
		(void)scanf("%d", &input);
		switch (input)
		{
		case 0:
			break;
		case 1:
			game(show, board, ROWS, COLS);
			break;
		default:
			break;
		}

	} while (input);
	return 0;
}里插入代码片

你可能感兴趣的:(C)