推箱子

推箱子的思想

推箱子其实就是一个二维数组,在二维数组中进行判断,当玩家和空地和箱子和成功点的不断变化,而你只需要对玩家能操作的进行编写,就可以推动,而返回就需要对推动的方向和是否推动箱子进行判断,这样你就可以用栈来保存。

#include <iostream>
#include <conio.h>
#include<vector>
#include<fstream>
using namespace std;
int Map[10][10];
//记录玩家的坐标(行下标和列下标)
int PosX, PosY;
enum DIRCTIO {down_=1,up_,left_,right_};//推动的方向

int NextCustom = 0;

struct MyStruct  //做一个结构体来记录是否推动和方向
{
	DIRCTIO dr;
	bool move;
};
/*0表示空地、1表示墙、2表示玩家、3表示箱子、4表示成功点
				6表示玩家和成功点重合、7表示箱子和成功点重合。*/
bool front_down(int numX,int numY,bool &move)
{
	
	if (0 == Map[PosX + numX][PosY + numY])//当PosX和PosY的前方为空地时
		{
		Map[PosX + numX][PosY + numY] = 2;
			return true;
		}
	else if (4 == Map[PosX + numX][PosY + numY])//当PosX和PosY的前方为成功点时,玩家和成功点相交
		{
		Map[PosX + numX][PosY + numY] = 6;
			return true;
		}
	else if (3 == Map[PosX + numX][PosY + numY])//当PosX和PosY前方是箱子时,就需要进行一次判断
		{
		move = true;
		if (0 == Map[PosX + numX * 2][PosY + numY*2])//箱子前方为空地时
			{
			Map[PosX + numX][PosY + numY] = 2;
			Map[PosX + numX * 2][PosY + numY*2] = 3;
				return true;
			}
		else if (4 == Map[PosX + numX * 2][PosY + numY*2])//箱子前方为成功点时
			{
			Map[PosX + numX][PosY + numY] = 2;
			Map[PosX + numX * 2][PosY + numY*2] = 7;
				return true;
			}
		}
	else if (7 == Map[PosX + numX][PosY + numY])//PosX和PosY的前方为箱子和成功点重合时
		{
		move = true;
		if (0 == Map[PosX + numX * 2][PosY + numY*2])//箱子和成功点重合时前方为空地时
			{
			Map[PosX + numX][PosY + numY] = 6;
			Map[PosX + numX * 2][PosY + numY*2] = 3;
				return true;
			}
		if (4 == Map[PosX + numX * 2][PosY + numY*2])//箱子和成功点重合时前方为成功点时
			{
			Map[PosX + numX][PosY + numY] = 6;
			Map[PosX + numX * 2][PosY + numY * 2] = 7;
				return true;
			}

		}
		return false;
	
}

bool front_down_request(int numX,int numY,bool &move){
	if (front_down(numX, numY,move))//如果能推动,则PosX和PosY的标志改变
	{
		if (2 == Map[PosX][PosY])
			Map[PosX][PosY] = 0;
		else if (6 == Map[PosX][PosY])
			Map[PosX][PosY] = 4;
		PosX += numX;
		PosY += numY;
		return true;
	}
	return false;
}

