Skip to content

Commit 2c930fa

Browse files
committed
add game files
1 parent 6545e8b commit 2c930fa

33 files changed

+4222
-0
lines changed

astar.js

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// javascript-astar
2+
// http://github.com/bgrins/javascript-astar
3+
// Freely distributable under the MIT License.
4+
// Implements the astar search algorithm in javascript using a binary heap.
5+
6+
var astar = {
7+
init: function(grid) {
8+
for(var x = 0, xl = grid.length; x < xl; x++) {
9+
for(var y = 0, yl = grid[x].length; y < yl; y++) {
10+
var node = grid[x][y];
11+
node.f = 0;
12+
node.g = 0;
13+
node.h = 0;
14+
node.cost = 1;
15+
node.visited = false;
16+
node.closed = false;
17+
node.parent = null;
18+
}
19+
}
20+
},
21+
heap: function() {
22+
return new BinaryHeap(function(node) {
23+
return node.f;
24+
});
25+
},
26+
search: function(grid, start, end, diagonal, heuristic) {
27+
astar.init(grid);
28+
heuristic = heuristic || astar.manhattan;
29+
diagonal = !!diagonal;
30+
31+
var openHeap = astar.heap();
32+
33+
openHeap.push(start);
34+
35+
while(openHeap.size() > 0) {
36+
37+
// Grab the lowest f(x) to process next. Heap keeps this sorted for us.
38+
var currentNode = openHeap.pop();
39+
40+
// End case -- result has been found, return the traced path.
41+
if(currentNode === end) {
42+
var curr = currentNode;
43+
var ret = [];
44+
while(curr.parent) {
45+
ret.push(curr);
46+
curr = curr.parent;
47+
}
48+
return ret.reverse();
49+
}
50+
51+
// Normal case -- move currentNode from open to closed, process each of its neighbors.
52+
currentNode.closed = true;
53+
54+
// Find all neighbors for the current node. Optionally find diagonal neighbors as well (false by default).
55+
var neighbors = astar.neighbors(grid, currentNode, diagonal);
56+
57+
for(var i=0, il = neighbors.length; i < il; i++) {
58+
var neighbor = neighbors[i];
59+
60+
if(neighbor.closed || neighbor.isWall()) {
61+
// Not a valid node to process, skip to next neighbor.
62+
continue;
63+
}
64+
65+
// The g score is the shortest distance from start to current node.
66+
// We need to check if the path we have arrived at this neighbor is the shortest one we have seen yet.
67+
var gScore = currentNode.g + neighbor.cost;
68+
var beenVisited = neighbor.visited;
69+
70+
if(!beenVisited || gScore < neighbor.g) {
71+
72+
// Found an optimal (so far) path to this node. Take score for node to see how good it is.
73+
neighbor.visited = true;
74+
neighbor.parent = currentNode;
75+
neighbor.h = neighbor.h || heuristic(neighbor.pos, end.pos);
76+
neighbor.g = gScore;
77+
neighbor.f = neighbor.g + neighbor.h;
78+
79+
if (!beenVisited) {
80+
// Pushing to heap will put it in proper place based on the 'f' value.
81+
openHeap.push(neighbor);
82+
}
83+
else {
84+
// Already seen the node, but since it has been rescored we need to reorder it in the heap
85+
openHeap.rescoreElement(neighbor);
86+
}
87+
}
88+
}
89+
}
90+
91+
// No result was found - empty array signifies failure to find path.
92+
return [];
93+
},
94+
manhattan: function(pos0, pos1) {
95+
// See list of heuristics: http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html
96+
97+
var d1 = Math.abs (pos1.x - pos0.x);
98+
var d2 = Math.abs (pos1.y - pos0.y);
99+
return d1 + d2;
100+
},
101+
neighbors: function(grid, node, diagonals) {
102+
var ret = [];
103+
var x = node.x;
104+
var y = node.y;
105+
106+
// West
107+
if(grid[x-1] && grid[x-1][y]) {
108+
ret.push(grid[x-1][y]);
109+
}
110+
111+
// East
112+
if(grid[x+1] && grid[x+1][y]) {
113+
ret.push(grid[x+1][y]);
114+
}
115+
116+
// South
117+
if(grid[x] && grid[x][y-1]) {
118+
ret.push(grid[x][y-1]);
119+
}
120+
121+
// North
122+
if(grid[x] && grid[x][y+1]) {
123+
ret.push(grid[x][y+1]);
124+
}
125+
126+
if (diagonals) {
127+
128+
// Southwest
129+
if(grid[x-1] && grid[x-1][y-1]) {
130+
ret.push(grid[x-1][y-1]);
131+
}
132+
133+
// Southeast
134+
if(grid[x+1] && grid[x+1][y-1]) {
135+
ret.push(grid[x+1][y-1]);
136+
}
137+
138+
// Northwest
139+
if(grid[x-1] && grid[x-1][y+1]) {
140+
ret.push(grid[x-1][y+1]);
141+
}
142+
143+
// Northeast
144+
if(grid[x+1] && grid[x+1][y+1]) {
145+
ret.push(grid[x+1][y+1]);
146+
}
147+
148+
}
149+
150+
return ret;
151+
}
152+
};

0 commit comments

Comments
 (0)