一、前言:
众所周知,扫雷是一款大众类的益智小游戏,它的游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。
今天,我们的目的就是通过C语言来实现一个简单扫雷游戏。
主要操作有:
1.初始化棋盘;
2.打印棋盘;
3.统计周围雷的个数;
4.排雷;
5.判断输赢;
我这里是通过三个文件:源文件(Test.c)源文件(Game.c)头文件(Game.h)来实现的它们分别有各自的分工:
1.源文件-Test.c:主要用于调用定义的函数来实现扫雷操作。
2.源文件-Game.c:主要用于定义头文件-Game.h声明的函数。
3.头文件-Game.h:主要用于声明所需要的操作的函数。
二、头文件-Game.h:
2.1-目的:
这里我们需要的操作是声明所需要的头文件,将所需要的操作声明成一个函数并在源文件-Game.c中定义所声明的函数。
2.2-代码:
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 9
#define COL  9
#define ROWS 11
#define COLS  11
#define COUNT 10
//选单
void menu();		
//扫雷游戏
//用于整理函数,实现扫雷所有操作
void game();
//初始化棋盘
void InitBoard(char board[ROWS][COLS],int rows,int cols,char tem);
//打印棋盘
void PrintBoard(char board[ROWS][COLS], int row, int col);
//布置雷
void SetBoard(char board[ROWS][COLS], int row, int col);
//排除雷
void FindBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
//统计周围雷的个数
int get_mine_count(char mine[ROWS][COLS],int x,int y);		
//判断是否获胜
int If_win(int win); 
三、源文件-Game.c:
3.1-目的:
将上述头文件-Game.h中所声明的操作函数通过自我实现给定义了。
3.2-操作函数的定义:
3.2.1-选单:
目的:
为了使函数操作在执行时更美观,更便于用户使用。
代码:
//设置选单
void menu()
{
	printf("*************************************\n");
	printf("**********      1.play      *********\n");
	printf("**********      0.exit      *********\n");
	printf("*************************************\n");
} 
效果图:

3.2.2-初始化棋盘:
目的:
将定义的二维数组给初始化,便于用户在打印时观察以及后续的操作。
代码:
//初始化棋盘
void	InitBoard(char board[ROWS][COLS], int rows, int cols, char tem)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			board[i][j] = tem;
		}
	}
} 
效果图:
我们可以在初始化后打印来检查初始化是否成功。

3.2.3-打印棋盘:
目的:
打印扫雷棋盘,便于自我检查自我定义的函数,以及用户进行扫雷时的操作及观看。
代码:
//打印棋盘
void PrintBoard(char board[ROWS][COLS], int row, int col)
{
	printf("----------------扫雷------------------\n");
	for (int j = 0; j <= col; j++)
	{
		printf(" %d ",j);
	}
	printf("\n");
	for (int i = 1; i <= row; i++)
	{
		printf(" %d ",i);
		for (int j = 1; j <= col; j++)
		{
			printf(" %c ", board[i][j]);
		}
		printf("\n");
	}
	printf("----------------扫雷------------------\n");
} 
效果图:

3.2.4-布置雷:
目的:
在二维数组中随机生成雷,来便于后续的扫雷操作。
代码:
//在布雷数组中布置雷
void SetBoard(char board[ROWS][COLS], int row, int col)
{
	int count = COUNT;
	while (count)
	{
		int x = rand() % col + 1;
		int y = rand() % row + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;
		}
	}
} 
效果图:

