您的位置:首页 > 大数据 > 人工智能

POJ3322-经典的游戏搜索问题

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

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

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

 

#include <iostream>
#include<algorithm>
#include <vector>
#include <queue>
#include <cstdio>
#include <cstring>
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<Node> 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<r;i++)
{
scanf("%s",map[i]);
}

//for(int i=0;i<r;i++)
//{
//	for(int j=0;j<c;j++)
//	{
//		cout<<map[i][j];
//	}
//	cout<<endl;
//}
//Find the start point and end point.
int flag = 0;
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
if( (map[i][j] == 'X') && ((flag & 1) == 0) )
{
flag = flag | 1;
if( (j+1 < c) && (map[i][j+1] == 'X') )
{
sNode.horizontal =true;
sNode.stand = false;
sNode.lx = i;
sNode.ly = j;
visMat[i][j][1] = 0;
}
else if( (i+1<r) && (map[i+1][j] == 'X') )
{
sNode.horizontal =false;
sNode.stand = false;
sNode.lx = i;
sNode.ly = j;
visMat[i][j][2] = 0;
}

else
{
sNode.stand = true;
sNode.lx = i;
sNode.ly = j;
visMat[i][j][0] = 0;
}
}

else if(map[i][j] == 'O')
{
flag = flag | (1<<1);
ex = i;
ey = j;
}
}

if(flag == 3)
break;
}

////Initialize the visit matrix
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
for(int k=0;k<3;k++)
{
visMat[i][j][k] = MAX;
}
//memset(visMat,MAX,sizeof(visMat));

int step = BFSearch(r, c, sNode, ex,ey);
if(step >= 0)
{
printf("%d\n",step);
}
else
{
printf("Impossible\n");
}

scanf("%d%d",&r,&c);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 POJ 游戏AI策略