Skip to content

Commit

Permalink
Reset closed nodes...
Browse files Browse the repository at this point in the history
  • Loading branch information
tukkek authored Sep 26, 2024
1 parent cad6791 commit 36a2083
Showing 1 changed file with 78 additions and 76 deletions.
154 changes: 78 additions & 76 deletions astar.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,118 +34,120 @@ function getHeap() {
}

var astar = {
/**
* Perform an A* Search on a graph given a start and end node.
* @param {Graph} graph
* @param {GridNode} start
* @param {GridNode} end
* @param {Object} [options]
* @param {bool} [options.closest] Specifies whether to return the
path to the closest node if the target is unreachable.
* @param {Function} [options.heuristic] Heuristic function (see
* astar.heuristics).
*/
search: function(graph, start, end, options) {
/**
* Perform an A* Search on a graph given a start and end node.
* @param {Graph} graph
* @param {GridNode} start
* @param {GridNode} end
* @param {Object} [options]
* @param {bool} [options.closest] Specifies whether to return the
path to the closest node if the target is unreachable.
* @param {Function} [options.heuristic] Heuristic function (see
* astar.heuristics).
*/
search: function(graph, start, end, options) {
graph.cleanDirty();
options = options || {};
var heuristic = options.heuristic || astar.heuristics.manhattan;
var closest = options.closest || false;

var openHeap = getHeap();
var closestNode = start; // set the start node to be the closest if required

var closedList = [];
start.h = heuristic(start, end);
graph.markDirty(start);

openHeap.push(start);

while (openHeap.size() > 0) {
while(openHeap.size() > 0) {

// Grab the lowest f(x) to process next. Heap keeps this sorted for us.
var currentNode = openHeap.pop();
// Grab the lowest f(x) to process next. Heap keeps this sorted for us.
var currentNode = openHeap.pop();

// End case -- result has been found, return the traced path.
if (currentNode === end) {
return pathTo(currentNode);
}
// End case -- result has been found, return the traced path.
if(currentNode === end) {
while(closedList.length>0)closedList.pop().closed = false;
return pathTo(currentNode);
}

// Normal case -- move currentNode from open to closed, process each of its neighbors.
currentNode.closed = true;
// Normal case -- move currentNode from open to closed, process each of its neighbors.
currentNode.closed = true;
closedList.push(currentNode);

// Find all neighbors for the current node.
var neighbors = graph.neighbors(currentNode);
// Find all neighbors for the current node.
var neighbors = graph.neighbors(currentNode);

for (var i = 0, il = neighbors.length; i < il; ++i) {
var neighbor = neighbors[i];
for (var i = 0, il = neighbors.length; i < il; ++i) {
var neighbor = neighbors[i];

if (neighbor.closed || neighbor.isWall()) {
// Not a valid node to process, skip to next neighbor.
continue;
}
if (neighbor.closed || neighbor.isWall()) {
// Not a valid node to process, skip to next neighbor.
continue;
}

// The g score is the shortest distance from start to current node.
// We need to check if the path we have arrived at this neighbor is the shortest one we have seen yet.
var gScore = currentNode.g + neighbor.getCost(currentNode);
var beenVisited = neighbor.visited;

if (!beenVisited || gScore < neighbor.g) {

// Found an optimal (so far) path to this node. Take score for node to see how good it is.
neighbor.visited = true;
neighbor.parent = currentNode;
neighbor.h = neighbor.h || heuristic(neighbor, end);
neighbor.g = gScore;
neighbor.f = neighbor.g + neighbor.h;
graph.markDirty(neighbor);
if (closest) {
// If the neighbour is closer than the current closestNode or if it's equally close but has
// a cheaper path than the current closest node then it becomes the closest node
if (neighbor.h < closestNode.h || (neighbor.h === closestNode.h && neighbor.g < closestNode.g)) {
closestNode = neighbor;
// The g score is the shortest distance from start to current node.
// We need to check if the path we have arrived at this neighbor is the shortest one we have seen yet.
var gScore = currentNode.g + neighbor.getCost(currentNode);
var beenVisited = neighbor.visited;

if (!beenVisited || gScore < neighbor.g) {

// Found an optimal (so far) path to this node. Take score for node to see how good it is.
neighbor.visited = true;
neighbor.parent = currentNode;
neighbor.h = neighbor.h || heuristic(neighbor, end);
neighbor.g = gScore;
neighbor.f = neighbor.g + neighbor.h;
graph.markDirty(neighbor);
if (closest) {
// If the neighbour is closer than the current closestNode or if it's equally close but has
// a cheaper path than the current closest node then it becomes the closest node
if (neighbor.h < closestNode.h || (neighbor.h === closestNode.h && neighbor.g < closestNode.g)) {
closestNode = neighbor;
}
}

if (!beenVisited) {
// Pushing to heap will put it in proper place based on the 'f' value.
openHeap.push(neighbor);
} else {
// Already seen the node, but since it has been rescored we need to reorder it in the heap
openHeap.rescoreElement(neighbor);
}
}
}

if (!beenVisited) {
// Pushing to heap will put it in proper place based on the 'f' value.
openHeap.push(neighbor);
} else {
// Already seen the node, but since it has been rescored we need to reorder it in the heap
openHeap.rescoreElement(neighbor);
}
}
}
}
while(closedList.length>0)closedList.pop().closed = false;

if (closest) {
return pathTo(closestNode);
return pathTo(closestNode);
}

// No result was found - empty array signifies failure to find path.
return [];
},
// See list of heuristics: http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html
heuristics: {
},
// See list of heuristics: http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html
heuristics: {
manhattan: function(pos0, pos1) {
var d1 = Math.abs(pos1.x - pos0.x);
var d2 = Math.abs(pos1.y - pos0.y);
return d1 + d2;
var d1 = Math.abs(pos1.x - pos0.x);
var d2 = Math.abs(pos1.y - pos0.y);
return d1 + d2;
},
diagonal: function(pos0, pos1) {
var D = 1;
var D2 = Math.sqrt(2);
var d1 = Math.abs(pos1.x - pos0.x);
var d2 = Math.abs(pos1.y - pos0.y);
return (D * (d1 + d2)) + ((D2 - (2 * D)) * Math.min(d1, d2));
var D = 1;
var D2 = Math.sqrt(2);
var d1 = Math.abs(pos1.x - pos0.x);
var d2 = Math.abs(pos1.y - pos0.y);
return (D * (d1 + d2)) + ((D2 - (2 * D)) * Math.min(d1, d2));
}
},
cleanNode: function(node) {
},
cleanNode:function(node){
node.f = 0;
node.g = 0;
node.h = 0;
node.visited = false;
node.closed = false;
node.parent = null;
}
}
};

/**
Expand Down Expand Up @@ -401,4 +403,4 @@ return {
Graph: Graph
};

});
});

0 comments on commit 36a2083

Please sign in to comment.