【C语言初阶】 快来看看扫雷的简单实现(C语言,后附完整代码)

目录

 

扫雷规则简介

游戏主界面

头文件

初始化棋盘

打印棋盘

布置雷场

排查雷

完整代码


扫雷规则简介

实现扫雷前,我们先来看看扫雷的玩法:在一个9×9(初级)、16×16(中级)、16×30(高级)或自定义大小的方块矩阵中随机布置一定量的地雷(初级为10个,中级为40个,高级为99个),再由玩家逐个翻开方块,以找出所有地雷为最终游戏目标,若打开的方块没有雷,则会出现一个数子用于统计该空格附近雷的数量。

这次呢,博主会带领大家完成一个初级的扫雷游戏(9*9),这次博主依旧如前面三子棋游戏实现一样,采用三个文件

 8006892a7ae44bfe8dd14562808c5d65.png

game.h 里包含了我们这次所需要的头文件

game.c 里是我们游戏的具体实现

test.c 是我们的一个游戏测试

游戏主界面

作为一个游戏,我们肯定的有一个界面,让使用者知道这是干什么,那我们先写一个主界面吧:

void meanu()
{
	printf("*************************\n");
	printf("******  扫雷游戏   ******\n");
	printf("******  1.玩游戏   ******\n");
	printf("******  2.退出游戏 ******\n");
	printf("*************************\n");
}

主界面代码实现如下:

 

主界面都实现了,我们肯定的有一个主函数;那么主函数我们应该怎么写呢?

我们在有了三子棋经验后,便知道这个游戏我们需要可以选择,只要不退出可以满足多次游戏,那么我们便可以写出代码了

int main()
{
	int input = 0;
	meanu();
	srand((unsigned int)time(NULL));//与rand()搭配使用,用于产生随机数
	printf("请选择>:");
	do 
	{
		scanf("%d",& input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 2:
			printf("退出游戏");
			break;
		default:printf("非法输入,请重新输入");
		}
	} while (input != 2);
	return 0;
}

主界面和主函数的成功实现,那么我们test.c就可以写出来了

#include "game.h"

void meanu()
{
	printf("*************************\n");
	printf("******  扫雷游戏   ******\n");
	printf("******  1.玩游戏   ******\n");
	printf("******  2.退出游戏 ******\n");
	printf("*************************\n");
}

int main()
{
	int input = 0;
	meanu();
	srand((unsigned int)time(NULL));
	printf("请选择>:");
	do 
	{
		scanf("%d",& input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 2:
			printf("退出游戏");
			break;
		default:printf("非法输入,请重新输入");
		}
	} while (input != 2);
	return 0;

头文件

为了防止每次使用函数前都需要声明,所以我们将所有需要的声明和头文件都放在了game.h里面

我们先来看一下所需要用的game.h内容

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROW 9         //进行宏定义
#define COL 9		  //
#define ROWS  ROW+2	  //
#define COLS  COL+2	  //
#define cnt 10

//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);
//布置雷场
void SetMine(char board[ROWS][COLS], int row, int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

在game.h里面我们看到了一些函数的声明,而他们就是我们等会儿需要在game.c里逐一实现函数,接下来看看博主是怎么实现的吧

初始化棋盘

首先我们得先创建数组,博主用的是创建两个二维数组的方式,创建如下

char mine[ROWS][COLS];//用来储存含‘0’和‘1’的棋盘,含雷盘
char show[ROWS][COLS];//用来储存玩家所看见的棋盘

至于为什么这儿用ROWS和COLS,而不用row和col,主要是为了方便雷数量的判断,后面还会有介绍。

这里初始化时,因为我们mine[ROWS][COLS]里存放的是雷,而我们这里用‘0’和‘1’来表示,‘1’表示雷,而这里初始化时因为没有雷,我们全部初始化为‘0’;show[ROWS][COLS]是展示给玩家的,我们给它全部初始化为‘*’;

InitBoard()函数代码如下

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

当我们需要使用时,只需要传入我们所需初始化的参数就行

InitBoard(mine,ROWS,COLS,'0');
InitBoard(show, ROWS, COLS, '*');

打印棋盘

我们希望玩家在选择玩游戏后,可以给玩家打印出以下这样一个棋盘

7226a666bd654bf8944a265bb4d35e3b.png

这个棋盘包含行和列的编码,显示的时9*9,顶上有扫雷游戏的提示,打印的是‘*’,获取这些信息,便可以写出代码如下

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	printf("*****扫雷游戏******\n");//打印扫雷
	for (i = 0; i <=col; i++)//打印列的编号
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d", i);//打印行的编号
		int j = 1;
		for (j = 1; j <= col;j++)
		{
			printf(" %c", board[i][j]);
		}
		printf("\n");
	}
}
//i和j从1开始,等于row、col结束,这里传进来的是ROW、COL,也就是9
//是为了打印9*9的棋盘

传参如下

DisplayBoard(show, ROW, COL);//打印9*9的棋盘

布置雷场

当我们棋盘打印好后我们发现到现在为止,我们还没有雷啊,无法玩

所以我们接下来开始布置雷场,布置雷场呢,我们采用前面所说随机数的概念来随机产生雷,SetMine()函数实现如下

void SetMine(char board[ROWS][COLS], int row, int col)
{
	
	int count = cnt;//cnt为前面宏定义为10;
	while (count)//循环结束条件
	{
		int x = (rand() % 9)+1;//产生1-9的随机数
		int y = (rand() % 9)+1;//因为board[ROWS][COLS]是11*11的,而我们需要9*9的
		if (board[x][y] == '0')//判断是否有雷,若无,则放上一个雷
		{
			board[x][y] = '1';
			count--;//放一个雷就减一,10个雷放完结束
		}
	}
}

传参入下

