C语言实现扫雷

游戏介绍

在一个方块矩阵中随机布置一定量的地雷,再由玩家逐个翻开方块,以找出所有地雷为最终游戏目标。如果玩家翻开的方块有地雷,则游戏结束。如果玩家翻开的方块没有地雷,就显示周边一圈的地雷数量(提示数)

设计思路

1.布置有地雷的矩阵自然是定义一个二维数组,但要同时存储地雷信息和周边地雷数量的提示数信息有点乱,所以我定义两个二位数组,一个存储地雷信息,一个存储提示数
2.在实现提示数的过程中,需要遍历一圈玩家所翻开方块的周围,但遍历方块矩阵边上的方块显然会越界。
在这里插入图片描述

所以干脆在游戏方块矩阵的基础上再扩大一圈,初始化地雷数组的时候用字符‘0’,地雷用字符‘1’表示。计算提示数的时候,用玩家选择方块周边的八个方块的字符对应的ASCII码之和减去8个字符‘0’对应的ASCII码之和
在这里插入图片描述

代码实现

这里为了方便后期排查,我创建一个头文件(game.h)和俩源文件(frame.c 和 game.c)

在头文件包含待会可能会使用的库函数的声明,同时用宏定义方块矩阵的行列数及扩大一圈后的方块矩阵的行列数:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#define ROW 9//行 设置方块矩阵的行数

#define COL 9//列 设置方块矩阵的列数

#define ROWS ROW + 2//在原本方块矩阵的基础上扩大一圈,方便确定一个方块周边的地雷数

#define COLS COL + 2//在原本方块矩阵的基础上扩大一圈,方便确定一个方块周边的地雷数

开始菜单

源文件frame.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void menu()//开始菜单
{
	printf("**********************************\n");
	printf("************  1.Play  ************\n");
	printf("************  2.Exit  ************\n");
	printf("**********************************\n");
}

int main()
{
	int input = 0;
	do
	{
		printf("请输入-->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏:\n");
			game();
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("非法输入,请重新选择\n");
			break;		
		}
	} while (input);
	return 0;
}

用数组表示方块矩阵

定义两个二位数组,一个存储地雷信息,一个存储提示数

	char mine[ROWS][COLS] = { 0 };//用于存放雷
	char reminder[ROWS][COLS] = { 0 };//用于存放数字提示

frame.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void menu()//开始菜单
{
	printf("**********************************\n");
	printf("************  1.Play  ************\n");
	printf("************  2.Exit  ************\n");
	printf("**********************************\n");
}

void game()//游戏入口
{
	char mine[ROWS][COLS] = { 0 };//用于存放雷
	char reminder[ROWS][COLS] = { 0 };//用于存放数字提示 
}

int main()
{
	int input = 0;
	do
	{
		menu();//游戏入口
		printf("请输入-->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏:\n");
			game();
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("非法输入,请重新选择\n");
			break;		
		}
	} while (input);
	return 0;
}

初始化方块矩阵

由于我们定义了两个方块矩阵分别用于存放地雷信息和提示数信息,初始化时,分别定义初始化内容,方便后期判断是否踩雷及周围一圈地雷数量

传参是多传一个字符,以该字符初始化对应数组
这里在地雷数组中是以字符‘0’来初始化的
在源文件frame.c中,调用函数

	InitBoard(mine, ROWS, COLS, '0');//初始化地雷方块矩阵
	InitBoard(reminder, ROWS, COLS, '*');//初始化提示数方块矩阵

在源文件game.c中,丰富函数内容

void InitBoard(char arr[ROWS][COLS], int row, int col, char symbol)//初始化方块矩阵
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			arr[i][j] = symbol;
		}
	}
}

在头文件中声明函数:

void InitBoard(char arr[ROWS][COLS], int row, int col, char symbol);//初始化方块矩阵

头文件game.h:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#define ROW 9//行 设置方块矩阵的行数

#define COL 9//列 设置方块矩阵的列数

#define ROWS ROW + 2//在原本方块矩阵的基础上扩大一圈,方便确定一个方块周边的地雷数

#define COLS COL + 2//在原本方块矩阵的基础上扩大一圈,方便确定一个方块周边的地雷数

#define MODE 10 //地雷数

void InitBoard(char arr[ROWS][COLS], int row, int col, char symbol);//初始化方块矩阵

源文件frame.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void menu()//开始菜单
{
	printf("**********************************\n");
	printf("************  1.Play  ************\n");
	printf("************  2.Exit  ************\n");
	printf("**********************************\n");
}

