C语言实现扫雷

本文详细介绍了如何在控制台上实现经典扫雷游戏,包括使用11x11二维数组避免越界问题,数据结构的设计,以及随机放置雷和排雷功能的代码实现。
摘要由CSDN通过智能技术生成

感谢各位大佬支持

继续卑微求赞,各位大佬先赞后看哦~~

 一、扫雷游戏的分析和设计

1.扫雷游戏的功能说明

使用控制台实现经典的扫雷游戏
游戏可以通过菜单实现继续玩或者退出游戏
扫雷的棋盘是9*9的格子
默认随机布置10个雷
可以排查雷
  ◦ 如果位置不是雷,就显示周围有几个雷
  ◦ 如果位置是雷,就炸死游戏结束
  ◦ 把除10个雷之外的所有雷都找出来,排雷成功,游戏结束
游戏界面 : 
             
初始界面   
排雷界面
 排雷失败界面

2.游戏的分析和设计

(1)数据结构的分析

问题一:当我们创建了一个9*9的棋盘格时,用户如果选中了边缘的格子,那我们会统计这个2格子周围8个位置的雷数目,必然会出现越界访问!!!

       所以我们应该创建一个11*11大小的二维数组去存放信息!!!

    

 9*9会越界访问 

改用11*11后

问题二:棋盘上我们用1来表示雷用0表示非雷,当我们排查了一个位置后,我们统计这3*3面积内雷的数量,将数字显示在我们排查出的位置上,如果我们再次排雷,去统计雷数时,如果存放在布 置雷的数组中,这样雷的信息和雷的个数信息就可能或产生混淆和打印上的困难!!!

对应的数组应该是:
char mine[11][11] = {0};//⽤来存放布置好的雷的信息
char show[11][11] = {0};//⽤来存放排查出的雷的个数信息
(2)文件结构设计
我们设计三个文件:
    test.c // ⽂件中写游戏的测试逻辑
    game.c // ⽂件中写游戏中函数的实现等
    game.h //⽂件中写游戏需要的数据类型和函数声明等

3.扫雷游戏代码的实现

首先打印菜单喽~~:

在test文件中实现,选1来玩游戏,选0退出游戏

void menu()
{
	printf("*******************************\n");
	printf("************1.play*************\n");
	printf("************0.exit*************\n");
	printf("*******************************\n");
}


int main()
{
	int input=0;
	do{
		menu();
		printf("请输入:");
		scanf("%d",&input);
		switch(input)
		{
		case 0:
			break;
		case 1:
			game();
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	}while(input);
	
	return 0;
}

然后实现我们的game函数:

先给各位看看game.h的内容方便大家了解已经声明的内容

#include <stdio.h>
#include <stdlib.h>//使用srand函数
#include <time.h>//使用time函数
#include <windows.h>//使用system和sleep函数

#define ROW 9
#define COL 9
#define EasyCount 10

#define ROWS ROW+2
#define COLS COL+2


void InitBoard(char arr[ROWS][COLS], int rows, int cols, char set);
void DisplayBoard(char arr[ROWS][COLS], int row, int col);
void SetMine(char arr[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);

第一步:初始化棋盘!这里库库要提醒大家的是:我们不但要打印用0组成的棋盘,还要打印用*组成的棋盘,所以打印棋盘的参数一定要有一个参数用来控制打印的字符哦~~~,这里的ROW和COLS,我们在game.h中声明!!

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

第二步:打印棋盘!!这里库库给了很多装饰,大家可以根据自己需求给出别的装饰哦

void DisplayBoard(char arr[ROWS][COLS], int row, int col)
{
	printf("----------------------\n");
	printf("-");//装饰
	//先打印列号
	for(int i=0;i<=row;i++)
	{
		printf("%d ",i);
	}
	printf("-");//装饰
	printf("\n");
	
	for(int i=1; i<=row; i++)
	{
		printf("-");//装饰
		printf("%d ", i);
		for(int j=1; j<=col; j++)
		{
			printf("%c ",arr[i][j]);
		}
		printf("-");//装饰
	    printf("\n");
	}
	printf("----------------------\n");//装饰
}

第三步:就是往我们的棋盘中放置雷了~~,我们需要随机生成1~9的数字赋给我们的坐标来实现随机放雷,要用到srand()函数,我们可以将这段代码放在test文件中,使用时间戳来得到随机数

int main()
{
	int input=0;
	srand((unsigned int)time(NULL));//NULL空指针
	do{
		menu();
		printf("请输入:");
		scanf("%d",&input);

然后在game.c文件中实现随机放雷的功能,

void SetMine(char arr[ROWS][COLS], int row, int col)
{
	//布置十个雷
	int count=EasyCount;
	while(count)
	{
		int x = rand()%row+1;//1~9
		int y = rand()%col+1;//1~9
		//成功布置一个雷count--
		if(arr[x][y]== '0')
		{
			arr[x][y] = '1';
			count--;
		}
	}
}

最后一步 : 实现排雷的功能~~,统计周围雷的信息并打印出来~~

static int GetMineCount(char mine[ROWS][COLS], int x, int y)//用了static别的文件就看不到了
{
	int n = mine[x+1][y]+mine[x-1][y]+mine[x][y+1]+mine[x][y-1]+mine[x+1][y-1]+mine[x+1][y+1]+mine[x-1][y+1]+mine[x-1][y-1]-8*'0';
    return n;
}
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while(win < row*col-EasyCount)
	{
		printf("请输入要排查的坐标");
		scanf("%d %d", &x, &y);
		Sleep(10);//有个过度
		system("cls");//清理一下~~
		if(x>=1 && x<= row && y>= 1 && y<= col)
		{
			if(mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				DisplayBoard(mine, ROW, COL);//让我们知道怎么死的
				break;
			}
			else
			{
				int n = GetMineCount(mine, x, y);
                show[x][y] = n + '0';
				DisplayBoard(show, ROW, COL);//打印出雷的信息~~
				win++;
			}
		}
		else
		{
			printf("输入的坐标错误,请重新输入");
		}
	}
	if(win == row*col-EasyCount)
	{
		printf("恭喜你成功排雷\n");
		DisplayBoard(mine, ROW, COL);
	}
}

二、最后给出全部的代码

1.test.c

#include "game.h"
#include "game.c"
void menu()
{
	printf("*******************************\n");
	printf("************1.play*************\n");
	printf("************0.exit*************\n");
	printf("*******************************\n");
}
void game()
{
	char mine [ROWS][COLS];
	char show [ROWS][COLS];
	InitBoard(mine, ROWS, COLS, '0');//'0'初始化棋盘的函数
	InitBoard(show, ROWS, COLS, '*');//'*'展示棋盘的函数
	//打印棋盘
	DisplayBoard(show, ROW, COL);
	//DisplayBoard(mine, ROW, COL);
	//1.布置雷
	SetMine(mine, ROW, COL); 
	//DisplayBoard(mine, ROW, COL);
	//2.排查雷
	FindMine(mine, show, ROW, COL);
}
int main()
{
	int input=0;
	srand((unsigned int)time(NULL));//NULL空指针
	do{
		menu();
		printf("请输入:");
		scanf("%d",&input);
		switch(input)
		{
		case 0:
			break;
		case 1:
			game();
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	}while(input);
	
	return 0;
}

2.game.c

#include "game.h"

void InitBoard(char arr[ROWS][COLS], int rows, int cols, char set)
{
	for(int i=0;i<rows; i++)
	{
		for(int j=0; j<cols; j++)
		{
			arr[i][j]=set;
		}
	}
}
void DisplayBoard(char arr[ROWS][COLS], int row, int col)
{
	printf("----------------------\n");
	printf("-");//装饰
	//先打印列号
	for(int i=0;i<=row;i++)
	{
		printf("%d ",i);
	}
	printf("-");//装饰
	printf("\n");
	
	for(int i=1; i<=row; i++)
	{
		printf("-");//装饰
		printf("%d ", i);
		for(int j=1; j<=col; j++)
		{
			printf("%c ",arr[i][j]);
		}
		printf("-");//装饰
	    printf("\n");
	}
	printf("----------------------\n");//装饰
}


void SetMine(char arr[ROWS][COLS], int row, int col)
{
	//布置十个雷
	int count=EasyCount;
	while(count)
	{
		int x = rand()%row+1;//1~9
		int y = rand()%col+1;//1~9
		//成功布置一个雷count--
		if(arr[x][y]== '0')
		{
			arr[x][y] = '1';
			count--;
		}
	}
}
static int GetMineCount(char mine[ROWS][COLS], int x, int y)//static别的文件看不到了
{
	int n = mine[x+1][y]+mine[x-1][y]+mine[x][y+1]+mine[x][y-1]+mine[x+1][y-1]+mine[x+1][y+1]+mine[x-1][y+1]+mine[x-1][y-1]-8*'0';
    return n;
}
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while(win < row*col-EasyCount)
	{
		printf("请输入要排查的坐标");
		scanf("%d %d", &x, &y);
		Sleep(10);
		system("cls");
		if(x>=1 && x<= row && y>= 1 && y<= col)
		{
			if(mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
			{
				int n = GetMineCount(mine, x, y);
                show[x][y] = n + '0';
				DisplayBoard(show, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("输入的坐标错误,请重新输入");
		}
	}
	if(win == row*col-EasyCount)
	{
		printf("恭喜你成功排雷\n");
		DisplayBoard(mine, ROW, COL);
	}
}

3.game.h

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

#define ROW 9
#define COL 9
#define EasyCount 10

#define ROWS ROW+2
#define COLS COL+2


void InitBoard(char arr[ROWS][COLS], int rows, int cols, char set);
void DisplayBoard(char arr[ROWS][COLS], int row, int col);
void SetMine(char arr[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);

最后库库提醒大家:不要忘记引用自己写好的头文件哦,感谢各位的支持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

库库爱学习

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

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

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

打赏作者

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

抵扣说明:

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

余额充值