UNPKG

astar-core

Version:

A-Star Algorithm Core

111 lines (110 loc) 3.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const BinaryHeap_1 = require("./BinaryHeap"); function pathTo(node) { let curr = node; const path = []; while (curr.parent) { path.unshift(curr); curr = curr.parent; } return path; } exports.Heuristics = { manhattan: function (pos0, pos1) { 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)); } }; class AStar { static cleanNode(node) { node.f = 0; node.g = 0; node.h = 0; node.visited = false; node.closed = false; node.parent = null; } static search(graph, start, end, options) { graph.cleanDirty(); options = options || {}; const heuristic = options.heuristic || exports.Heuristics.manhattan; const closest = options.closest || false; const openHeap = new BinaryHeap_1.default(function (node) { return node.f; }); let closestNode = start; start.h = heuristic(start, end); graph.markDirty(start); openHeap.push(start); let iterNum = 0; const neighborNodes = new Map(); const currentNodes = new Map(); while (openHeap.size() > 0) { let currentNode = openHeap.pop(); if (currentNode === end) { const result = { path: pathTo(currentNode), currentNodes, neighborNodes, }; return result; } currentNode.closed = true; const neighbors = graph.neighbors(currentNode); for (var i = 0, il = neighbors.length; i < il; ++i) { const neighbor = neighbors[i]; if (neighbor.closed || neighbor.isWall()) { continue; } const gScore = currentNode.g + neighbor.getCost(currentNode); const beenVisited = neighbor.visited; if (!beenVisited || gScore < neighbor.g) { 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 (neighbor.h < closestNode.h || (neighbor.h === closestNode.h && neighbor.g < closestNode.g)) { closestNode = neighbor; } } if (!beenVisited) { openHeap.push(neighbor); } else { openHeap.rescoreElement(neighbor); } } } neighborNodes[iterNum] = neighbors; currentNodes[iterNum] = currentNode; iterNum++; } if (closest) { const result = { path: pathTo(closestNode), currentNodes, neighborNodes, }; return result; } const result = { path: [], currentNodes, neighborNodes, }; return result; } } exports.default = AStar;