void game()//游戏入口
{
	char mine[ROWS][COLS] = { 0 };//用于存放雷
	char reminder[ROWS][COLS] = { 0 };//用于存放数字提示
	InitBoard(mine, ROWS, COLS, '0');//初始化地雷方块矩阵
	InitBoard(reminder, ROWS, COLS, '*');//初始化提示数方块矩阵
}

int main()
{
	int input = 0;
	do
	{
		menu();//游戏入口
		printf("请输入-->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏:\n");
			game();
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("非法输入,请重新选择\n");
			break;		
		}
	} while (input);
	return 0;
}

头文件game.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void InitBoard(char arr[ROWS][COLS], int row, int col, char symbol)//初始化方块矩阵
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			arr[i][j] = symbol;
		}
	}
}

布置地雷

1.生成随机数

随机数不能大于没扩容的方块矩阵的行列数

2.不能在同一个地方布置两次地雷

之前我用字符‘0’来初始化地雷数组,如果生成的随机数的坐标指向的元素,是字符‘0’(这个位置之前没放过地雷),那么在这个位置放置字符‘1’,表示这个位置放过地雷了

在头文件game.c中,用宏定义一个地雷数量

#define MODE 10 //地雷数

在源文件frame.c中,调用函数、设置随机种子

SetMine(mine, ROW, COL);//布置地雷
srand((unsigned int)time(NULL));//设置一个随机种子

在源文件game.c中,丰富函数内容

void SetMine(char mine[ROWS][COLS], int row, int col)//随机放置地雷
{
	int count = MODE;
	int x = 0;
	int y = 0;
	while (count)
	{
		x = rand() % row + 1;
		y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';//放置雷
			count--;
		}
	}
}

在头文件中声明函数:

void SetMine(char arr[ROW][COL], int row, int col);//布置地雷

头文件game.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#define ROW 9//行 设置方块矩阵的行数

#define COL 9//列 设置方块矩阵的列数

#define ROWS ROW + 2//在原本方块矩阵的基础上扩大一圈,方便确定一个方块周边的地雷数

#define COLS COL + 2//在原本方块矩阵的基础上扩大一圈,方便确定一个方块周边的地雷数

#define MODE 10 //地雷数

void InitBoard(char arr[ROWS][COLS], int row, int col, char symbol);//初始化方块矩阵

void SetMine(char arr[ROW][COL], int row, int col);//布置地雷

源文件frame.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void menu()//开始菜单
{
	printf("**********************************\n");
	printf("************  1.Play  ************\n");
	printf("************  2.Exit  ************\n");
	printf("**********************************\n");
}

void game()//游戏入口
{
	char mine[ROWS][COLS] = { 0 };//用于存放雷
	char reminder[ROWS][COLS] = { 0 };//用于存放数字提示
	InitBoard(mine, ROWS, COLS, '0');//初始化地雷方块矩阵
	InitBoard(reminder, ROWS, COLS, '*');//初始化提示数方块矩阵
	SetMine(mine, ROW, COL);//布置地雷
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));//设置一个随机种子
	do
	{
		menu();//游戏入口
		printf("请输入-->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏:\n");
			game();
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("非法输入,请重新选择\n");
			break;		
		}
	} while (input);
	return 0;
}

源文件game.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void InitBoard(char arr[ROWS][COLS], int row, int col, char symbol)//初始化方块矩阵
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			arr[i][j] = symbol;
		}
	}
}

void SetMine(char mine[ROWS][COLS], int row, int col)//随机放置地雷
{
	int count = MODE;
	int x = 0;
	int y = 0;
	while (count)
	{
		x = rand() % row + 1;
		y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';//放置雷
			count--;
		}
	}
}

打印方块矩阵

1.在方块矩阵外,打印行列数,方便输入坐标
2.这里打印的是没扩容的方块矩阵(扩容的方块是为了方便计算提示数)
在源文件frame.c中调用:

DisplayBoard(reminder, ROW, COL);//打印地雷数组

在源文件game.c中丰富函数内容:

void DisplayBoard(char arr[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 ", arr[i][j]);
		}
		printf("\n");
	}
	printf("---------  扫雷  ---------\n");
}

在头文件中声明:

void DisplayBoard(char arr[ROW][COL], int row, int col);//打印方块矩阵

头文件game.h:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#define ROW 9//行 设置方块矩阵的行数

#define COL 9//列 设置方块矩阵的列数

