Skip to content

Instantly share code, notes, and snippets.

@m1el
Created September 6, 2013 22:49
Show Gist options
  • Save m1el/6471066 to your computer and use it in GitHub Desktop.
Save m1el/6471066 to your computer and use it in GitHub Desktop.
A* path finding implementation in js
function astar_path(field, start, end) {
start = {x: start.x, y: start.y, cost: 0};
var queue = [start],
visited = {},
node;
visited[start.x + ':' + start.y] = start;
while ((node = queue.shift())) {
var neighbors = get_neighbors(field, node);
if (get_distance(node, end) === 0) {
return get_reverse_path(visited, end);
}
for (var i = 0; i < neighbors.length; i++) {
var n = neighbors[i],
id = n.x + ':' + n.y;
n.cost = node.cost + get_distance(n, node);
n.weight = n.cost + get_distance(n, end);
if (!visited.hasOwnProperty(id) || visited[id].cost > n.cost) {
add_weighted(queue, n);
visited[id] = n;
}
}
}
return null;
}
function get_distance(a, b) {
return Math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
function add_weighted(queue, ref) {
for (var i = 0; i < queue.length; i++) {
if (queue[i].weight >= ref.weight) {
break;
}
}
queue.splice(i, 0, ref);
}
function get_neighbors(field, ref) {
var response = [];
var bot = Math.min(1, field.length - 1 - ref.y);
for (var i = Math.max(-1, -ref.y); i <= bot; i++) {
var y = ref.y + i,
right = Math.min(1, field[y].length - 1 - ref.x);
for (var j = Math.max(-1, -ref.x); j <= right; j++) {
if (i === 0 && j === 0) {
continue;
}
var x = ref.x + j;
if (!field[y][x]) {
response.push({x: x, y: y});
}
}
}
return response;
}
function get_reverse_path(visited, end) {
var path = [end],
node = end,
sortFn = function(a, b) { return a.cost - b.cost; },
getVis = function(a) { return visited[a.x + ':' + a.y]; };
while (node.cost !== 0) {
var neighbours = get_neighbors(field, node);
neighbours = neighbours.map(getVis).sort(sortFn);
node = neighbours[0];
path.push(node);
}
return path.reverse();
}
var field = [
[0,0,0,1,0],
[0,1,0,1,0],
[0,1,0,1,0],
[0,1,0,1,0],
[0,1,0,0,0]
];
console.log(astar_path(field, {x: 0, y: 4}, {x: 4, y: 0}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment