C++实现简单扫雷小游戏

目录

游戏需求文档:

 C++实现:


游戏需求文档:

打开扫雷后进入初始化界面,输入生成的雷的数量并按下回车确认完成地图初始化

地图大小默认为10*10

输入按下回车确认后进入游戏,在10*10的地图的左侧和上测标注坐标,地图未探索区域用’#’表示,每次输入需要先确定操作码,1代表扫雷,0代表标记,例如对(0,7)点标记:

按下回车确认操作后:

被标记点显示为’!’表是该点被标记,若再次对该点进行标记操作则会撤销标记.

若想要扫雷(2,1)点则需使用操作码1:

按下回车确认操作后:

若被扫的点为附近没有地雷则会自动将其上下左右四个方向为探索地区探开,若被探开的点位周围有雷则会停止探索并显示其附近的雷数。

失败:若扫雷位置刚好有地雷则游戏失败

胜利:点开整张地图所有不是地雷的格子(若被标记点实际并不是地雷,则无法胜利)

 C++实现:

#include<iostream>
#include<time.h>
#include<stdlib.h>
//修改Max可以设置地图大小 
#define Max 10
using namespace std;
//初始化答案地图,并设置炸弹数量 
void initMap(int map[Max][Max],int boomNum)
{
	int i,j,z,x,y;
	int a[8] = {-1,-1,-1,0,1,1,1,0};
	int b[8] = {-1,0,1,1,1,0,-1,-1};
	srand((unsigned int)time(NULL));
	for(i=0;i<Max;++i)
		for(j=0;j<Max;++j)
			map[i][j] = 0;
	for(z=0;z<boomNum;++z)
	{
		i = rand()%Max;
		j = rand()%Max;
		if(map[i][j] == 9) ++boomNum;
		else map[i][j] = 9;
	}
	for(i=0;i<Max;++i)
		for(j=0;j<Max;++j)
		{
			if(map[i][j] == 9) continue;
			for(z=0;z<8;++z)
			{
				x = i + a[z];
				y = j + b[z];
				if(x >= 0 && x < Max && y >=0 && y < Max && map[x][y] == 9)
					++map[i][j];
			}
		}
}
//初始化玩家视角地图(全部置9,显示的时候9代表未探索) 
void initPlayerViewMap(int playerViewMap[Max][Max])
{
	int i,j;
	for(i=0;i<Max;++i)
		for(j=0;j<Max;++j)
			playerViewMap[i][j] = 9;
}
//打印玩家视角下的地图 
void printViewMap(int playerViewMap[Max][Max],int map[Max][Max])
{
	int i,j;
	cout<<"   ";
	for(i=0;i<Max;++i)
		cout<<i%10<<" ";
	cout<<endl;
	for(i=0;i<Max;++i)
	{
		cout<<" "<<i%10<<" ";
		for(j=0;j<Max;++j)
		{
			if(playerViewMap[i][j] == 9) cout<<"# ";
			else if(playerViewMap[i][j] == -1) cout<<"! ";
			else cout<<map[i][j]<<" ";
		}
		cout<<endl;
	}
	cout<<"操作码:1->扫雷 0->标记"<<endl;
}
//点击空白位置时递归探索附近所有非雷区域 
void pathFinding(int i,int j,int playerViewMap[Max][Max],int map[Max][Max])
{
	//递归结束判断
	if(i < 0 || i >= Max || j < 0 || j >= Max || playerViewMap[i][j] == 0) return ;
	//探索开玩家视角地图
	playerViewMap[i][j] = map[i][j];
	if(map[i][j] != 0) return ;
	//递归探索上面 
	pathFinding(i-1,j,playerViewMap,map);
	//递归探索右面 
	pathFinding(i,j+1,playerViewMap,map);
	//递归探索下面 
	pathFinding(i+1,j,playerViewMap,map);
	//递归探索左面 
	pathFinding(i,j-1,playerViewMap,map);
}
//操作1(扫雷) 
bool operate_1(int i,int j,int playerViewMap[Max][Max],int map[Max][Max])
{
	if(map[i][j] == 9) return true;
	else if(map[i][j] > 0 && map[i][j] < 9)
		playerViewMap[i][j] = map[i][j];
	else if(map[i][j] == 0)
		pathFinding(i,j,playerViewMap,map);
	return false;
}
//选择操作0(标记) 
void operate_0(int i,int j,int playerViewMap[Max][Max])
{
	if(playerViewMap[i][j] == -1) playerViewMap[i][j] = 9;
	else if(playerViewMap[i][j] == 9) playerViewMap[i][j] = -1;
}
//判断是否获胜 
bool isWin(int playerViewMap[Max][Max],int map[Max][Max])
{
	int i,j;
	for(i=0;i<Max;++i)
		for(j=0;j<Max;++j)
			if(map[i][j] != 9 && (playerViewMap[i][j] == 9 || playerViewMap[i][j] == -1))
				return false;
	return true;
}
//打印答案地图 
void printMap(int map[Max][Max])
{
	int i,j;
	cout<<"   ";
	for(i=0;i<Max;++i)
		cout<<i%10<<" ";
	cout<<endl;
	for(i=0;i<Max;i++)
	{
		cout<<" "<<i%10<<" ";
		for(j=0;j<Max;++j)
		{
			cout<<map[i][j]<<" ";
		}
		cout<<endl;
	}
}

