POJ3322-经典的游戏搜索问题

2014-11-24 00:04:29 · 作者: · 浏览: 6

临近毕业真是各种琐事多,好不容易写完几万字蛋疼的论文,又接着户口档案挂靠,毕业旅游,20多个离校盖章,签证被check了几个星期还没消息,希望8月初能走啊。

各种事情之下,人就是懒加心散,好久没写代码,也时间写,再说也不知道写啥。突然心血来潮还是刷刷题,不然都忘记代码怎么写了。

Poj33222,Bloxorz,一个很有意思的小游戏,一道中等的搜索题目。该题目也是相关游戏的AI算法的一个典型思路:利用BFS或者DFS来不断搜索下一步所有可能的游戏状态,继而找到解(像推箱子都可以用类似思路解决),为了加速可以利用剪枝,常量表等技巧。不过不知道为啥一开始用Java没过,后来无奈,语法稍微改成C++就过了。。POJ的神奇。。

#include 
#include
#include 
#include 
#include 
#include 
using namespace std;

//------>y
//|
//|
//|
//x


class Node
{
public:
	int lx,ly;
	bool stand;
	bool horizontal;
	int t;

	 Node()
	{

	}
	 
	 Node(int x,int y,bool s,bool h, int t)
	{
		this->lx = x;
		this->ly = y;
		this->stand = s;
		this->horizontal = h;
		this->t = t;
	}
};


char map[501][501];
int visMat[502][502][3] ;//0:stand 1:horizontal 2:vertical
const int MAX =  1<<30;

bool  TestLie(int lx, int ly, bool hFlag, int r, int c)
{
	if(lx<0 || lx >=r || ly<0 || ly>=c)
	{
		return false;
	}

	if(hFlag == true)
	{
		if(ly < c-1)
		{
			if( (map[lx][ly] != '#') && (map[lx][ly+1] != '#') )
				return true;
		}
	}

	else//lie vertically
	{
		if(lx < r-1)
		{
			if( (map[lx][ly] != '#') && (map[lx+1][ly] != '#') )
				return true;
		}
	}

	return false;
}

bool TestStand(int lx, int ly, int r, int c)
{
	if(lx>=0 && ly>=0 && lx < r && ly < c && map[lx][ly]!='#' && map[lx][ly]!='E')
		return true;

	return false;
}

