传统A*算法有一个估价函数int judge(int x,int y)
// 估价函数,估价 x,y 到目的地的距离,估计值必须保证比实际值小
本程序算法假设估价函数估价值总为0,因而抛弃了函数int judge(int x,int y)
只是简单的控制寻路方向优先向目的地靠近。
简单测试速度较快,但目前不能保证寻路的路径一定是最短的,也没有经过复杂路况测试保证能寻路成功(应该没问题^_^)
// find_path.h: interface for the find_path class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_FIND_PATH_H__6D68E153_6763_4EA4_81B7_8256024B5E23__INCLUDED_)
#define AFX_FIND_PATH_H__6D68E153_6763_4EA4_81B7_8256024B5E23__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include
#include
//--寻路算法(最短路径???)
//--从A*算法演变来的
//--就叫AB算法好了
typedef class find_path find_pathAB;
class find_path
{
//--判断某点能否到达的函数指针定义
typedef bool (*pf_go_test)(int, int);
//--函数指针
pf_go_test _pf_go_test;
void set_pf(pf_go_test pf) { if (pf) _pf_go_test = pf; };
//--判断某点能否到达
//--需要用户提供该函数
inline bool go_test(int x, int y)
{
if (x < 0 || y < 0
|| x >= w || y >= h) return false;
//--
if (_pf_go_test) return _pf_go_test(x, y);
//--默认都能到达
return true;
}
public:
void init(int width, int height, pf_go_test pf = NULL);
void reset();
//--返回找到的最短路径步数
//--并将找到的最短路径存储在path_p
int go(int x0, int y0, int x1, int y1, pf_go_test pf = NULL);
public:
struct path_z { int x, y; };
int path_t; //--找到的最短路径步数
path_z *path_p; //--找到的最短路径
private:
enum
{
OPEN = 0x01,
CLOSE = 0x02,
OPEN_CLOSE = OPEN|CLOSE,
}__CONST;
struct path_node;
typedef struct path_node T;
struct path_node
{
short x, y; //--节点坐标
short flag; //--Open/Close标志
T * parent;
T * next;
};
T * node_map; //--对应地图中每个节点
T * node_close; //--保存处理过的节点(node_map)
T * node_open; //--保存待处理的节点(node_map)
T * node_next; //--node_open链的最后一个
int w; //--地图的宽度
int h; //--地图的高度
int path_max; //--w*h
public:
//--将节点加入OPEN表
//--先进先出(不排序)
inline void AddToOpenQueue(T * node)
{
node->flag = OPEN; // 记录Open标志
if (NULL == node_open)
{
node_open = node;
//node_next = node;
}
else
{
node_next->next = node;
//node_next = node;
}
node_next = node;
}
//--从OPEN表取节点并将节点加入CLOSE表
//--(取节点时负责处理周边节点)
inline T * GetFromOpenQueue()
{
if (NULL == node_open
// || node_open->flag & CLOSE //--不可能已经在Close中
) return NULL;
T * it = node_open;
//--从OPEN表移走
//it->flag = 0;
node_open = node_open->next;
//--加入CLOSE表
it->next = node_close;
it->flag = CLOSE;
node_close = it;
return node_close;
}
//--尝试下一步移动到 x,y 可行否
inline void TryTile(int x, int y, T * parent)
{
T * it = node_map + w*y + x;
if (
//&&
//--速度比较快
0 == (it->flag & OPEN_CLOSE)//--不在OPEN/CLOSE表中
&&
true == go_test(x, y) //--该点可以到达
)
{
it->parent = parent;
AddToOpenQueue(it); //--将节点加入Open队列
}
}
public:
find_path();
//virtual
~find_path();
};
#endif // !defined(AFX_FIND_PATH_H__6D68E153_6763_4EA4_81B7_8256024B5E23__INCLUDED_)