int main()
{
	int map[Max][Max];
	int playerViewMap[Max][Max];
	int i,j,boomNum,operate;
	bool lose = false;
	cout<<"#->未探索 0~8->附近的雷数 !->标记点 9->雷"<<endl;
	cout<<"请输入要生成的雷的数量:";
	cin>>boomNum;
	initMap(map,boomNum);
	initPlayerViewMap(playerViewMap);
	system("cls");
	while(true)
	{
		printViewMap(playerViewMap,map);
		cout<<"请输入操作码以及要操作的点位坐标:";
		cin>>operate>>i>>j;
		if(operate == 1) lose = operate_1(i,j,playerViewMap,map);
		else if(operate == 0) operate_0(i,j,playerViewMap);
		if(lose) break;
		if(isWin(playerViewMap,map)) break;
		system("cls");
	}
	system("cls");
	printMap(map);
	if(lose) cout<<"你输了!"<<endl;
	else cout<<"你赢了!"<<endl;
	system("pause"); 
	return 0;
}

做一个M*N的扫雷游戏,每个方格包含两种状态:关闭和打开,初始化时每个方格都是关闭的,一个打开的方格也会包含两种状态:一个数字或者一个雷。你可以打开一个方格,如果你打开的是一个雷,那么就失败;否则就会打开一个数字,该数字是位于[0,8]的一个整数,该数字表示其所有邻居方格所包含的雷数,应用该信息可以帮助你扫雷。 要求细节: (1) 能够打开一个方格,一个已打开的方格不能再关闭。 (2) 能够标记一个方格,标记方格的含义是对该方格有雷的预测,当一个方格标记后该方格不能被打开,只能执行取消标记的操作,取消标记后才能被打开。 (3) 合理分配各个操作的按键,以及各方格各种状态如何合理显示。 基本要求: 能够给出游戏结果(输,赢,剩余雷数,用掉的时间按秒计)。 游戏界面最好图形化,否则一定要有清楚的字符界面。 输入: 用户鼠标左键点击界面格子打开格子,鼠标右键点击界面格子进行标记。 输出: 界面上用户点击的格子打开,计时器开始计时并显示在界面上。如果不是雷,则显示格子周围格子数目,如果数目是0,则自动打开周围雷数为0的格子,如果是雷,游戏结束。当用户标记一个格子,对应格子显示被标记符号,同时界面显示的剩余雷数减1。当扫完所有雷,玩家获胜,游戏结束。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值