C语言小游戏扫雷【简单实现】

文章目录

  • 前言
  • 实现目标
  • 实现步骤
    • 打印菜单
    • 初始化棋盘
    • 布置雷
    • 打印棋盘
    • 判断是否继续游戏
    • 计算附近的雷的个数
    • 递归展开【重难点】
    • 判断是否扫雷成功
  • 源代码

前言

扫雷游戏就是在一个棋盘内放置一定的雷数,玩家可以不断地排除雷来实现扫雷,如果附近没有雷的话就可以排除附近一片附近没有雷的棋子,如果碰到雷了游戏就失败了,如果棋盘只剩下雷的话排雷就成功了。

如果没有玩过扫雷的话可以点击这里体验一下:扫雷

实现目标

最终实现的样式如下(可以根据自身需要进一步加以改进):

扫雷视屏演示

实现步骤

打印菜单

提供选项供玩家选择,是开始游戏还是退出游戏

void menu(void)
{
	printf("***********************\n");
	printf("***** 1、开始游戏 *****\n");
	printf("***** 0、退出游戏 *****\n");
	printf("***********************\n");
}

初始化棋盘

在布置棋盘的时候,我们需要创建两个棋盘也就是二维数组,因为我们在进行扫雷的时候需要将雷隐藏起来,不能让玩家看到,而且不能将雷的位置改变,所以我们创建两个棋盘,一个用来存放雷的位置(简称雷盘),一个用来展示。我们就可以根据雷盘的信息来打印棋盘。首先需要初始化棋盘将雷盘全部初始化为字符‘0’,将棋盘全部初始化为‘*’。

void init_board(char board[ROWS][COLS], int row, int col, char ch)  //ch用来控制棋子的样式
{  
	for (int i = 0; i < row; i++)    
	{
		for (int j = 0; j < col; j++)
		{
			board[i][j] = ch;    //将二维数组里的全部元素都初始化为
		}
	}
}

布置雷

布置雷的时候需要使用随机数函数rand来实现雷的随机布置,在使用rand函数之前又需要调用函数srand,使用srand 的时候又需要使用时间戳函数time。这跟三子棋中电脑下棋是一样的。

void init_mine(char board[ROWS][COLS], int row, int col)
{
	int count = COUNT_MINE;		//自定义雷数
	do {
		int x = (rand() % 9) + 1;		//控制雷的生成位置
		int y = (rand() % 9) + 1;		
		if (board[x][y] == '0')			//判断当前位置是否为雷,如果是不是雷的话就布置雷
		{
			board[x][y] = '1';
			count--;
		}
	} while (count);
}

打印棋盘

将棋盘全部打印出来中间可以使用一些符号隔开来,方便区分行和列。这一步在每一次下扫雷后都需要进行一次

void print(char board[ROWS][COLS], int row, int col)
{
	for (int i = 0; i <= ROW; i++) 		//打印列数
	{
		printf("%d   ", i);
	}
	printf("\n");
	printf("————————————————————\n");		//行与行之间的分割
	for (int i = 1; i <= row; i++)
	{
		printf("%d ", i);				//打印列数
		for (int j = 1; j <= col; j++)
		{
			printf("| %c ", board[i][j]);		//列与列之间的分割
		}
		putchar('|');
		printf("\n");
		printf("————————————————————\n");
	}
}

判断是否继续游戏

如果当前位置为雷,就立马结束游戏。

char is_continue(char board[ROWS][COLS], int row, int col)
{
	if (board[row][col] == '1')		//判断当前位置是否为雷
		return '1';
	else
		return '0';
}

计算附近的雷的个数

如果当前位置不是雷就显示附近的雷数。

char count_mine(char board[ROWS][COLS], int row, int col)
{
	char count = '0';
	for (int i = row - 1; i <= row + 1; i++)
	{
		for (int j = col - 1; j <= col + 1; j++)
		{
			if (board[i][j] == '1')		//判断当前位置是不是雷
				count++;		//计数
		}
	}
	return count;
}

递归展开【重难点】

如果当前位置没有雷并且其附近的位置也没有雷,就可以使用递归展开这些位置。在递归的时候需要注意:不能超过棋盘的边界,并且这个位置不可以是雷,递归的时候需要首先判断这两个条件,满足这两个条件之后再进行递归。

void spread_board(char put_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col)
{
	if (row == 0 || col == 0 || row > ROW || col > COL) 	//判断有没有超过边界
		return;
	if (show_board[row][col] != '*') 		//判断当前位置是不是雷
		return;
	char count = count_mine(put_board, row, col);	  //计算当前位置附近的雷数
	show_board[row][col] = count;		//展开
	if (count == '0')
	{
		for (int i = row - 1; i <= row + 1; i++)
		{
			for (int j = col - 1; j <= col + 1; j++)
			{
					spread_board(put_board, show_board, i, j);	 //递归展开
			}
		}
	}
}

判断是否扫雷成功

要是棋盘上面的没有被排查的个数大于雷数,那就继续游戏,如果等于雷数,那就扫雷成功了!!!(这一步也同样可以用来验证代码的正确性)所以这时候只需要遍历棋盘并计算没有没有被排查的个数就可以了。

int is_discion(char board[ROWS][COLS], int row, int col)
{
	int count = 0;
	for (int i = 1; i <= row; i++)
	{
		for (int j = 1; j <= col; j++)
		{
			if (board[i][j] == '*')			//判断当前位置有没有被排查
			{
				count++;			//计数
			}
		}
	}
	return count;
}

源代码

在实现扫雷的时候有什么不懂的地方可以参考这里的代码:扫雷

你可能感兴趣的:(C语言,c语言,开发语言,后端)