【C语言】——扫雷游戏

目录

① 前言

② 游戏规则 

③ 实现思路 

一. test.c文件实现

1.创建菜单

 2.实现switch case语句

3.创建雷盘

4.多种函数 

二. game.c文件实现 

1.初始化雷盘

2.打印雷盘 

3.随机布雷 

4. 进行排雷

 三.game.h头文件实现

 致谢:

三.整体代码实现 

1.test.c

2.game.c


前言

上期讲到了C语言三子棋游戏的实现,本期介绍另外一款热门小游戏--——扫雷!

这款游戏相信小时候都玩过,接下来随着我来用C语言实现,我会一步步把整个扫雷游戏的所有功能实现,详细的讲解每一个功能代码上的实现。

扫雷~启动!!

游戏规则 

在一个N*N的方块矩阵中随机布置一定量的地雷,再由玩家输入坐标翻出地雷,以找出所有地雷为最终游戏目标。如果玩家翻开的方块有地雷,则游戏结束

实现思路 

1.创建菜单:进行菜单的美化。

2.实现switch case语句:开始游戏或退出游戏的选择。

3.创建雷盘:假设创建9*9的数组雷盘,在这个棋盘上去布置雷,再对雷进行排查。但我们在找雷的过程中,进行遍历该位置的周围,会导致越界,所以我们就把这个数组扩大一圈,变成11*11。

创建两个雷盘,一个我们放雷,一个对外加密的雷盘

4.初始化雷盘:对两个雷盘初始化。

5.打印雷盘:打印对外加密的雷盘,再加入行列序号方便输入坐标查雷。

6.随机布雷:利用rand函数进行在9*9雷盘范围内随机布雷,不会让后面的排查雷操作越界。

7.进行排雷:这是非常关键的一步,需要假设多种情况。

主要通过三个文件来实: test.c game.c game.h
test.c — 扫雷的测试

game.c — 游戏函数的实现

game.h — 游戏函数的声明,

一. test.c文件实现

1.创建菜单

//菜单
void menu()			
{
	printf("->*************************<-\n");
	printf("->******1. 开始游戏********<-\n");
	printf("->******0. 退出游戏********<-\n");
	printf("->*************************<-\n");
}

 2.实现switch case语句

int main()
{
	srand((unsigned int )time(NULL));	//产生随机值
	int input = 0;
	do
	{
		printf("请选择\n");
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("你已经退出游戏");
			break;
		default:
			printf("输入错误,重新选择");
			break;
		}
	} while (input);
	return 0;
}

3.创建雷盘

在自定义进入游戏函数里面创建两个数组

因为代码中多次使用数组,利用#define定义两个数组和大小在头文件中。

//printf("扫雷 启动!\n");
	char mine[ROWS][COLS];   //创建布置雷的数组
	char show[ROWS][COLS];   //对外显示需要排查雷的数组

4.多种函数 

需要对雷盘初始化打印雷盘随机布置雷排查雷这些操作

//游戏
void game()
{
	//printf("扫雷 启动!\n");
	char mine[ROWS][COLS];   //创建布置雷的数组
	char show[ROWS][COLS];   //对外显示需要排查雷的数组
	//初始化棋盘
	Initboard(mine,ROWS,COLS,'0');
	Initboard(show, ROWS, COLS,'*');

	//打印棋盘
	//Displayboard(mine, ROW, COL);
	Displayboard(show, ROW, COL);

	//布置雷
	Setmine(mine,ROW,COL);
	//Displayboard(mine, ROW, COL);

	//排查雷
	Findboard(mine, show, ROW, COL);

二. game.c文件实现 

1.初始化雷盘

设置四个参数,二维数组名,大小,还有一个想要初始化独立的字符。

数组大小比对外数组大,防止后期越界

//初始化棋盘定义
void Initboard(char board[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++)
		{
			board[i][j] = set;
		}
	}
}

2.打印雷盘 

打印对外显示的雷盘,经过‘*’加密的,数组大小没变,只是遍历范围变成对外数组大小

//打印棋盘定义
void Displayboard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("-------扫 雷-------\n");
	for (j = 0; j <= col; j++)  //打印列的序号
	{
		printf("%d ", j);
	}
	printf("\n");
	for (i = 0; i <= row; i++)		//打印排雷区分割
	{
		printf("- ");
	}
	printf("\n");

	for (i = 1; i <= row; i++)
	{
		printf("%d", i);	//打印行的序号
		printf("|");	//打印排雷区分隔
		for (j = 1; j <= row; j++)
		{
			printf("%c ",board[i][j]);
		
		}
		printf("\n");
	}
	printf("-------扫 雷-------\n");

}

3.随机布雷 

通过rand()进行随机布雷,控制范围。创建一个地雷数量的变量,只有成功布雷后才结束。

//布置雷定义
void Setmine(char board[ROWS][COLS], int row, int col)    //范围依旧在对外显示数组内
{
	int x = 0;
	int y = 0;
	int ret = BOMB;	//定义炸弹的数量
	while (ret)
	{
		x = rand() % row + 1;		//布置随机雷,范围在1~9
		y = rand() % col + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			ret--;
		}
	}	
}

4. 进行排雷

1.当翻开的是“地雷”时,会被炸然后游戏结束
2.当输入的格子周围一圈当中存在“地雷”时,输入的坐标处会显示周围一圈格子内存在“地雷”的个数。
3.如果把不是雷的地方都找出来了,游戏也结束 