int BFSearch(int r,int c,Node sNode, int ex,int ey)
{
	int visNum = -1;

	queue nodeQueue;
	nodeQueue.push(sNode);

	while(nodeQueue.empty() == false)
	{
		Node node = nodeQueue.front();
		nodeQueue.pop();

		/////////////////Test if it meets the end/////////////////////////
		if(node.stand == true && node.lx == ex && node.ly == ey)
		{
			//Find the solution.
			visNum = visMat[node.lx][node.ly][0];
			break;
		}

		//System.out.println(node.lx+" "+node.ly+" "+node.stand+" "+node.horizontal+" "+node.t);


		//////////////////////////////////////////////////////////////////

		if(node.stand == true)//stand
		{
			//lie vertical up
			if(TestLie((node.lx - 2), node.ly, false, r, c)
				&&
				node.t + 1 < visMat[node.lx-2][node.ly][2])
			{
				Node tNode((node.lx-2), node.ly, false, false, (node.t+1));
				nodeQueue.push(tNode);

				visMat[node.lx-2][node.ly][2] = node.t + 1;
			}

			//lie vertical down
			if(TestLie((node.lx + 1), node.ly, false, r, c)
				&&
				node.t + 1 < visMat[node.lx+1][node.ly][2])
			{
				Node tNode((node.lx+1), node.ly, false, false, (node.t+1));
				nodeQueue.push(tNode);

				visMat[node.lx+1][node.ly][2] = node.t + 1;
			}

			//lie horizontal left
			if(TestLie(node.lx, (node.ly - 2), true, r, c)
				&&
				node.t + 1 < visMat[node.lx][node.ly - 2][1])
			{
				Node tNode(node.lx, (node.ly - 2), false, true, (node.t+1));
				nodeQueue.push(tNode);

				visMat[node.lx][node.ly - 2][1] = node.t + 1;
			}

			//lie horizontal right
			if(TestLie(node.lx, (node.ly + 1), true, r, c)
				&&
				node.t + 1 < visMat[node.lx][node.ly + 1][1])
			{
				Node tNode(node.lx, (node.ly + 1), false, true, (node.t+1));
				nodeQueue.push(tNode);

				visMat[node.lx][node.ly + 1][1] = node.t + 1;
			}

		}

		else//lie
		{
			if(node.horizontal == true)
			{
				//lie horizontal towards up
				if(TestLie((node.lx - 1 ), node.ly, true, r, c)
					&&
					node.t + 1 < visMat[node.lx-1][node.ly][1])
				{
					Node tNode((node.lx-1), node.ly, false, true, (node.t+1));
					nodeQueue.push(tNode);

					visMat[node.lx-1][node.ly][1] = node.t + 1;
				}

				//lie horizontal towards down
				if(TestLie((node.lx + 1 ), node.ly, true, r, c)
					&&
					node.t + 1 < visMat[node.lx+1][node.ly][1])
				{
					Node tNode((node.lx+1), node.ly, false, true, (node.t+1));
					nodeQueue.push(tNode);

					visMat[node.lx+1][node.ly][1] = node.t + 1;
				}


				//stand towards left
				if(TestStand(node.lx, (node.ly-1), r, c)
					&&
					node.t + 1 < visMat[node.lx][node.ly-1][0])
				{
					Node tNode(node.lx, (node.ly-1), true, false, (node.t+1));
					nodeQueue.push(tNode);

					visMat[node.lx][node.ly - 1][0] = node.t + 1;
				}

				//stand towards right
				if(TestStand(node.lx, (node.ly+2), r, c)
					&&
					node.t + 1 < visMat[node.lx][node.ly+2][0])
				{
					Node tNode(node.lx, (node.ly+2), true, false, (node.t+1));
					nodeQueue.push(tNode);

					visMat[node.lx][node.ly + 2][0] = node.t + 1;
				}
			}

			else//lie vertically at first
			{

				//lie vertically towards left
				if(TestLie(node.lx, (node.ly-1), false, r, c)
					&&
					node.t + 1 < visMat[node.lx][node.ly-1][2])
				{
					Node tNode(node.lx, (node.ly-1), false, false, (node.t+1));
					nodeQueue.push(tNode);

					visMat[node.lx][node.ly-1][2] = node.t + 1;
				}

				//lie vertically toward right
				if(TestLie(node.lx, (node.ly+1), false, r, c)
					&&
					node.t + 1 < visMat[node.lx][node.ly+1][2])
				{
					Node tNode(node.lx, (node.ly+1), false, false, (node.t+1));
					nodeQueue.push(tNode);

					visMat[node.lx][node.ly+1][2] = node.t + 1;
				}


				//stand towards up
				if(TestStand( (node.lx-1), node.ly, r, c)
					&&
					node.t + 1 < visMat[node.lx-1][node.ly][0])
				{
					Node tNode((node.lx-1), node.ly, true, false, (node.t+1));
					nodeQueue.push(tNode);

					visMat[node.lx-1][node.ly][0] = node.t + 1;
				}

				//stand towards down
				if(TestStand((node.lx+2), node.ly, r, c)
					&&
					node.t + 1 < visMat[node.lx+2][node.ly][0])
				{
					Node tNode((node.lx+2), node.ly, true, false, (node.t+1));
					nodeQueue.push(tNode);

					visMat[node.lx+2][node.ly][0] = node.t + 1;
				}

			}
		}
	}

	return visNum;
}

int main()
{
	int r,c;
	scanf("%d%d",&r,&c);


	while(r!=0 && c!=0)
	{
		int ex = 0,ey = 0;
		Node sNode;
		sNode.t = 0;

		//Initialize the map
		for(int i=0;i= 0)
				{
					printf("%d\n",step);
				}
				else
				{
					printf("Impossible\n");
				}


				scanf("%d%d",&r,&c);
	}
}