#define ROWS ROW + 2//在原本方块矩阵的基础上扩大一圈,方便确定一个方块周边的地雷数

#define COLS COL + 2//在原本方块矩阵的基础上扩大一圈,方便确定一个方块周边的地雷数

#define MODE 10 //地雷数

void InitBoard(char arr[ROWS][COLS], int row, int col, char symbol);//初始化方块矩阵

void DisplayBoard(char arr[ROW][COL], int row, int col);//打印方块矩阵

void SetMine(char arr[ROW][COL], int row, int col);//布置地雷

源文件frame.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void menu()//开始菜单
{
	printf("**********************************\n");
	printf("************  1.Play  ************\n");
	printf("************  2.Exit  ************\n");
	printf("**********************************\n");
}

void game()//游戏入口
{
	char mine[ROWS][COLS] = { 0 };//用于存放雷
	char reminder[ROWS][COLS] = { 0 };//用于存放数字提示
	InitBoard(mine, ROWS, COLS, '0');//初始化地雷方块矩阵
	InitBoard(reminder, ROWS, COLS, '*');//初始化提示数方块矩阵
	SetMine(mine, ROW, COL);//布置地雷
	DisplayBoard(reminder, ROW, COL);//打印地雷数组
	SweepMine(mine, reminder, ROW, COL);//排查雷
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));//设置一个随机种子
	do
	{
		menu();//游戏入口
		printf("请输入-->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏:\n");
			game();
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("非法输入,请重新选择\n");
			break;		
		}
	} while (input);
	return 0;
}

源文件game.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void InitBoard(char arr[ROWS][COLS], int row, int col, char symbol)//初始化方块矩阵
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			arr[i][j] = symbol;
		}
	}
}

void DisplayBoard(char arr[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 ", arr[i][j]);
		}
		printf("\n");
	}
	printf("---------  扫雷  ---------\n");
}

void SetMine(char mine[ROWS][COLS], int row, int col)//随机放置地雷
{
	int count = MODE;
	int x = 0;
	int y = 0;
	while (count)
	{
		x = rand() % row + 1;
		y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';//放置雷
			count--;
		}
	}
}

玩家排查地雷

1.判断玩家所输入的坐标是否越界
2.判断玩家所输入坐标对应的方块是否有雷

踩雷了就游戏结束,然后打印存有地雷的数组,死个明白
(这里计算提示数所调用的函数的内容在下一个小节)
没踩雷,就在玩家所输入的坐标对应的方块的位置上显示提示数(周围8个方块中有
多少雷),并且打印提示数方块矩阵(方便玩家进一步判断)

3.判断玩家是否排完了所有的雷

定义一个变量。在上一步中,如果没踩雷,这个变量就自加1。当这个变量等于没扩容的
方块矩阵中方块的数量(即行*列),说明玩家已经排完了所有的雷。游戏胜利,并且打印
地雷矩阵(显示地雷存放的位置)。在这之前自然是要循环,知道满足这个条件

在源文件frame.c中调用

SweepMine(mine, reminder, ROW, COL);//排查雷

在源文件game.c中丰富:

