package main
const (
MapRow = int32(5)
MapCol = int32(7)
MapRoad = 8
)
const (
KCost1 = 10
KCost2 = 14
KcalcG = 0
)
type Point struct {
x int32
y int32
g int32
h int32
f int32
parent *Point
}
func NewPoint(_x, _y int32) *Point {
this := &Point{}
this.x = _x
this.y = _y
this.f = 0
this.g = 0
this.h = 0
this.parent = nil
return this
}
type Astar struct {
gameMap [5][7]int32
openlist []*Point
closelist []*Point
}
func Abs(a int32) int32 {
if a < 0 {
return -a
}
return a
}
func Arease(ver []*Point, point *Point) []*Point {
intance := make([]*Point, 0)
for i, temp := range ver {
if temp.x == point.x && temp.y == point.y {
intance = append(ver[:i], ver[i+1:]...)
return intance
}
}
return nil
}
func NewAstar(_gameMap [MapRow][MapCol]int32) *Astar {
instance := &Astar{}
instance.gameMap = _gameMap
instance.openlist = make([]*Point, 0)
instance.closelist = make([]*Point, 0)
return instance
}
//func (this *Astar) GetPath(startPoint *Point, endPoint *Point, isIgnore bool) list.List {
//
//}
func (this *Astar) calcG(start *Point, point *Point) int32 {
tmp := int32(0)
tmpG := int32(0)
if (Abs(start.x-point.x) + Abs(start.y-point.y)) == 1 {
tmp = KCost1
} else {
tmp = KCost2
}
if point.parent == nil {
tmpG = KcalcG
} else {
tmpG = point.parent.g
}
return (tmp + tmpG)
}
func (this *Astar) calcH(end *Point, point *Point) int32 {
tmpX := int32(Abs(end.x - point.x))
tmpY := int32(Abs(end.y - point.y))
return (tmpX + tmpY) * KCost1
}
func (this *Astar) calcF(point *Point) int32 {
return point.g + point.h
}
func (this *Astar) isInList(sli []*Point, point *Point) *Point {
for _, tmp := range sli {
if tmp.x == point.x && tmp.y == point.y {
return tmp
}
}
return nil
}
func (this *Astar) getLeastFPoint() *Point {
if this.openlist != nil && len(this.openlist) > 0 {
resPoint := this.openlist[0]
for _, tmp := range this.openlist {
if tmp.f < resPoint.f {
resPoint = tmp
}
}
return resPoint
}
return nil
}
func (this *Astar) isCanreach(point *Point, targer *Point, isIgnore bool) bool {
if targer.x < int32(0) || targer.x > int32(4) ||
targer.y < int32(0) || targer.y > int32(6) ||
this.gameMap[targer.x][targer.y] == 1 ||
(targer.x == point.x && targer.y == point.y) ||
this.isInList(this.closelist, targer) != nil {
return false
} else {
if Abs(point.x-targer.x)+Abs(point.y-targer.y) == 1 {
return true
} else {
if this.gameMap[point.x][targer.y] == 0 && this.gameMap[targer.x][point.y] == 0 {
return true
} else {
return isIgnore
}
}
}
}
func (this *Astar) getSurrounds(point *Point, isIgnore bool) []*Point {
surround := make([]*Point, 0)
for _x := point.x - 1; _x <= point.x+1; _x++ {
for _y := point.y - 1; _y <= point.y+1; _y++ {
if this.isCanreach(point, NewPoint(_x, _y), isIgnore) == true {
surround = append(surround, NewPoint(_x, _y))
}
}
}
return surround
}
func (this *Astar) FindPath(startpoint *Point, endpoint *Point, isIgnore bool) *Point {
this.openlist = append(this.openlist, NewPoint(startpoint.x, startpoint.y))
// if this.Openlist != nil && len(this.Openlist) > 0 {
{
// if tmp != nil {
LOOP:
curPoint := this.getLeastFPoint()
this.closelist = append(this.closelist, curPoint)
// 删除指定元素
this.openlist = Arease(this.openlist, curPoint)
surroundsPoint := this.getSurrounds(curPoint, isIgnore)
for _, targer := range surroundsPoint {
if this.isInList(this.openlist, targer) == nil {
targer.parent = curPoint
targer.g = this.calcG(curPoint, targer)
targer.h = this.calcH(endpoint, targer)
targer.f = this.calcF(targer)
this.openlist = append(this.openlist, targer)
} else {
tempG := this.calcG(curPoint, targer)
if tempG < targer.g {
targer.parent = curPoint
targer.g = tempG
targer.f = this.calcF(targer)
}
}
resPoint := this.isInList(this.openlist, endpoint)
if resPoint != nil {
return resPoint
}
}
if this.openlist != nil && len(this.openlist) > 0 {
goto LOOP
} else {
return nil
}
}
}
func (this *Astar) GetPath(startpoint *Point, endpoint *Point, isIgnore bool) []*Point {
result := this.FindPath(startpoint, endpoint, isIgnore)
path := make([]*Point, 0)
GET:
path = append(path, result)
result = result.parent
if result != nil {
goto GET
}
this.openlist = this.openlist[0:0]
this.closelist = this.closelist[0:0]
return path
}
A*算法的实现_go语言
最新推荐文章于 2023-03-23 19:26:16 发布