Astar.cpp
#include <math.h>
#include "Astar.h"
#include <iostream>
#include <vector>
static int * maze;
static int cols;
static int lines;
static list< Point * > openlList;
static list< Point * > closeList;
static Point* findPath ( Point * startPoint, Point * endPoint) ;
static Point * getLeastFpoint ( ) ;
static vector< Point * > getSurroundPoints ( const Point * point) ;
static bool isCanreach ( const Point * point, const Point * target) ;
static Point * isInList ( const list< Point * > & list, const Point * point) ;
static int calcG ( Point * temp_start, Point * point) ;
static int calcH ( Point * point, Point * end) ;
static int calcF ( Point * point) ;
Point* AllocPoint ( int x, int y)
{
Point * temp = new Point;
memset ( temp, 0 , sizeof ( Point) ) ;
temp- > x = x;
temp- > y = y;
return temp;
}
void InitAstarMaze ( int * _maze, int _lines, int _colums)
{
maze = _maze;
lines = _lines;
cols = _colums;
}
list< Point * > GetPath ( Point * startPoint, Point * endPoint)
{
Point * result = findPath ( startPoint, endPoint) ;
list< Point * > path;
while ( result)
{
path. push_front ( result) ;
result = result- > parent;
}
return path;
}
static Point* findPath ( Point * startPoint, Point * endPoint)
{
openlList. push_back ( AllocPoint ( startPoint- > x, startPoint- > y) ) ;
while ( ! openlList. empty ( ) )
{
Point * curPoint = getLeastFpoint ( ) ;
openlList. remove ( curPoint) ;
closeList. push_back ( curPoint) ;
vector< Point * > surroundPoints = getSurroundPoints ( curPoint) ;
vector< Point * > :: const_iterator iter;
for ( iter = surroundPoints. begin ( ) ; iter != surroundPoints. end ( ) ; iter++ )
{
Point * target = * iter;
Point * exist = isInList ( openlList, target) ;
if ( ! exist)
{
target- > parent = curPoint;
target- > G = calcG ( curPoint, target) ;
target- > H = calcH ( target, endPoint) ;
target- > F = calcF ( target) ;
openlList. push_back ( target) ;
}
else
{
int tempG = calcG ( curPoint, target) ;
if ( tempG < target- > G)
{
exist- > parent = curPoint;
exist- > G = tempG;
exist- > F = calcF ( target) ;
}
delete target;
}
}
surroundPoints. clear ( ) ;
Point * resPoint = isInList ( openlList, endPoint) ;
if ( resPoint)
{
return resPoint;
}
}
return NULL ;
}
static Point * getLeastFpoint ( )
{
if ( ! openlList. empty ( ) )
{
Point * resPoint = openlList. front ( ) ;
list< Point * > :: const_iterator itor;
for ( itor = openlList. begin ( ) ; itor != openlList. end ( ) ; itor++ )
{
if ( ( * itor) - > F < resPoint- > F)
{
resPoint = * itor;
}
}
return resPoint;
}
return NULL ;
}
static vector< Point * > getSurroundPoints ( const Point * point)
{
vector< Point * > surroundPoints;
for ( int x = point- > x - 1 ; x < point- > x + 1 ; x++ )
{
for ( int y = point- > y - 1 ; y < point- > y + 1 ; y++ )
{
Point * temp = AllocPoint ( x, y) ;
if ( isCanreach ( point, temp) )
{
surroundPoints. push_back ( temp) ;
}
else
{
delete temp;
}
}
}
return surroundPoints;
}
static bool isCanreach ( const Point * point, const Point * target)
{
if ( target- > x< 0 || target- > x> ( lines - 1 )
|| target- > y< 0 || target- > y> ( cols - 1 )
|| maze[ target- > x* cols + target- > y] == 1
|| maze[ target- > x* cols + target- > y] == 2
|| ( target- > x == point- > x && target- > y == point- > y)
|| isInList ( closeList, target) )
{
return false ;
}
if ( ( abs ( point- > x - target- > x) + abs ( point- > y - target- > y) ) == 1 )
{
return true ;
}
else
{
return false ;
}
}
static Point * isInList ( const std:: list< Point * > & list, const Point * point)
{
std:: list< Point * > :: const_iterator itor;
for ( itor = list. begin ( ) ; itor != list. end ( ) ; itor++ )
{
if ( ( * itor) - > x == point- > x && ( * itor) - > y == point- > y)
{
return * itor;
}
}
return NULL ;
}
static int calcG ( Point * temp_start, Point * point)
{
int extraG = ( abs ( point- > x - temp_start- > x) + abs ( point- > y - temp_start- > y) ) == 1 ? kCost1 : kCost2;
int parentG = ( point- > parent == NULL ? NULL : point- > parent- > G) ;
return parentG + extraG;
}
static int calcH ( Point * point, Point * end)
{
return ( int ) sqrt ( ( double ) ( end- > x - point- > x) * ( double ) ( end- > x - point- > x) + ( double ) ( end- > y - point- > y) * ( double ) ( end- > y - point- > y) ) * kCost1;
}
static int calcF ( Point * point)
{
return point- > G + point- > H;
}
void ClearAstarMaze ( )
{
maze = NULL ;
lines = 0 ;
cols = 0 ;
list< Point * > :: iterator itor;
for ( itor = openlList. begin ( ) ; itor != openlList. end ( ) ; )
{
delete * itor;
itor = openlList. erase ( itor) ;
}
for ( itor = closeList. begin ( ) ; itor != closeList. end ( ) ; )
{
delete * itor;
itor = closeList. erase ( itor) ;
}
}
Astar.h
#pragma once
#include <list>
using namespace std;
const int kCost1 = 10 ;
const int kCost2 = 12 ;
typedef struct _Point
{
int x, y;
int F, G, H;
struct _Point * parent;
} Point;
Point* AllocPoint ( int x, int y) ;
void InitAstarMaze ( int * _maze, int _lines, int _colums) ;
list< Point * > GetPath ( Point * startPoint, Point * endPoint) ;
void ClearAstarMaze ( ) ;
main.cpp
#include "Astar.h"
#include <iostream>
#include <list>
#include <Windows.h>
using namespace std;
int map[ 13 ] [ 13 ] =
{
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , } ,
{ 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , } ,
{ 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , } ,
{ 0 , 1 , 0 , 1 , 0 , 1 , 2 , 1 , 0 , 1 , 0 , 1 , 0 , } ,
{ 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , } ,
{ 0 , 1 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , } ,
{ 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , } ,
{ 2 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 , 1 , 1 , 0 , 2 , } ,
{ 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , } ,
{ 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , } ,
{ 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , } ,
{ 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , } ,
{ 0 , 0 , 0 , 0 , 0 , 1 , 3 , 1 , 0 , 0 , 0 , 0 , 0 , } ,
} ;
void AStarTest ( )
{
InitAstarMaze ( & map[ 0 ] [ 0 ] , 13 , 13 ) ;
Point* start = AllocPoint ( 12 , 4 ) ;
Point* end = AllocPoint ( 0 , 0 ) ;
list< Point * > path = GetPath ( start, end) ;
cout << "寻路结果:" << endl;
list< Point * > :: const_iterator iter;
for ( iter = path. begin ( ) ; iter != path. end ( ) ; iter++ )
{
Point * cur = * iter;
cout << '(' << cur- > x << ',' << cur- > y << ')' << endl;
Sleep ( 800 ) ;
}
ClearAstarMaze ( ) ;
}
int main ( )
{
AStarTest ( ) ;
system ( "pause" ) ;
return 0 ;
}