#include<iostream>
#include<math.h>
#include<vector>
using namespace std;
const int I = 10;
const int J = 10;
const int start = 55 ;
const int endPoint = 58 ;
bool deadLoop = true;
struct node
{
int m_G;
node* m_parent;
int m_index;
int m_place;//0 1 -1 1:open,-1:close;
};
vector <node*> v_open;
vector <node*> v_close;
const int map[10][10] = {
{0,0,0,0,0,0,0,0,0,0},//0
{0,0,0,0,0,0,0,0,0,0},//1
{0,0,0,0,0,0,0,0,0,0},//2
{0,0,0,0,0,0,0,0,0,1},//3
{1,1,1,1,1,1,1,1,0,1},//4
{0,0,0,0,0,0,0,1,0,0},//5
{0,1,1,1,1,1,1,1,0,0},//6
{0,0,0,0,0,0,0,0,0,1},//7
{0,1,1,1,1,0,1,1,1,1},//8
{0,0,0,0,0,0,0,0,0,0}///9
};
void index2ij(int index,int &i,int &j)
{
i = index / I;
j = index % I;
}
//---------------------------- open 里是否有位置index的结点 -----------/
node* isInOpenVec(int index)
{
vector<node*>::iterator iter;
node* result = NULL;
for (iter=v_open.begin();iter!=v_open.end();iter++)
{
if(index == (*iter)->m_index)
{
result = *iter;
break;
}
}
return result;
}
//---------------------------- close 里是否有位置index的结点 -----------/
node* isInCloseVec(int index)
{
vector<node*>::iterator iter;
node* result = NULL;
for (iter=v_close.begin();iter!=v_close.end();iter++)
{
if(index == (*iter)->m_index)
{
result = *iter;
break;
}
}
return result;
}
//----------------属于左边界的点---
bool isLeftEdge(int index)
{
int leftEdge[10] = {0,10,20,30,40,50,60,70,80,90};
for(int i = 0; i < 10; i ++)
if(index == leftEdge[i])
return true;
return false;
}
//----------------属于右边界的点---
bool isRightEdge(int index)
{
int rightEdge[10] = {9,19,29,39,49,59,69,79,89,99};
for(int i = 0; i < 10; i ++)
if(index == rightEdge[i])
return true;
return false;
}
//---------------------------- 周边的结点链到中心结点parent上 并放到opeen vector里 -----------/
void addNode2Paret(node* parent)
{
parent->m_index;
int index = parent->m_index;
int a[9] = {0, -J-1,-J,-J+1, -1,1, J-1,J,J+1};
int delta[9] = {0,14,10,14,10,10,14,10,14};
for(int i = 1; i <= 8; i++)
{
int b = index+a[i];
if(b >=100 || b < 0 ) //不存在此结点
continue;
if(isLeftEdge(index) && (i == 1 || i == 4 || i == 6))
//左边界不能往左找,
continue;
if(isRightEdge(index) && (i == 3 || i == 5 || i == 8))//右边界不能往右找
continue;
int m,n;
index2ij(b,m,n);
if (map[m][n] != 0)
{
continue;
}
node* pInOpen = isInOpenVec(b);
if(pInOpen) //在v_open里了
{
int newG = delta[i] + parent->m_G;
if(newG < pInOpen->m_G)
{
pInOpen->m_G = newG;
pInOpen->m_parent = parent;
}
continue;
}
if( !isInCloseVec(b)) //没找过该点
{
node *child = new node;
child->m_index = b;
child->m_parent = parent;
child->m_G = parent->m_G + delta[i];
child->m_place = 1;
v_open.push_back(child);
}
}
}
//---------------------------- 两个不同index之间路程代价 -----------/
int distanceFromA2B(int index_a,int index_b)
{
int i1,i2,j1,j2;
i1 = i2 = j1 = j2 = 0;
index2ij(index_a,i1,j1);
index2ij(index_b,i2,j2);
int distance = sqrt( (i1-12)*(i1-12) + (j1-j2)*(j1-j2) ) * 10;
return distance;
}
//---------------------------- 在open 里找一个到终点最小的结点 -----------/
node* findMinNode2EndInOpen()
{
int min = 0xFFFFFFF;
vector<node*>::iterator iter;
node* result = NULL;
int deleteWhere = 0;
for (int i = 0; i < v_open.size();i++)
{
node* p = v_open[i];
int a = distanceFromA2B(p->m_index,endPoint);
a += p->m_G;
cout<<min<<"==="<<a<<endl;
if(min > a)
{
result = p;
min = a;
deleteWhere = i;
}
}
if (v_open.size() > 0)
{
v_open.erase(v_open.begin() + deleteWhere);//删掉后返回值还有 已确认
}
return result;
}
void deleteVec()
{
for (int i = 0; i < (int)v_open.size(); i++)
{
delete v_open[i];
}
for (int i = 0; i < (int)v_close.size(); i++)
{
delete v_close[i];
}
}
void main()
{
node* p = new node;
p->m_G = 0;
p->m_index = start;
p->m_place = 1;
p->m_parent = NULL;
v_close.push_back(p);
//A* 核心 close 放找过的点,open放将要找的点 从open里找出到终点最小代价的值为当前下一搜索点,
//每次搜索当前点的时候,把其四周结点加当进来,且当前点为父结点
//算法参考http://blog.csdn.net/dssdss123/article/details/11494065
do
{
deadLoop = true;
node* pcur = v_close.back();
if(!pcur) //没找到,搜索结束
break;
if(pcur->m_index == endPoint)//已找到,搜索结束
{
deadLoop = false;
break;
}
addNode2Paret(pcur);
node* p = findMinNode2EndInOpen();
if (p)
{
deadLoop = false;
v_close.push_back(p);
}
}while(!deadLoop);//!v_open.empty()
node *pp0 = v_close.back();
cout<<"sssssssssssssssssssssssssssssssssssss";
while (pp0 && !deadLoop)
{
cout<<pp0->m_index<<endl;
pp0 = pp0->m_parent;
}
if (deadLoop)
{
cout<<"no path";
}
deleteVec();
getchar();
}