-
Notifications
You must be signed in to change notification settings - Fork 0
/
a_star.js
95 lines (89 loc) · 3.28 KB
/
a_star.js
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
class A_Star{
constructor(grid, startNode, goalNode){
this.grid = grid
this.startNode = startNode
this.goalNode = goalNode
this.ctx = grid.ctx
this.openSet = []
this.closedSet = []
this.openSet.push(this.startNode)
this.path = []
this.done = false
this.startNode.setOpening(true)
this.goalNode.setOpening(true)
this.startNode.color = '#00FF00'
this.goalNode.color = '#FF0000'
this.speed = 100
this.play = false
}
heuristic(a, b){
let sideA = a.x - b.x;
let sideB = a.y - b.y;
return Math.sqrt(sideA*sideA + sideB*sideB);
}
execute(){
this.play = true
clearInterval(this.loop)
this.loop = setInterval(() => {
this.grid.draw()
if(this.openSet.length > 0 && !this.done){
// Set color
for (let i = 0; i < this.openSet.length; i++) {
this.openSet[i].color = '#0000FF'
}
for (let i = 0; i < this.closedSet.length; i++) {
this.closedSet[i].color = '#000000'
}
// Select suitable node
let select = 0
for (let i = 0; i < this.openSet.length; i++) {
if(this.openSet[i].f < this.openSet[select].f) select = i
}
let current = this.openSet[select]
// Find path
let node = current
this.path.push(node)
while (node.cameFrom){
this.path.push(node.cameFrom)
node.color = '#00FF00'
node = node.cameFrom
}
if(current === this.goalNode){
this.done = true
}
for (let i = this.openSet.length-1; i >= 0; i--) {
if(this.openSet[i] == current){
this.openSet.splice(i, 1)
}
}
this.closedSet.push(current)
for (let i = 0; i < current.neighbors.length; i++) {
let neighbor = current.neighbors[i]
if(!this.closedSet.includes(neighbor)){
let tempCost = current.cost + 1
if(this.openSet.includes(neighbor)){
if(tempCost < neighbor.cost){
neighbor.cost = tempCost
}
}else{
neighbor.cost = tempCost
this.openSet.push(neighbor)
}
neighbor.h = this.heuristic(neighbor, this.goalNode)
neighbor.f = neighbor.cost + neighbor.h
neighbor.cameFrom = current
}
}
}else if(this.done){
this.ctx.fillStyle = '#00FF00'
this.grid.write('COMPLETE')
clearInterval(this.loop);
}
else{
this.ctx.fillStyle = '#FF0000'
this.grid.write('NO SOLUTION')
clearInterval(this.loop);
}
}, this.speed)
}
}