-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpath.go
110 lines (90 loc) · 1.89 KB
/
path.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package astar
import (
"container/heap"
"math"
)
type PathSection struct {
start *Grid
end *Grid
}
type PathNode struct {
grid *Grid
parent *PathNode
g float64
h float64
index int
open bool
closed bool
}
type Path struct {
m *Map
root *PathNode
nodes map[*Grid]*PathNode
open priorityQueue
target *Grid
}
func NewPath(m *Map, root *PathNode, target *Grid) *Path {
path := &Path{
m: m,
root: root,
nodes: make(map[*Grid]*PathNode),
open: make([]*PathNode, 0),
target: target,
}
path.nodes[root.grid] = root
heap.Init(&path.open)
// add target to open list
heap.Push(&path.open, path.root)
return path
}
func (p *Path) GetNeighbors(node *PathNode) []*PathNode {
neighborNodes := make([]*PathNode, 0)
neighborGrids := p.m.GetNeighbors(node.grid)
for _, grid := range neighborGrids {
neighborNode := p.CheckPathNode(grid)
if neighborNode.g == 0 {
gridG := LengthValue(node.grid, neighborNode.grid)
neighborNode.g = gridG + node.g
// if grid is slow, double grid's g value
if neighborNode.grid.Slow {
neighborNode.g += gridG
}
}
neighborNodes = append(neighborNodes, neighborNode)
}
return neighborNodes
}
// if node didn't exist, create one and calculate it's h value
func (p *Path) CheckPathNode(grid *Grid) *PathNode {
node, found := p.nodes[grid]
if !found {
node = &PathNode{
grid: grid,
h: LengthValue(grid, p.target),
}
p.nodes[grid] = node
}
return node
}
func LengthValue(from, to *Grid) float64 {
x := from.X - to.X
y := from.Y - to.Y
if x == 0 {
return math.Abs(float64(y))
}
if y == 0 {
return math.Abs(float64(x))
}
max := x
if y > x {
max = y
}
return math.Abs(float64(max)) * math.Sqrt2
// return math.Sqrt(float64(x*x + y*y))
}
func GetSlope(from, to *Grid) float64 {
if from.X == to.X {
return math.Inf(1)
}
return float64(to.Y-from.Y) / float64(to.X-from.X)
}