推箱子
作者:互联网
推箱子的思想
推箱子其实就是一个二维数组,在二维数组中进行判断,当玩家和空地和箱子和成功点的不断变化,而你只需要对玩家能操作的进行编写,就可以推动,而返回就需要对推动的方向和是否推动箱子进行判断,这样你就可以用栈来保存。
#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的,读数据的哪里我没有进行详细的处理,就只能把地图做的工整
标签:箱子,Map,numX,numY,record,PosX,PosY 来源: https://blog.csdn.net/Liaring/article/details/111313007