void SweepMine(char mine[ROWS][COLS], char reminder[ROWS][COLS], int row, int col)//玩家寻找地雷
{

	int x = 0;
	int y = 0;
	int flag = 0;//用于判断游戏是否胜利
	while (flag < row * col - MODE)
	{
		printf("请输入要排查的坐标:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)//判断坐标是否非法
		{
			if (mine[x][y] == '1')//判断输入的坐标是不是雷
			{
				printf("踩雷了,游戏结束\n");
				DisplayBoard(mine, ROW, COL);//打印布置地雷的矩阵(死个明白)
				break;
			}
			else
			{
				int count = ReminderNumber(mine, x, y);//周边雷的个数
				reminder[x][y] = count + '0';//把周边地雷的个数填到玩家刚刚翻开的方块中去
				DisplayBoard(reminder, ROW, COL);//在打印一遍带有提示数的方块矩阵
				flag++;
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
	if (flag == row * col - MODE)
	{
		printf("游戏胜利\n");
		DisplayBoard(mine, ROW, COL);//胜利后打印布置地雷的矩阵
	}
}

在头文件game.h中声明:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#define ROW 9//行 设置方块矩阵的行数

#define COL 9//列 设置方块矩阵的列数

#define ROWS ROW + 2//在原本方块矩阵的基础上扩大一圈,方便确定一个方块周边的地雷数

#define COLS COL + 2//在原本方块矩阵的基础上扩大一圈,方便确定一个方块周边的地雷数

#define MODE 10 //地雷数

void InitBoard(char arr[ROWS][COLS], int row, int col, char symbol);//初始化方块矩阵

void DisplayBoard(char arr[ROW][COL], int row, int col);//打印方块矩阵

void SetMine(char arr[ROW][COL], int row, int col);//布置地雷

void SweepMine(char mine[ROWS][COLS], char reminder[ROWS][COLS], int row, int col);//寻找地雷

提示数的计算

在源文件game.c中,实现玩家排查地雷的函数(SweepMine)上面定义计算提示数的函数:

字符是按ASCII码值转化为整数存储的。

字符‘0’和‘1’对应的ASCII码值分别为48、49
前面我将地雷以字符‘1’的形式存储在地雷数组中
再前面我用字符‘0’初始化地雷数组
将玩家所输入坐标对应的方块周边的方块中的字符所对应的ASCII码值相加,在减去8个字符‘0’所对应的ASCII码值相加,便得到了提示数(即玩家所选方块周边8个方块中,地雷的个数)
int ReminderNumber(char mine[ROWS][COLS], int x, int y)//计算周边8个格子的雷的个数
{
	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';
}

源文件game.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void InitBoard(char arr[ROWS][COLS], int row, int col, char symbol)//初始化方块矩阵
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			arr[i][j] = symbol;
		}
	}
}

void DisplayBoard(char arr[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 ", arr[i][j]);
		}
		printf("\n");
	}
	printf("---------  扫雷  ---------\n");
}

void SetMine(char mine[ROWS][COLS], int row, int col)//随机放置地雷
{
	int count = MODE;
	int x = 0;
	int y = 0;
	while (count)
	{
		x = rand() % row + 1;
		y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';//放置雷
			count--;
		}
	}
}

int ReminderNumber(char mine[ROWS][COLS], int x, int y)//计算周边8个格子的雷的个数
{
	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 SweepMine(char mine[ROWS][COLS], char reminder[ROWS][COLS], int row, int col)//玩家寻找地雷
{

	int x = 0;
	int y = 0;
	int flag = 0;//用于判断游戏是否胜利
	while (flag < row * col - MODE)
	{
		printf("请输入要排查的坐标:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)//判断坐标是否非法
		{
			if (mine[x][y] == '1')//判断输入的坐标是不是雷
			{
				printf("踩雷了,游戏结束\n");
				DisplayBoard(mine, ROW, COL);//打印布置地雷的矩阵(死个明白)
				break;
			}
			else
			{
				int count = ReminderNumber(mine, x, y);//周边雷的个数
				reminder[x][y] = count + '0';//把周边地雷的个数填到玩家刚刚翻开的方块中去
				DisplayBoard(reminder, ROW, COL);//在打印一遍带有提示数的方块矩阵
				flag++;
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
	if (flag == row * col - MODE)
	{
		printf("游戏胜利\n");
		DisplayBoard(mine, ROW, COL);//胜利后打印布置地雷的矩阵
	}
}

最后附上完整代码:

头文件game.h:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#define ROW 9//行 设置方块矩阵的行数

#define COL 9//列 设置方块矩阵的列数

#define ROWS ROW + 2//在原本方块矩阵的基础上扩大一圈,方便确定一个方块周边的地雷数

#define COLS COL + 2//在原本方块矩阵的基础上扩大一圈,方便确定一个方块周边的地雷数

#define MODE 10 //地雷数

void InitBoard(char arr[ROWS][COLS], int row, int col, char symbol);//初始化方块矩阵

void DisplayBoard(char arr[ROW][COL], int row, int col);//打印方块矩阵

void SetMine(char arr[ROW][COL], int row, int col);//布置地雷

void SweepMine(char mine[ROWS][COLS], char reminder[ROWS][COLS], int row, int col);//寻找地雷

源文件frame.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void menu()//开始菜单
{
	printf("**********************************\n");
	printf("************  1.Play  ************\n");
	printf("************  2.Exit  ************\n");
	printf("**********************************\n");
}

void game()//游戏入口
{
	char mine[ROWS][COLS] = { 0 };//用于存放雷
	char reminder[ROWS][COLS] = { 0 };//用于存放数字提示
	InitBoard(mine, ROWS, COLS, '0');//初始化地雷方块矩阵
	InitBoard(reminder, ROWS, COLS, '*');//初始化提示数方块矩阵
	SetMine(mine, ROW, COL);//布置地雷
	DisplayBoard(reminder, ROW, COL);//打印地雷数组
	SweepMine(mine, reminder, ROW, COL);//排查雷
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));//设置一个随机种子
	do
	{
		menu();//游戏入口
		printf("请输入-->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏:\n");
			game();
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("非法输入,请重新选择\n");
			break;		
		}
	} while (input);
	return 0;
}

源文件game.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void InitBoard(char arr[ROWS][COLS], int row, int col, char symbol)//初始化方块矩阵
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			arr[i][j] = symbol;
		}
	}
}

