From 1db40356a21e8e429530a776b911eb9d3bc7a62d Mon Sep 17 00:00:00 2001 From: takenaoki Date: Wed, 21 Jun 2017 16:03:56 +0900 Subject: [PATCH 1/5] fix weight calc --- .gitignore | 1 + astar.js | 436 +++++++++++++++++++++++++---------------------------- 2 files changed, 209 insertions(+), 228 deletions(-) diff --git a/.gitignore b/.gitignore index fd4f2b0..22d59e5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules .DS_Store +.idea diff --git a/astar.js b/astar.js index 8a25115..108cc98 100644 --- a/astar.js +++ b/astar.js @@ -4,55 +4,192 @@ // Implements the astar search algorithm in javascript using a Binary Heap. // Includes Binary Heap (with modifications) from Marijn Haverbeke. // http://eloquentjavascript.net/appendix2.html -(function(definition) { - /* global module, define */ - if (typeof module === 'object' && typeof module.exports === 'object') { - module.exports = definition(); - } else if (typeof define === 'function' && define.amd) { - define([], definition); - } else { - var exports = definition(); - window.astar = exports.astar; - window.Graph = exports.Graph; - } -})(function() { - -function pathTo(node) { - var curr = node; - var path = []; - while (curr.parent) { - path.unshift(curr); - curr = curr.parent; + +function BinaryHeap(scoreFunction) { + this.content = []; + this.scoreFunction = scoreFunction; +} + +BinaryHeap.prototype = { + push: function(element) { + // Add the new element to the end of the array. + this.content.push(element); + + // Allow it to sink down. + this.sinkDown(this.content.length - 1); + }, + pop: function() { + // Store the first element so we can return it later. + const result = this.content[0]; + // Get the element at the end of the array. + const end = this.content.pop(); + // If there are any elements left, put the end element at the + // start, and let it bubble up. + if (this.content.length > 0) { + this.content[0] = end; + this.bubbleUp(0); + } + return result; + }, + remove: function(node) { + const i = this.content.indexOf(node); + + // When it is found, the process seen in 'pop' is repeated + // to fill up the hole. + const end = this.content.pop(); + + if (i !== this.content.length - 1) { + this.content[i] = end; + + if (this.scoreFunction(end) < this.scoreFunction(node)) { + this.sinkDown(i); + } + else { + this.bubbleUp(i); + } + } + }, + size: function() { + return this.content.length; + }, + rescoreElement: function(node) { + this.sinkDown(this.content.indexOf(node)); + }, + sinkDown: function(n) { + // Fetch the element that has to be sunk. + const element = this.content[n]; + + // When at 0, an element can not sink any further. + while (n > 0) { + // Compute the parent element's index, and fetch it. + const parentN = ((n + 1) >> 1) - 1; + const parent = this.content[parentN]; + // Swap the elements if the parent is greater. + if (this.scoreFunction(element) < this.scoreFunction(parent)) { + this.content[parentN] = element; + this.content[n] = parent; + // Update 'n' to continue at the new position. + n = parentN; + } + // Found a parent that is less, no need to sink any further. + else { + break; + } + } + }, + bubbleUp: function(n) { + // Look up the target element and its score. + const length = this.content.length; + const element = this.content[n]; + const elemScore = this.scoreFunction(element); + + let shouldLoop = true; + while (shouldLoop) { + // Compute the indices of the child elements. + const child2N = (n + 1) << 1; + const child1N = child2N - 1; + // This is used to store the new position of the element, if any. + let swap = null; + let child1Score; + // If the first child exists (is inside the array)... + if (child1N < length) { + // Look it up and compute its score. + const child1 = this.content[child1N]; + child1Score = this.scoreFunction(child1); + + // If the score is less than our element's, we need to swap. + if (child1Score < elemScore) { + swap = child1N; + } + } + + // Do the same checks for the other child. + if (child2N < length) { + const child2 = this.content[child2N]; + const child2Score = this.scoreFunction(child2); + if (child2Score < (swap === null ? elemScore : child1Score)) { + swap = child2N; + } + } + + // If the element needs to be moved, swap it, and continue. + if (swap !== null) { + this.content[n] = this.content[swap]; + this.content[swap] = element; + n = swap; + } + // Otherwise, we are done. + else { + shouldLoop = false; + } + } } - return path; +}; + +function GridNode(x, y, weight) { + this.x = x; + this.y = y; + this.weight = weight; } -function getHeap() { - return new BinaryHeap(function(node) { - return node.f; - }); +/** + * A graph memory structure + * @param {Array} gridIn 2D array of input weights + * @param {Object} [options] + * @param {bool} [options.diagonal] Specifies whether diagonal moves are allowed + */ +export function Graph(gridIn, options) { + options = options || {}; + this.nodes = []; + this.diagonal = !!options.diagonal; + this.grid = []; + for (let x = 0; x < gridIn.length; x++) { + this.grid[x] = []; + + for (let y = 0, row = gridIn[x]; y < row.length; y++) { + const node = new GridNode(x, y, row[y]); + this.grid[x][y] = node; + this.nodes.push(node); + } + } + this.init(); } -var astar = { +export const astar = { + pathTo: function(node) { + let curr = node; + const path = []; + while (curr.parent) { + path.unshift(curr); + curr = curr.parent; + } + return path; + }, + getHeap: function() { + return new BinaryHeap(function(node) { + return node.f; + }); + }, + /** - * 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). - */ + * 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; + const heuristic = options.heuristic || astar.heuristics.manhattan; + const closest = options.closest || false; - var openHeap = getHeap(); - var closestNode = start; // set the start node to be the closest if required + const openHeap = this.getHeap(); + let closestNode = start; // set the start node to be the closest if required start.h = heuristic(start, end); graph.markDirty(start); @@ -60,23 +197,22 @@ var astar = { openHeap.push(start); while (openHeap.size() > 0) { - // Grab the lowest f(x) to process next. Heap keeps this sorted for us. - var currentNode = openHeap.pop(); + const currentNode = openHeap.pop(); // End case -- result has been found, return the traced path. if (currentNode === end) { - return pathTo(currentNode); + return this.pathTo(currentNode); } // Normal case -- move currentNode from open to closed, process each of its neighbors. currentNode.closed = true; // Find all neighbors for the current node. - var neighbors = graph.neighbors(currentNode); + const neighbors = graph.neighbors(currentNode); - for (var i = 0, il = neighbors.length; i < il; ++i) { - var neighbor = neighbors[i]; + for (let i = 0, il = neighbors.length; i < il; ++i) { + const neighbor = neighbors[i]; if (neighbor.closed || neighbor.isWall()) { // Not a valid node to process, skip to next neighbor. @@ -85,11 +221,10 @@ var astar = { // 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; + const gScore = currentNode.g + neighbor.getCost(currentNode); + const 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; @@ -108,7 +243,8 @@ var astar = { if (!beenVisited) { // Pushing to heap will put it in proper place based on the 'f' value. openHeap.push(neighbor); - } else { + } + else { // Already seen the node, but since it has been rescored we need to reorder it in the heap openHeap.rescoreElement(neighbor); } @@ -117,7 +253,7 @@ var astar = { } if (closest) { - return pathTo(closestNode); + return this.pathTo(closestNode); } // No result was found - empty array signifies failure to find path. @@ -126,15 +262,15 @@ var astar = { // 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); + const d1 = Math.abs(pos1.x - pos0.x); + const 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); + const D = 1; + const D2 = Math.sqrt(2); + const d1 = Math.abs(pos1.x - pos0.x); + const d2 = Math.abs(pos1.y - pos0.y); return (D * (d1 + d2)) + ((D2 - (2 * D)) * Math.min(d1, d2)); } }, @@ -148,38 +284,15 @@ var astar = { } }; -/** - * A graph memory structure - * @param {Array} gridIn 2D array of input weights - * @param {Object} [options] - * @param {bool} [options.diagonal] Specifies whether diagonal moves are allowed - */ -function Graph(gridIn, options) { - options = options || {}; - this.nodes = []; - this.diagonal = !!options.diagonal; - this.grid = []; - for (var x = 0; x < gridIn.length; x++) { - this.grid[x] = []; - - for (var y = 0, row = gridIn[x]; y < row.length; y++) { - var node = new GridNode(x, y, row[y]); - this.grid[x][y] = node; - this.nodes.push(node); - } - } - this.init(); -} - Graph.prototype.init = function() { this.dirtyNodes = []; - for (var i = 0; i < this.nodes.length; i++) { + for (let i = 0; i < this.nodes.length; i++) { astar.cleanNode(this.nodes[i]); } }; Graph.prototype.cleanDirty = function() { - for (var i = 0; i < this.dirtyNodes.length; i++) { + for (let i = 0; i < this.dirtyNodes.length; i++) { astar.cleanNode(this.dirtyNodes[i]); } this.dirtyNodes = []; @@ -190,10 +303,10 @@ Graph.prototype.markDirty = function(node) { }; Graph.prototype.neighbors = function(node) { - var ret = []; - var x = node.x; - var y = node.y; - var grid = this.grid; + const ret = []; + const x = node.x; + const y = node.y; + const grid = this.grid; // West if (grid[x - 1] && grid[x - 1][y]) { @@ -241,32 +354,26 @@ Graph.prototype.neighbors = function(node) { }; Graph.prototype.toString = function() { - var graphString = []; - var nodes = this.grid; - for (var x = 0; x < nodes.length; x++) { - var rowDebug = []; - var row = nodes[x]; - for (var y = 0; y < row.length; y++) { + const graphString = []; + const nodes = this.grid; + for (let x = 0; x < nodes.length; x++) { + const rowDebug = []; + const row = nodes[x]; + for (let y = 0; y < row.length; y++) { rowDebug.push(row[y].weight); } - graphString.push(rowDebug.join(" ")); + graphString.push(rowDebug.join(' ')); } - return graphString.join("\n"); + return graphString.join('\n'); }; -function GridNode(x, y, weight) { - this.x = x; - this.y = y; - this.weight = weight; -} - GridNode.prototype.toString = function() { - return "[" + this.x + " " + this.y + "]"; + return `[${this.x} ${this.y}]`; }; GridNode.prototype.getCost = function(fromNeighbor) { // Take diagonal weight into consideration. - if (fromNeighbor && fromNeighbor.x != this.x && fromNeighbor.y != this.y) { + if (fromNeighbor && fromNeighbor.x !== this.x && fromNeighbor.y !== this.y) { return this.weight * 1.41421; } return this.weight; @@ -275,130 +382,3 @@ GridNode.prototype.getCost = function(fromNeighbor) { GridNode.prototype.isWall = function() { return this.weight === 0; }; - -function BinaryHeap(scoreFunction) { - this.content = []; - this.scoreFunction = scoreFunction; -} - -BinaryHeap.prototype = { - push: function(element) { - // Add the new element to the end of the array. - this.content.push(element); - - // Allow it to sink down. - this.sinkDown(this.content.length - 1); - }, - pop: function() { - // Store the first element so we can return it later. - var result = this.content[0]; - // Get the element at the end of the array. - var end = this.content.pop(); - // If there are any elements left, put the end element at the - // start, and let it bubble up. - if (this.content.length > 0) { - this.content[0] = end; - this.bubbleUp(0); - } - return result; - }, - remove: function(node) { - var i = this.content.indexOf(node); - - // When it is found, the process seen in 'pop' is repeated - // to fill up the hole. - var end = this.content.pop(); - - if (i !== this.content.length - 1) { - this.content[i] = end; - - if (this.scoreFunction(end) < this.scoreFunction(node)) { - this.sinkDown(i); - } else { - this.bubbleUp(i); - } - } - }, - size: function() { - return this.content.length; - }, - rescoreElement: function(node) { - this.sinkDown(this.content.indexOf(node)); - }, - sinkDown: function(n) { - // Fetch the element that has to be sunk. - var element = this.content[n]; - - // When at 0, an element can not sink any further. - while (n > 0) { - - // Compute the parent element's index, and fetch it. - var parentN = ((n + 1) >> 1) - 1; - var parent = this.content[parentN]; - // Swap the elements if the parent is greater. - if (this.scoreFunction(element) < this.scoreFunction(parent)) { - this.content[parentN] = element; - this.content[n] = parent; - // Update 'n' to continue at the new position. - n = parentN; - } - // Found a parent that is less, no need to sink any further. - else { - break; - } - } - }, - bubbleUp: function(n) { - // Look up the target element and its score. - var length = this.content.length; - var element = this.content[n]; - var elemScore = this.scoreFunction(element); - - while (true) { - // Compute the indices of the child elements. - var child2N = (n + 1) << 1; - var child1N = child2N - 1; - // This is used to store the new position of the element, if any. - var swap = null; - var child1Score; - // If the first child exists (is inside the array)... - if (child1N < length) { - // Look it up and compute its score. - var child1 = this.content[child1N]; - child1Score = this.scoreFunction(child1); - - // If the score is less than our element's, we need to swap. - if (child1Score < elemScore) { - swap = child1N; - } - } - - // Do the same checks for the other child. - if (child2N < length) { - var child2 = this.content[child2N]; - var child2Score = this.scoreFunction(child2); - if (child2Score < (swap === null ? elemScore : child1Score)) { - swap = child2N; - } - } - - // If the element needs to be moved, swap it, and continue. - if (swap !== null) { - this.content[n] = this.content[swap]; - this.content[swap] = element; - n = swap; - } - // Otherwise, we are done. - else { - break; - } - } - } -}; - -return { - astar: astar, - Graph: Graph -}; - -}); \ No newline at end of file From f05aad215503b81ea6d5108e028c13c5e77e4a3f Mon Sep 17 00:00:00 2001 From: takenaoki Date: Wed, 21 Jun 2017 16:17:33 +0900 Subject: [PATCH 2/5] fix prototype --- astar.js | 274 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 138 insertions(+), 136 deletions(-) diff --git a/astar.js b/astar.js index 108cc98..d797ff0 100644 --- a/astar.js +++ b/astar.js @@ -5,6 +5,144 @@ // Includes Binary Heap (with modifications) from Marijn Haverbeke. // http://eloquentjavascript.net/appendix2.html +function GridNode(x, y, weight) { + this.x = x; + this.y = y; + this.weight = weight; + this.clean(); +} + +GridNode.prototype.toString = function() { + return `[${this.x} ${this.y}]`; +}; + +GridNode.prototype.getCost = function(fromNeighbor) { + // Take diagonal weight into consideration. + if (fromNeighbor && fromNeighbor.x !== this.x && fromNeighbor.y !== this.y) { + return this.weight * 1.41421; + } + return this.weight; +}; + +GridNode.prototype.isWall = function() { + return this.weight === 0; +}; + +GridNode.prototype.clean = function() { + this.f = 0; + this.g = 0; + this.h = 0; + this.visited = false; + this.closed = false; + this.parent = null; +}; + +/** + * A graph memory structure + * @param {Array} gridIn 2D array of input weights + * @param {Object} [options] + * @param {bool} [options.diagonal] Specifies whether diagonal moves are allowed + */ +export function Graph(gridIn, options) { + options = options || {}; + this.nodes = []; + this.diagonal = !!options.diagonal; + this.grid = []; + for (let x = 0; x < gridIn.length; x++) { + this.grid[x] = []; + + for (let y = 0, row = gridIn[x]; y < row.length; y++) { + const node = new GridNode(x, y, row[y]); + this.grid[x][y] = node; + this.nodes.push(node); + } + } + this.init(); +} + +Graph.prototype.init = function() { + this.dirtyNodes = []; + for (let i = 0; i < this.nodes.length; i++) { + this.nodes[i].clean(); + } +}; + +Graph.prototype.cleanDirty = function() { + for (let i = 0; i < this.dirtyNodes.length; i++) { + this.dirtyNodes[i].clean(); + } + this.dirtyNodes = []; +}; + +Graph.prototype.markDirty = function(node) { + this.dirtyNodes.push(node); +}; + +Graph.prototype.neighbors = function(node) { + const ret = []; + const x = node.x; + const y = node.y; + const grid = this.grid; + + // West + if (grid[x - 1] && grid[x - 1][y]) { + ret.push(grid[x - 1][y]); + } + + // East + if (grid[x + 1] && grid[x + 1][y]) { + ret.push(grid[x + 1][y]); + } + + // South + if (grid[x] && grid[x][y - 1]) { + ret.push(grid[x][y - 1]); + } + + // North + if (grid[x] && grid[x][y + 1]) { + ret.push(grid[x][y + 1]); + } + + if (this.diagonal) { + // Southwest + if (grid[x - 1] && grid[x - 1][y - 1]) { + ret.push(grid[x - 1][y - 1]); + } + + // Southeast + if (grid[x + 1] && grid[x + 1][y - 1]) { + ret.push(grid[x + 1][y - 1]); + } + + // Northwest + if (grid[x - 1] && grid[x - 1][y + 1]) { + ret.push(grid[x - 1][y + 1]); + } + + // Northeast + if (grid[x + 1] && grid[x + 1][y + 1]) { + ret.push(grid[x + 1][y + 1]); + } + } + + return ret; +}; + +Graph.prototype.toString = function() { + const graphString = []; + const nodes = this.grid; + for (let x = 0; x < nodes.length; x++) { + const rowDebug = []; + const row = nodes[x]; + for (let y = 0; y < row.length; y++) { + rowDebug.push(row[y].weight); + } + graphString.push(rowDebug.join(' ')); + } + return graphString.join('\n'); +}; + function BinaryHeap(scoreFunction) { this.content = []; this.scoreFunction = scoreFunction; @@ -126,35 +264,6 @@ BinaryHeap.prototype = { } }; -function GridNode(x, y, weight) { - this.x = x; - this.y = y; - this.weight = weight; -} - -/** - * A graph memory structure - * @param {Array} gridIn 2D array of input weights - * @param {Object} [options] - * @param {bool} [options.diagonal] Specifies whether diagonal moves are allowed - */ -export function Graph(gridIn, options) { - options = options || {}; - this.nodes = []; - this.diagonal = !!options.diagonal; - this.grid = []; - for (let x = 0; x < gridIn.length; x++) { - this.grid[x] = []; - - for (let y = 0, row = gridIn[x]; y < row.length; y++) { - const node = new GridNode(x, y, row[y]); - this.grid[x][y] = node; - this.nodes.push(node); - } - } - this.init(); -} - export const astar = { pathTo: function(node) { let curr = node; @@ -273,112 +382,5 @@ export const astar = { const d2 = Math.abs(pos1.y - pos0.y); return (D * (d1 + d2)) + ((D2 - (2 * D)) * Math.min(d1, d2)); } - }, - cleanNode: function(node) { - node.f = 0; - node.g = 0; - node.h = 0; - node.visited = false; - node.closed = false; - node.parent = null; - } -}; - -Graph.prototype.init = function() { - this.dirtyNodes = []; - for (let i = 0; i < this.nodes.length; i++) { - astar.cleanNode(this.nodes[i]); - } -}; - -Graph.prototype.cleanDirty = function() { - for (let i = 0; i < this.dirtyNodes.length; i++) { - astar.cleanNode(this.dirtyNodes[i]); - } - this.dirtyNodes = []; -}; - -Graph.prototype.markDirty = function(node) { - this.dirtyNodes.push(node); -}; - -Graph.prototype.neighbors = function(node) { - const ret = []; - const x = node.x; - const y = node.y; - const grid = this.grid; - - // West - if (grid[x - 1] && grid[x - 1][y]) { - ret.push(grid[x - 1][y]); - } - - // East - if (grid[x + 1] && grid[x + 1][y]) { - ret.push(grid[x + 1][y]); } - - // South - if (grid[x] && grid[x][y - 1]) { - ret.push(grid[x][y - 1]); - } - - // North - if (grid[x] && grid[x][y + 1]) { - ret.push(grid[x][y + 1]); - } - - if (this.diagonal) { - // Southwest - if (grid[x - 1] && grid[x - 1][y - 1]) { - ret.push(grid[x - 1][y - 1]); - } - - // Southeast - if (grid[x + 1] && grid[x + 1][y - 1]) { - ret.push(grid[x + 1][y - 1]); - } - - // Northwest - if (grid[x - 1] && grid[x - 1][y + 1]) { - ret.push(grid[x - 1][y + 1]); - } - - // Northeast - if (grid[x + 1] && grid[x + 1][y + 1]) { - ret.push(grid[x + 1][y + 1]); - } - } - - return ret; -}; - -Graph.prototype.toString = function() { - const graphString = []; - const nodes = this.grid; - for (let x = 0; x < nodes.length; x++) { - const rowDebug = []; - const row = nodes[x]; - for (let y = 0; y < row.length; y++) { - rowDebug.push(row[y].weight); - } - graphString.push(rowDebug.join(' ')); - } - return graphString.join('\n'); -}; - -GridNode.prototype.toString = function() { - return `[${this.x} ${this.y}]`; -}; - -GridNode.prototype.getCost = function(fromNeighbor) { - // Take diagonal weight into consideration. - if (fromNeighbor && fromNeighbor.x !== this.x && fromNeighbor.y !== this.y) { - return this.weight * 1.41421; - } - return this.weight; -}; - -GridNode.prototype.isWall = function() { - return this.weight === 0; }; From a94fdae47f663bb946c64017dd5df251fdde829e Mon Sep 17 00:00:00 2001 From: takenaoki Date: Wed, 21 Jun 2017 17:12:14 +0900 Subject: [PATCH 3/5] fix weight calc --- astar.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/astar.js b/astar.js index d797ff0..5399e7b 100644 --- a/astar.js +++ b/astar.js @@ -18,9 +18,9 @@ GridNode.prototype.toString = function() { GridNode.prototype.getCost = function(fromNeighbor) { // Take diagonal weight into consideration. - if (fromNeighbor && fromNeighbor.x !== this.x && fromNeighbor.y !== this.y) { - return this.weight * 1.41421; - } + // if (fromNeighbor && fromNeighbor.x !== this.x && fromNeighbor.y !== this.y) { + // return this.weight * 1.41421; + // } return this.weight; }; From de23fb71057de704599cbaf8706296aa717bfcfb Mon Sep 17 00:00:00 2001 From: takenaoki Date: Wed, 21 Jun 2017 17:12:14 +0900 Subject: [PATCH 4/5] fix weight calc[ci skip] --- astar.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/astar.js b/astar.js index d797ff0..5399e7b 100644 --- a/astar.js +++ b/astar.js @@ -18,9 +18,9 @@ GridNode.prototype.toString = function() { GridNode.prototype.getCost = function(fromNeighbor) { // Take diagonal weight into consideration. - if (fromNeighbor && fromNeighbor.x !== this.x && fromNeighbor.y !== this.y) { - return this.weight * 1.41421; - } + // if (fromNeighbor && fromNeighbor.x !== this.x && fromNeighbor.y !== this.y) { + // return this.weight * 1.41421; + // } return this.weight; }; From 9c268fbc3d9ddb6b717224806bd5aebf7fcc2f1a Mon Sep 17 00:00:00 2001 From: takenaoki Date: Wed, 21 Jun 2017 19:08:07 +0900 Subject: [PATCH 5/5] fix weight calc[ci skip] --- astar.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/astar.js b/astar.js index 5399e7b..8820620 100644 --- a/astar.js +++ b/astar.js @@ -18,9 +18,9 @@ GridNode.prototype.toString = function() { GridNode.prototype.getCost = function(fromNeighbor) { // Take diagonal weight into consideration. - // if (fromNeighbor && fromNeighbor.x !== this.x && fromNeighbor.y !== this.y) { - // return this.weight * 1.41421; - // } + if (fromNeighbor && fromNeighbor.x !== this.x && fromNeighbor.y !== this.y) { + return this.weight + 0.5; + } return this.weight; };