SetMine(mine, ROW, COL);
//前面所说mine里放雷,所这里传参为mine

排查雷

当我们布置雷也完成之后我们就需要开始排雷了,首先我们得这个函数得提示玩家改干什么

printf("请输入需要排查雷的坐标>;");

接下来玩家需要输入坐标,所以我们得接收

scanf("%d %d", &x, &y);

输入得坐标我们是不是得进行一个判断,判断是否合法

if (x > 0 && x <= row && y > 0 && y <= col)

不合法时我们得给出提示

else printf("输入非法,重新输入:>");

当合法时,我们就得判断输入的该位置是否有雷,有雷我们就的提醒玩家你被炸死,并结束游戏,

我们为了让玩家死的明白,我们把雷的位置给玩家打印出来

if (mine[x][y] == '1')
			{
				printf("你被炸死了\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}

该位置不是雷时,我们就要判断坐标周围有多少雷了,这时候我们创建11*11的作用就体现出来了,因为棋盘为9*9,要判断坐标周围雷的数量,一般是判断周围八个坐标,但是呢,边缘区域没有8个,就比较特殊,情况较为麻烦,而我们创建了11*11,可以有效的防止数组越界额,我们只在中间9*9的棋盘内放置了雷,边缘区域没有雷,所以不影响雷数量的判断

	int n = GetMineCount(mine, x, y);
			show[x][y] = n + '0';//在给玩家所展示的棋盘该位置告诉玩家有多少雷
			DisplayBoard(show, ROW, COL);//打印
			count++;//表示成功排除一个空位

GetMineCount()函数为我们写的判断有几个雷的函数,实现逻辑为周围8个字符的ascll值相加减去8个字符‘0’的ascll值,就为我们‘1’的数量,这里也可以看出把雷设为‘1’,无雷设为‘0’的好处了,下来我们看一下GetMineCount()函数的实现

int GetMineCount(char mine[ROW][COL], 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');
}

配合下图观看,若有三个就放返回3

4659716200794ea2b7dac88d05a80ddd.png

 当我们输入错误,或者成功排除一个空位时,我们还要进行下一次输入所一我们用while()来实现,到这儿我们布置雷的函数全部完成,实现如下

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = 0;
	while (cnt<(row * col - count))//结束循环的条件
	{
		printf("请输入需要排查雷的坐标>;");
		scanf("%d %d", &x, &y);
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("你被炸死了\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}
			int n = GetMineCount(mine, x, y);
			show[x][y] = n + '0';
			DisplayBoard(show, ROW, COL);
			count++;
		}
		else printf("输入非法,重新输入:>");
		if (count == row * col -cnt)
		{
			printf("恭喜你,排雷成功\n");
			DisplayBoard(mine, ROW, COL);
		}
	}
}

至此我们game.c已经全部实现,我们来看一下game()函数的代码

void game()
{
	char mine[ROWS][COLS];
	char show[ROWS][COLS];
	InitBoard(mine,ROWS,COLS,'0');
	InitBoard(show, ROWS, COLS, '*');
	DisplayBoard(show, ROW, COL);
	SetMine(mine, ROW, COL);
	FindMine(mine, show, ROW, COL);
}

以上就是博主的对扫雷游戏的实现,制作不易,各位看官给个三连呗!!!

以上就是博主的对扫雷游戏的实现,制作不易,各位看官给个三连呗!!!

 

完整代码

 

                                                                  game.h

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROW 9         //进行宏定义
#define COL 9		  //
#define ROWS  ROW+2	  //
#define COLS  COL+2	  //
#define cnt 10

//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);
//布置雷场
void SetMine(char board[ROWS][COLS], int row, int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

                                                               game.c 

#include "game.h"

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

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	printf("*****扫雷游戏******\n");
	for (i = 0; i <=col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d", i);
		int j = 1;
		for (j = 1; j <= col;j++)
		{
			printf(" %c", board[i][j]);
		}
		printf("\n");
	}
}

void SetMine(char board[ROWS][COLS], int row, int col)
{
	
	int count = cnt;
	while (count)
	{
		int x = (rand() % 9)+1;//产生1-9的随机数
		int y = (rand() % 9)+1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;
		}
	}
}

int GetMineCount(char mine[ROW][COL], 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 FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = 0;
	while (cnt<(row * col - count))
	{
		printf("请输入需要排查雷的坐标>;");
		scanf("%d %d", &x, &y);
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("你被炸死了\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}
			int n = GetMineCount(mine, x, y);
			show[x][y] = n + '0';
			DisplayBoard(show, ROW, COL);
			count++;
		}
		else printf("输入非法,重新输入:>");
		if (count == row * col -cnt)
		{
			printf("恭喜你,排雷成功\n");
			DisplayBoard(mine, ROW, COL);
		}
	}
}

void game()
{
	char mine[ROWS][COLS];
	char show[ROWS][COLS];
	InitBoard(mine,ROWS,COLS,'0');
	InitBoard(show, ROWS, COLS, '*');
	DisplayBoard(show, ROW, COL);
	SetMine(mine, ROW, COL);
	FindMine(mine, show, ROW, COL);
}

                                                                test.c 

#include "game.h"

void meanu()
{
	printf("*************************\n");
	printf("******  扫雷游戏   ******\n");
	printf("******  1.玩游戏   ******\n");
	printf("******  2.退出游戏 ******\n");
	printf("*************************\n");
}

int main()
{
	int input = 0;
	meanu();
	srand((unsigned int)time(NULL));
	printf("请选择>:");
	do 
	{
		scanf("%d",& input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 2:
			printf("退出游戏");
			break;
		default:printf("非法输入,请重新输入");
		}
	} while (input != 2);
	return 0;
}

 

 

 

  • 18
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

遇事问春风乄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值