void DisplayBoard(char arr[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 ", arr[i][j]);
		}
		printf("\n");
	}
	printf("---------  扫雷  ---------\n");
}

void SetMine(char mine[ROWS][COLS], int row, int col)//随机放置地雷
{
	int count = MODE;
	int x = 0;
	int y = 0;
	while (count)
	{
		x = rand() % row + 1;
		y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';//放置雷
			count--;
		}
	}
}

int ReminderNumber(char mine[ROWS][COLS], int x, int y)//计算周边8个格子的雷的个数
{
	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 SweepMine(char mine[ROWS][COLS], char reminder[ROWS][COLS], int row, int col)//玩家寻找地雷
{

	int x = 0;
	int y = 0;
	int flag = 0;//用于判断游戏是否胜利
	while (flag < row * col - MODE)
	{
		printf("请输入要排查的坐标:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)//判断坐标是否非法
		{
			if (mine[x][y] == '1')//判断输入的坐标是不是雷
			{
				printf("踩雷了,游戏结束\n");
				DisplayBoard(mine, ROW, COL);//打印布置地雷的矩阵(死个明白)
				break;
			}
			else
			{
				int count = ReminderNumber(mine, x, y);//周边雷的个数
				reminder[x][y] = count + '0';//把周边地雷的个数填到玩家刚刚翻开的方块中去
				DisplayBoard(reminder, ROW, COL);//在打印一遍带有提示数的方块矩阵
				flag++;
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
	if (flag == row * col - MODE)
	{
		printf("游戏胜利\n");
		DisplayBoard(mine, ROW, COL);//胜利后打印布置地雷的矩阵
	}
}

调试

将打印提示数的方块矩阵改为打印地雷的方块矩阵

//#define MODE 10 //地雷数

#define MODE 80//调试

将地雷数量改为方块总数-1

//DisplayBoard(reminder, ROW, COL);//打印地雷数组
DisplayBoard(mine, ROW, COL);//调试

头文件game.h:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#define ROW 9//行 设置方块矩阵的行数

#define COL 9//列 设置方块矩阵的列数

#define ROWS ROW + 2//在原本方块矩阵的基础上扩大一圈,方便确定一个方块周边的地雷数

#define COLS COL + 2//在原本方块矩阵的基础上扩大一圈,方便确定一个方块周边的地雷数

//#define MODE 10 //地雷数

#define MODE 80//调试

void InitBoard(char arr[ROWS][COLS], int row, int col, char symbol);//初始化方块矩阵

void DisplayBoard(char arr[ROW][COL], int row, int col);//打印方块矩阵

void SetMine(char arr[ROW][COL], int row, int col);//布置地雷

void SweepMine(char mine[ROWS][COLS], char reminder[ROWS][COLS], int row, int col);//寻找地雷

源文件game.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void menu()//开始菜单
{
	printf("**********************************\n");
	printf("************  1.Play  ************\n");
	printf("************  2.Exit  ************\n");
	printf("**********************************\n");
}

void game()//游戏入口
{
	char mine[ROWS][COLS] = { 0 };//用于存放雷
	char reminder[ROWS][COLS] = { 0 };//用于存放数字提示
	InitBoard(mine, ROWS, COLS, '0');//初始化地雷方块矩阵
	InitBoard(reminder, ROWS, COLS, '*');//初始化提示数方块矩阵
	SetMine(mine, ROW, COL);//布置地雷
	//DisplayBoard(reminder, ROW, COL);//打印地雷数组
	DisplayBoard(mine, ROW, COL);//调试
	SweepMine(mine, reminder, ROW, COL);//排查雷
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));//设置一个随机种子
	do
	{
		menu();//游戏入口
		printf("请输入-->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏:\n");
			game();
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("非法输入,请重新选择\n");
			break;		
		}
	} while (input);
	return 0;
}
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值