//排查雷定义,将两个数组联系到一起
void Findboard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	int win = 0; 
	while (win<row*col-BOMB)
	{
		printf("请输入排查雷坐标->\n");
		scanf("%d %d", &i, &j);
		if (i >= 1 && i <= row && j >= 1 && j <= col)
		{
			if (mine[i][j] == '1')
			{
				printf("你被炸了,游戏结束\n");
				Displayboard(mine, ROW, COL);  //让用户被炸的明白
				break;
			}
			else if (mine[i][j] != '1')   //不是雷,计算周围有几个雷
			{
				int ret = GetBomb(mine,i,j);
				show[i][j] = ret + '0';		//得到的数字需要转成字符形式,因为数组是char。将该位置换成字符数
				Displayboard(show, ROW, COL);	//打印赋值后的show棋盘
				win++;
			}
		}
		else
		{
			printf("输入错误,请重新输入坐标\n");
		}
	}
	if (win == row * col - BOMB)
	{
		printf("恭喜你,排雷成功\n");
	}
}	

GetBomb()计算坐标处雷的数量,因为数组char型,函数返回的是整型,加上'0'。

因为:'0'的ascll值 48。

'1' ------49

'2'---50

所以:'2' - '0' = 2;

字符2减去字符0,等于数字2,同理,字符1-字符0 = 数字1

//计算坐标周围雷的数量
int GetBomb(char mine[ROWS][COLS], int x, int y) {
	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';
}

 三.game.h头文件实现

我们需要两组二维数组大小,需要炸弹数量的定义,需要包含rand() time()头文件,还要多个函数的定义

#pragma once
#include<stdlib.h>
#include<time.h>

#define ROW 9		//给用户看的大小
#define COL 9
#define ROWS ROW+2	//实际大小
#define COLS COL+2
#define BOMB 10			//布置炸弹的数量
//初始化棋盘
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);

//排查雷
void Findboard(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);

 致谢:


到这里,整体扫雷游戏代码讲解差不多结束了,感谢你看到这里,扫雷游戏是非常经典的一款,相信每一位初学者都会接触,希望我的介绍能有些许帮助,谢谢大佬看到这里,在下面我献上整个文件代码实现。 文中不足的,希望得到指正和改善。感激不尽!!

愿星光照亮每一位赶路人。

三.整体代码实现 

1.test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"game.h"

//菜单
void menu()			
{
	printf("->*************************<-\n");
	printf("->******1. 开始游戏********<-\n");
	printf("->******0. 退出游戏********<-\n");
	printf("->*************************<-\n");
}

//游戏
void game()
{
	//printf("扫雷 启动!\n");
	char mine[ROWS][COLS];   //创建布置雷的数组
	char show[ROWS][COLS];   //对外显示需要排查雷的数组
	//初始化棋盘
	Initboard(mine,ROWS,COLS,'0');
	Initboard(show, ROWS, COLS,'*');

	//打印棋盘
	//Displayboard(mine, ROW, COL);
	Displayboard(show, ROW, COL);

	//布置雷
	Setmine(mine,ROW,COL);
	//Displayboard(mine, ROW, COL);

	//排查雷
	Findboard(mine, show, ROW, COL);

}

int main()
{
	srand((unsigned int )time(NULL));	//产生随机值
	int input = 0;
	do
	{
		printf("请选择\n");
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("你已经退出游戏");
			break;
		default:
			printf("输入错误,重新选择");
			break;
		}
	} while (input);
	return 0;
}

2.game.c

#pragma once
#include"game.h"

//初始化棋盘定义
void Initboard(char board[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++)
		{
			board[i][j] = set;
		}
	}
}

//打印棋盘定义
void Displayboard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("-------扫 雷-------\n");
	for (j = 0; j <= col; j++)  //打印列的序号
	{
		printf("%d ", j);
	}
	printf("\n");
	for (i = 0; i <= row; i++)		//打印排雷区分割
	{
		printf("- ");
	}
	printf("\n");

	for (i = 1; i <= row; i++)
	{
		printf("%d", i);	//打印行的序号
		printf("|");	//打印排雷区分隔
		for (j = 1; j <= row; j++)
		{
			printf("%c ",board[i][j]);
		
		}
		printf("\n");
	}
	printf("-------扫 雷-------\n");

}

//布置雷定义
void Setmine(char board[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int ret = BOMB;	//定义炸弹的数量
	while (ret)
	{
		x = rand() % row + 1;		//布置随机雷,范围在1~9
		y = rand() % col + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			ret--;
		}
	}	
}

//计算坐标周围雷的数量
int GetBomb(char mine[ROWS][COLS], int x, int y) {
	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 Findboard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	int win = 0; 
	while (win<row*col-BOMB)
	{
		printf("请输入排查雷坐标->\n");
		scanf("%d %d", &i, &j);
		if (i >= 1 && i <= row && j >= 1 && j <= col)
		{
			if (mine[i][j] == '1')
			{
				printf("你被炸了,游戏结束\n");
				Displayboard(mine, ROW, COL);  //让用户被炸的明白
				break;
			}
			else if (mine[i][j] != '1')   //不是雷,计算周围有几个雷
			{
				int ret = GetBomb(mine,i,j);
				show[i][j] = ret + '0';		//得到的数字需要转成字符形式,因为数组是char。将该位置换成字符数
				Displayboard(show, ROW, COL);	//打印赋值后的show棋盘
				win++;
			}
		}
		else
		{
			printf("输入错误,请重新输入坐标\n");
		}
	}
	if (win == row * col - BOMB)
	{
		printf("恭喜你,排雷成功\n");
	}
}	

 3.game.h

#pragma once
#include<stdlib.h>
#include<time.h>

#define ROW 9		//给用户看的大小
#define COL 9
#define ROWS ROW+2	//实际大小
#define COLS COL+2
#define BOMB 10			//布置炸弹的数量
//初始化棋盘
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);

//排查雷
void Findboard(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);

猜你喜欢

转载自blog.csdn.net/m0_67367079/article/details/132589202