bool Go_Up_Down_Left_Right(MyStruct my,int numX, int numY)//撤销  numX和numY根据my中的方向
{
	if (0 == Map[PosX + numX][PosY + numY])
	{
		Map[PosX + numX][PosY + numY] = 2;
	}
	else if (4 == Map[PosX + numX][PosY + numY])
	{
		Map[PosX + numX][PosY + numY] = 6;
	}//返回时的后一步比如向左走了一步,PosY发生了改变,PosY+numY你才能找到前一步在根据PosY+numY去赋值


	if (my.move)//如果推动箱子的时候
	{
		if (2 == Map[PosX][PosY])
			Map[PosX][PosY] = 3;
		else if (6 == Map[PosX][PosY])
			Map[PosX][PosY] = 7;  //此时的PosX和PosY是是要返回箱子的位置

		if (3 == Map[PosX - numX][PosY - numY])//
			Map[PosX - numX][PosY - numY] = 0;
		else if (7 == Map[PosX - numX][PosY - numY])
			Map[PosX - numX][PosY - numY] = 4;
			//此时箱子的位置则要变成先前的位置
	}
	else
	{
		if (2 == Map[PosX][PosY])
			Map[PosX][PosY] = 0;
		else if (6 == Map[PosX][PosY])
			Map[PosX][PosY] = 4;//不推动是此时的PosX和PosY只要是返回先前的位置就好了
	}
	PosX += numX;
	PosY += numY;

	return false;
}
void ChangeCustom(int &num)
{
	if (4 != num)
	{
		ifstream input("Map.txt", ios::in);//去读取地图
		if (!input)
		{
			cerr << "Open input file error!" << endl;
		}
		input.seekg((10 * 10 * 2 + 10)*num, ios::beg);
		for (int i = 0; i < 10; i++)
		{
			for (int j = 0; j < 10; j++)
			{
				input >> Map[i][j];//读到数组中
				if (2 == Map[i][j])
				{
					PosX = i;
					PosY = j;
				}//玩家的位置
			}
		}
		num += 1;//记录是第几张图
	}
	else
	{
		system("CLS");
		cout << "恭喜通关" << endl;
	}

}
int main()
{

	//定义一个二维数组表示游戏地图
	vector<MyStruct> record;
	NextCustom = 0;//这个标记是标记箱的数量
	int Change = 0;//游戏的关卡
	while (true)//游戏循环
	{
		//打印地图
		if (0 == NextCustom)//开始的时候就要去读一次地图
		{
			ChangeCustom(Change);
			record.clear();//record记录的是玩家移动的位置和是否推动箱子
		}
		NextCustom = 0;
		for (int i = 0; i < 10; i++)
		{
			for (int j = 0; j < 10; j++)
			{
				if (3 == Map[i][j])
					NextCustom += 1;//还有几个箱子
				switch (Map[i][j])
				{
				case 0:
					cout << "  ";
					break;
				case 1:
					cout << "■";
					break;
				case 2:
					cout << "♀";
					break;
				case 3:
					cout << "※";
						break;
				case 4:
					cout << "☆";
					break;
				case 7:
					cout << "★";
					break;
				case 6:
					cout << "⊙";
					break;
				}
				
			}
			cout << endl;
		}
			
		//按键响应
		//获取从键盘中输入的字符
		int Input = _getch();
		system("CLS");//清屏
		MyStruct st;
		st.move = false;//推动的标记
		switch (Input)
		{
			
		case 's':
		case 'S':
			//判断下一个位置是否能移动:
			/*0表示空地、1表示墙、2表示玩家、3表示箱子、4表示成功点
				6表示玩家和成功点重合、7表示箱子和成功点重合。*/
			if (front_down_request(1, 0, st.move))//推动成功时  st.move会变成true
			{
				st.dr = down_;
				record.push_back(st);//记录
			}
			break;
		case 'w':
		case 'W':
			//判断下一个位置是否能移动:
			if (front_down_request(-1, 0, st.move))
			{
				st.dr = up_;
				record.push_back(st);
			}
			break;
		case 'a':
		case 'A':
			//判断下一个位置是否能移动:
			if (front_down_request(0, -1, st.move))
			{
				st.dr = left_;
				record.push_back(st);
			}	
			break;
		case 'd':
		case 'D':
			//判断下一个位置是否能移动:
			if (front_down_request(0, 1, st.move))
			{
				st.dr = right_;
				record.push_back(st);
			}
			break;
		case 'r':
		case 'R':
			/*vector<MyStruct>::iterator it;
			for (it = record.begin(); it != record.end(); it++)
				cout << (it->dr) << " " << (it->move) << endl;*/
			if (!record.empty()){
				if (down_ == record.back().dr)
					Go_Up_Down_Left_Right(record.back(), -1, 0);//取出record的标记结构体
				else if (up_ == record.back().dr)
					Go_Up_Down_Left_Right(record.back(), 1, 0);
				else if (left_ == record.back().dr)
					Go_Up_Down_Left_Right(record.back(), 0, 1);
				else if (right_ == record.back().dr)
					Go_Up_Down_Left_Right(record.back(), 0, -1);
				//Go_Back(record.back());
				record.pop_back();
			}
			break;
		case 'c':
		case 'C':
			exit(1);
			break;
		case 'q':
		case 'Q':
			NextCustom = 0;
			Change -= 1;
			break;
		}
	}
	return 0;
}

Map.h

1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 0 0 0 0 0 1 1 1
1 1 2 1 1 1 0 0 0 1
1 0 3 0 3 0 0 3 0 1
1 0 4 4 1 0 3 0 1 1
1 1 4 4 1 0 0 0 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 0 2 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 4 3 0 3 4 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 4 3 0 3 4 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 0 2 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 3 0 0 0 4 0 0 1
1 1 0 0 0 0 0 0 0 1
1 4 3 0 0 0 0 0 0 1
1 0 0 1 0 0 0 0 0 1
1 0 0 1 0 3 3 4 0 1
1 0 4 1 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 0 2 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 1
1 0 3 0 0 0 4 0 0 1
1 1 0 0 0 0 0 0 0 1
1 0 3 1 3 0 0 0 0 1
1 0 0 1 0 0 0 0 0 1
1 4 0 0 0 3 1 4 0 1
1 0 4 1 0 0 1 0 0 1
1 1 1 1 1 1 1 1 1 1

这是一个地图10*10的,读数据的哪里我没有进行详细的处理,就只能把地图做的工整

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值