A*算法的实现_go语言

1 篇文章 0 订阅
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
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值