3.2.5-进行排雷:
目的:
用户进行扫雷游戏。注意:这里需判断是否将没雷的位置全部点出,如果全部点出则需要提示用户获胜,并且如果用户输入的坐标已经排过一次雷了我们还需提示用户。
代码:
//在排雷数组中排雷
void FindBoard(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int win = 0;
	while (1)
	{
		printf("请输入坐标:");
		scanf("%d %d", &x, &y);
		if (show[x][y] != '*')
		{
			printf("该坐标已被排查过!\n");
			continue;
		}
		if (mine[x][y] == '1')
		{
			printf("很遗憾,你被炸死了!\n");
			PrintBoard(mine, ROW, COL);			   //打印布雷数组
			break;
		}
		if (mine[x][y] == '0')
		{
			int num = get_mine_count(mine, x, y);
			show[x][y] = num + '0';
			win++;
			//判断是否获胜
			if (If_win(win))
			{
				printf("恭喜你赢了!\n");
				PrintBoard(show, ROW, COL);			   //打印排雷数组
				return;
			}
			PrintBoard(show, ROW, COL);			   //打印排雷数组
		}
	}
} 
效果图:

3.2.6-统计周围雷的个数:
目的:
统计输入坐标格子周围8个位置中雷的总数,以便于用户进行排雷操作。
代码:
//统计周围雷的个数
int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
	int count = 0;
	if (mine[x - 1][y - 1] == '1')
	{
		count++;
	}
	if (mine[x - 1][y] == '1')
	{
		count++;
	}
	if (mine[x - 1][y + 1] == '1')
	{
		count++;
	}
	if (mine[x][y - 1] == '1')
	{
		count++;
	}
	if (mine[x][y + 1] == '1')
	{
		count++;
	}
	if (mine[x + 1][y - 1] == '1')
	{
		count++;
	}
	if (mine[x + 1][y] == '1')
	{
		count++;
	}
	if (mine[x + 1][y + 1] == '1')
	{
		count++;
	}
	return count;
} 
效果图:
3.2.7-判断是否获胜:
目的:
如果排除位置个数与总数-雷的个数相同则说明用户获胜,我们需要判断用户是否获胜并提示用户。
代码:
//判断是否获胜
int If_win(int win)
{
	if (win == (ROW * COL - COUNT))
	{
		return 1;
	}
	return 0;
} 
四、源文件-Test.c:
4.1-目的:
主要用于调用定义的函数通过分工来实现扫雷操作,并定义扫雷时所需要的两个数组。
4.2-思路:
首先,我们需要知道扫雷需要通过两个二维数组来实现,一个用于布置雷,一个用于进行排雷游戏。接着,我们需要对定义的两个二维数组进行初始化,便于后继的操作以及用户的观察。在初始化后我们也可以通过自我定义的打印函数来检查初始化是否正确。然后,在完成上述操作后,我们需要对布雷数组进行随机布置雷。最后,我们进行排雷操作,从而实现扫雷游戏。
4.3-代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include "Game.h"
void game()
{
	char mine[ROWS][COLS] = { 0 };			//布雷的二维数组
	char show[ROWS][COLS] = { 0 };			//排雷的二维数组
	InitBoard(mine, ROWS, COLS, '0');		//初始化布雷数组
	//PrintBoard(mine, ROW, COL);			   //打印布雷数组
	
	InitBoard(show, ROWS, COLS, '*');		初始化排雷数组
	PrintBoard(show, ROW, COL);			   //打印排雷数组
	
	SetBoard(mine, ROW, COL);			   //布置雷
	//PrintBoard(mine, ROW, COL);			   //打印布雷数组
	FindBoard(mine, show, ROW, COL);			   //排雷
}
int main()
{
	srand((unsigned int)time(NULL));
	int intput=1;
	do
	{
		menu();
		printf("请选择选项:>");
		scanf("%d", &intput);
		switch (intput)
		{
		case 1:
		{
			game();
			break;
		}
		case 0:
		{
			printf("退出游戏!");
			break;
		}
		default:
		{
			printf("选择错误,重新选择!");
			break;
		}
		}
	} while (intput);
	return 0;
} 
五、结语:
上述内容,即是我个人对扫雷游戏-C语言的个人见解以及自我实现。若有大佬发现哪里有问题可以私信或评论指教一下我这个小萌新。非常感谢各位uu们的点赞,关注,收藏,我会更加努力的学习编程语言,还望各位多多关照,让我们一起进步吧!





















