mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 14:22:26 +08:00
寻路服务器
This commit is contained in:
@@ -1,196 +0,0 @@
|
||||
package alg
|
||||
|
||||
const (
|
||||
NODE_NONE = iota
|
||||
NODE_START
|
||||
NODE_END
|
||||
NODE_BLOCK
|
||||
)
|
||||
|
||||
type PathNode struct {
|
||||
x int16
|
||||
y int16
|
||||
z int16
|
||||
visit bool
|
||||
state int
|
||||
parent *PathNode
|
||||
}
|
||||
|
||||
type BFS struct {
|
||||
gMap map[int16]map[int16]map[int16]*PathNode
|
||||
startPathNode *PathNode
|
||||
endPathNode *PathNode
|
||||
}
|
||||
|
||||
func NewBFS() (r *BFS) {
|
||||
r = new(BFS)
|
||||
return r
|
||||
}
|
||||
|
||||
func (b *BFS) InitMap(terrain map[MeshMapPos]bool, start MeshMapPos, end MeshMapPos, extR int16) {
|
||||
xLen := end.X - start.X
|
||||
yLen := end.Y - start.Y
|
||||
zLen := end.Z - start.Z
|
||||
dx := int16(1)
|
||||
dy := int16(1)
|
||||
dz := int16(1)
|
||||
if xLen < 0 {
|
||||
dx = -1
|
||||
xLen *= -1
|
||||
}
|
||||
if yLen < 0 {
|
||||
dy = -1
|
||||
yLen *= -1
|
||||
}
|
||||
if zLen < 0 {
|
||||
dz = -1
|
||||
zLen *= -1
|
||||
}
|
||||
b.gMap = make(map[int16]map[int16]map[int16]*PathNode)
|
||||
for x := start.X - extR*dx; x != end.X+extR*dx; x += dx {
|
||||
b.gMap[x] = make(map[int16]map[int16]*PathNode)
|
||||
for y := start.Y - extR*dy; y != end.Y+extR*dy; y += dy {
|
||||
b.gMap[x][y] = make(map[int16]*PathNode)
|
||||
for z := start.Z - extR*dz; z != end.Z+extR*dz; z += dz {
|
||||
state := -1
|
||||
if x == start.X && y == start.Y && z == start.Z {
|
||||
state = NODE_START
|
||||
} else if x == end.X && y == end.Y && z == end.Z {
|
||||
state = NODE_END
|
||||
} else {
|
||||
_, exist := terrain[MeshMapPos{
|
||||
X: x,
|
||||
Y: y,
|
||||
Z: z,
|
||||
}]
|
||||
if exist {
|
||||
state = NODE_NONE
|
||||
} else {
|
||||
state = NODE_BLOCK
|
||||
}
|
||||
}
|
||||
node := &PathNode{
|
||||
x: x,
|
||||
y: y,
|
||||
z: z,
|
||||
visit: false,
|
||||
state: state,
|
||||
parent: nil,
|
||||
}
|
||||
b.gMap[x][y][z] = node
|
||||
if node.state == NODE_START {
|
||||
b.startPathNode = node
|
||||
} else if node.state == NODE_END {
|
||||
b.endPathNode = node
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BFS) GetNeighbor(node *PathNode) []*PathNode {
|
||||
neighborList := make([]*PathNode, 0)
|
||||
dir := [][3]int16{
|
||||
//
|
||||
{1, 0, 0},
|
||||
{-1, 0, 0},
|
||||
{0, 1, 0},
|
||||
{0, -1, 0},
|
||||
{0, 0, 1},
|
||||
{0, 0, -1},
|
||||
//
|
||||
{1, 1, 0},
|
||||
{-1, 1, 0},
|
||||
{-1, -1, 0},
|
||||
{1, -1, 0},
|
||||
//
|
||||
{1, 0, 1},
|
||||
{-1, 0, 1},
|
||||
{-1, 0, -1},
|
||||
{1, 0, -1},
|
||||
//
|
||||
{0, 1, 1},
|
||||
{0, -1, 1},
|
||||
{0, -1, -1},
|
||||
{0, 1, -1},
|
||||
//
|
||||
{1, 1, 1},
|
||||
{1, 1, -1},
|
||||
{1, -1, 1},
|
||||
{1, -1, -1},
|
||||
{-1, 1, 1},
|
||||
{-1, 1, -1},
|
||||
{-1, -1, 1},
|
||||
{-1, -1, -1},
|
||||
}
|
||||
for _, v := range dir {
|
||||
x := node.x + v[0]
|
||||
y := node.y + v[1]
|
||||
z := node.z + v[2]
|
||||
if _, exist := b.gMap[x]; !exist {
|
||||
continue
|
||||
}
|
||||
if _, exist := b.gMap[x][y]; !exist {
|
||||
continue
|
||||
}
|
||||
if _, exist := b.gMap[x][y][z]; !exist {
|
||||
continue
|
||||
}
|
||||
neighborNode := b.gMap[x][y][z]
|
||||
neighborList = append(neighborList, neighborNode)
|
||||
}
|
||||
return neighborList
|
||||
}
|
||||
|
||||
func (b *BFS) GetPath() []*PathNode {
|
||||
path := make([]*PathNode, 0)
|
||||
if b.endPathNode.parent == nil {
|
||||
return nil
|
||||
}
|
||||
node := b.endPathNode
|
||||
for {
|
||||
if node == nil {
|
||||
break
|
||||
}
|
||||
path = append(path, node)
|
||||
node = node.parent
|
||||
}
|
||||
if len(path) == 0 {
|
||||
return nil
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
func (b *BFS) Pathfinding() []MeshMapPos {
|
||||
queue := NewALQueue[*PathNode]()
|
||||
b.startPathNode.visit = true
|
||||
queue.EnQueue(b.startPathNode)
|
||||
for queue.Len() > 0 {
|
||||
head := queue.DeQueue()
|
||||
neighborList := b.GetNeighbor(head)
|
||||
for _, neighbor := range neighborList {
|
||||
if !neighbor.visit && neighbor.state != NODE_BLOCK {
|
||||
neighbor.visit = true
|
||||
neighbor.parent = head
|
||||
queue.EnQueue(neighbor)
|
||||
if neighbor.state == NODE_END {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
path := b.GetPath()
|
||||
if path == nil {
|
||||
return nil
|
||||
}
|
||||
pathVectorList := make([]MeshMapPos, 0)
|
||||
for i := len(path) - 1; i >= 0; i-- {
|
||||
node := path[i]
|
||||
pathVectorList = append(pathVectorList, MeshMapPos{
|
||||
X: node.x,
|
||||
Y: node.y,
|
||||
Z: node.z,
|
||||
})
|
||||
}
|
||||
return pathVectorList
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package alg
|
||||
|
||||
type MeshMapPos struct {
|
||||
X int16
|
||||
Y int16
|
||||
Z int16
|
||||
}
|
||||
Reference in New Issue
Block a user