先吐槽一句:CODE功能太不给力了,怎么弄怎么崩溃,难道是CSDN也被扫黄打非了???
---------------------------------------------
A星算法的实现原理看这里:http://www.cnblogs.com/technology/archive/2011/05/26/2058842.html
实现部分:
头文件:
/*
A star 算法的基础处理
*/
#ifndef _A_STAR_BASE_H_
#define _A_STAR_BASE_H_
#include "windows.h"
typedef struct _APoint{
int x; // x 坐标
int y; // y 坐标
int type; // 类型
int f; // f = g + h
int g;
int h;
} APoint,*PAPoint;
enum APointType{
APT_UNKNOWN, // 未知状态
APT_OPENED, // 开放列表中
APT_CLOSED, // 关闭列表中
APT_STARTPOINT, // 起始点
APT_ENDPOINT // 结束点
};
class CAStarBase{
public:
CAStarBase();
~CAStarBase();
private:
PAPoint m_pAPointArr;
int m_nAPointArrWidth;
int m_nAPointArrHeight;
PAPoint m_pStartPoint,m_pEndPoint,m_pCurPoint;
char* m_pOldArr;
public:
BOOL Create(char* pDateArr,int nWidth,int nHeight);
void SetStartPoint(int x,int y);
void SetEndPoint(int x,int y);
void SetOpened(int x,int y);
void SetClosed(int x,int y);
void SetCurrent( int x,int y );
void PrintCharArr();
PAPoint CalcNextPoint(PAPoint ptCalc); // 应用迭代的办法进行查询
};
#endif
实现cpp文件:
#include "stdafx.h"
#include "AStarBase.h"
CAStarBase::CAStarBase()
{
m_pAPointArr = NULL;
m_nAPointArrWidth = 0;
m_nAPointArrHeight = 0;
m_pStartPoint = NULL;
m_pEndPoint = NULL;
m_pCurPoint = NULL;
}
CAStarBase::~CAStarBase()
{
}
BOOL CAStarBase::Create( char* pDateArr,int nWidth,int nHeight )
{
if(!pDateArr) return FALSE;
if(nWidth<1 || nHeight<1) return FALSE;
m_pAPointArr = new APoint[nWidth*nHeight];
if(!m_pAPointArr) return FALSE;
m_pOldArr = pDateArr;
m_nAPointArrWidth = nWidth;
m_nAPointArrHeight = nHeight;
// 初始化数组内容
for ( int y = 0;y<m_nAPointArrHeight;y++)
{
for ( int x=0;x<m_nAPointArrWidth;x++)
{
m_pAPointArr[y*m_nAPointArrWidth+x].x = x;
m_pAPointArr[y*m_nAPointArrWidth+x].y = y;
m_pAPointArr[y*m_nAPointArrWidth+x].g = 0;
m_pAPointArr[y*m_nAPointArrWidth+x].f = 0;
m_pAPointArr[y*m_nAPointArrWidth+x].h = 0;
if ( pDateArr[y*m_nAPointArrWidth+x] == '0')
{
m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_OPENED;
}else if ( pDateArr[y*m_nAPointArrWidth+x] == '1')
{
m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_CLOSED;
}else if ( pDateArr[y*m_nAPointArrWidth+x] == 'S')
{
m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_STARTPOINT;
m_pStartPoint = m_pAPointArr + y*m_nAPointArrWidth+x;
m_pCurPoint = m_pStartPoint;
}else if ( pDateArr[y*m_nAPointArrWidth+x] == 'E')
{
m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_ENDPOINT;
m_pEndPoint = m_pAPointArr + y*m_nAPointArrWidth+x;
}else{
m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_UNKNOWN;
}
}
}
return TRUE;
}
void CAStarBase::SetStartPoint( int x,int y )
{
if ( m_pStartPoint && m_pAPointArr[y*m_nAPointArrWidth+x].type!=APT_CLOSED )
{
m_pStartPoint->type = APT_OPENED;
// 设置新的值
m_pStartPoint = m_pAPointArr + y*m_nAPointArrWidth+x;
m_pStartPoint->type = APT_STARTPOINT;
m_pCurPoint = m_pStartPoint;
}
}
void CAStarBase::SetEndPoint( int x,int y )
{
if ( m_pStartPoint && m_pAPointArr[y*m_nAPointArrWidth+x].type!=APT_CLOSED )
{
m_pStartPoint->type = APT_OPENED;
// 设置新的值
m_pStartPoint = m_pAPointArr + y*m_nAPointArrWidth+x;
m_pStartPoint->type = APT_ENDPOINT;
}
}
void CAStarBase::SetCurrent( int x,int y )
{
// if ( m_pAPointArr[y*m_nAPointArrWidth+x].type==APT_OPENED )
{
m_pCurPoint = m_pAPointArr+y*m_nAPointArrWidth+x;
}
}
void CAStarBase::SetOpened( int x,int y )
{
if ( m_pAPointArr[y*m_nAPointArrWidth+x].type!=APT_OPENED )
{
m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_OPENED;
}
}
void CAStarBase::SetClosed( int x,int y )
{
if ( m_pAPointArr[y*m_nAPointArrWidth+x].type!=APT_CLOSED )
{
m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_CLOSED;
}
}
void CAStarBase::PrintCharArr()
{
if ( m_pOldArr )
{
for ( int y=0; y<m_nAPointArrHeight;y++)
{
for ( int x=0;x<m_nAPointArrWidth;x++)
{
printf("%c ",m_pOldArr[x+m_nAPointArrWidth*y]);
}
printf("\r\n");
}
printf("\r\n");
}
}
PAPoint CAStarBase::CalcNextPoint( PAPoint ptCalc )
{
if ( ptCalc == NULL )
{
ptCalc = m_pStartPoint;
}
int x = ptCalc->x;
int y = ptCalc->y;
int dx = m_pEndPoint->x;
int dy = m_pEndPoint->y;
int xmin = x,ymin = y,vmin = 0; // 最优步骤的坐标和值
// 判断是否已经到了最终的位置
if ( (x==dx && abs(y-dy)==1) || (y==dy && abs(x-dx)==1) )
{
return m_pEndPoint;
}
// 上
if ( m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].type == APT_OPENED && y>0)
{
m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].g = 10;
m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].h =
10*(abs(x - dx) + abs(y-1 - dy));
m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].f =
m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].g + m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].h;
if ( vmin==0 )
{
xmin = x;
ymin = y-1;
vmin = m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].f;
}else{
if ( vmin > m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].f )
{
xmin = x;
ymin = y-1;
vmin = m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].f;
}
}
}
// 下
if ( m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].type == APT_OPENED && y<m_nAPointArrHeight)
{
m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].g = 10;
m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].h =
10*(abs(x - dx) + abs(y+1 - dy));
m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].f =
m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].g + m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].h;
if ( vmin==0 )
{
xmin = x;
ymin = y+1;
vmin = m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].f;
}else{
if ( vmin > m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].f )
{
xmin = x;
ymin = y+1;
vmin = m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].f;
}
}
}
// 左
if ( m_pAPointArr[(x-1)+m_nAPointArrWidth*y].type == APT_OPENED && x>0)
{
m_pAPointArr[(x-1)+m_nAPointArrWidth*y].g = 10;
m_pAPointArr[(x-1)+m_nAPointArrWidth*y].h =
10*(abs(x-1 - dx) + abs(y - dy));
m_pAPointArr[(x-1)+m_nAPointArrWidth*y].f =
m_pAPointArr[(x-1)+m_nAPointArrWidth*y].g + m_pAPointArr[(x-1)+m_nAPointArrWidth*y].h;
if ( vmin==0 )
{
xmin = x-1;
ymin = y;
vmin = m_pAPointArr[(x-1)+m_nAPointArrWidth*y].f;
}else{
if ( vmin > m_pAPointArr[(x-1)+m_nAPointArrWidth*y].f )
{
xmin = x-1;
ymin = y;
vmin = m_pAPointArr[(x-1)+m_nAPointArrWidth*y].f;
}
}
}
// 右
if ( m_pAPointArr[(x+1)+m_nAPointArrWidth*y].type == APT_OPENED && x<m_nAPointArrWidth)
{
m_pAPointArr[(x+1)+m_nAPointArrWidth*y].g = 10;
m_pAPointArr[(x+1)+m_nAPointArrWidth*y].h =
10*(abs(x+1 - dx) + abs(y - dy));
m_pAPointArr[(x+1)+m_nAPointArrWidth*y].f =
m_pAPointArr[(x+1)+m_nAPointArrWidth*y].g + m_pAPointArr[(x+1)+m_nAPointArrWidth*y].h;
if ( vmin==0 )
{
xmin = x+1;
ymin = y;
vmin = m_pAPointArr[(x+1)+m_nAPointArrWidth*y].f;
}else{
if ( vmin > m_pAPointArr[(x+1)+m_nAPointArrWidth*y].f )
{
xmin = x+1;
ymin = y;
vmin = m_pAPointArr[(x+1)+m_nAPointArrWidth*y].f;
}
}
}
// 如果有最优点则迭代,则否就返回NULL
if ( vmin )
{
SetCurrent(xmin,ymin);
SetClosed(xmin,ymin);
*(m_pOldArr+xmin+m_nAPointArrWidth*ymin) = '-';
PrintCharArr();
PAPoint pApoint = CalcNextPoint(m_pCurPoint);
if ( pApoint == NULL )
{
SetCurrent(x,y);
SetClosed(xmin,ymin);
*(m_pOldArr+xmin+m_nAPointArrWidth*ymin) = '0';
return CalcNextPoint(m_pCurPoint);
}
return pApoint;
}else{
return NULL;
}
}
测试文件:
// AStarMath.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "AStarBase.h"
CAStarBase Astarbase;
int _tmain(int argc, _TCHAR* argv[])
{
char pBuff[5][7] = {
'0','0','0','1','0','0','0',
'0','1','1','0','0','1','1',
'0','S','1','0','1','E','0',
'0','1','0','0','0','1','0',
'0','0','0','1','0','0','0'
};
Astarbase.Create(&pBuff[0][0],7,5);
Astarbase.PrintCharArr();
PAPoint pPoint = Astarbase.CalcNextPoint(NULL);
if ( pPoint == NULL )
{
printf("no path can arrive!\r\n");
}else{
printf("success arrived!\r\n");
}
getchar();
return 0;
}
结果: