diff --git a/lib/pathfinding-browser.js b/lib/pathfinding-browser.js index de1a371b..9170fa66 100644 --- a/lib/pathfinding-browser.js +++ b/lib/pathfinding-browser.js @@ -1208,6 +1208,7 @@ function AStarFinder(opt) { this.dontCrossCorners = opt.dontCrossCorners; this.heuristic = opt.heuristic || Heuristic.manhattan; this.weight = opt.weight || 1; + this.avoidStaircase = opt.avoidStaircase; } /** @@ -1224,8 +1225,10 @@ AStarFinder.prototype.findPath = function(startX, startY, endX, endY, grid) { heuristic = this.heuristic, allowDiagonal = this.allowDiagonal, dontCrossCorners = this.dontCrossCorners, + avoidStaircase = this.avoidStaircase, weight = this.weight, abs = Math.abs, SQRT2 = Math.SQRT2, + turnPenalty = 1, lastDirection = undefined, node, neighbors, neighbor, i, l, x, y, ng; // set the `g` and `f` value of the start node to be 0 @@ -1263,6 +1266,14 @@ AStarFinder.prototype.findPath = function(startX, startY, endX, endY, grid) { // and calculate the next g score ng = node.g + ((x - node.x === 0 || y - node.y === 0) ? 1 : SQRT2); + + if (avoidStaircase) { + // add additional cost if neighbor creates a turn + lastDirection = node.parent == undefined? undefined : { x : node.x - node.parent.x, y : node.y - node.parent.y }; + var turned = lastDirection == undefined? 0 : lastDirection.x != x - node.x || lastDirection.y != y - node.y; + ng += turnPenalty * turned; + } + // check if the neighbor has not been inspected yet, or // can be reached with smaller cost from the current node if (!neighbor.opened || ng < neighbor.g) { @@ -2006,4 +2017,4 @@ require.define("/PathFinding.js", function (require, module, exports, __dirname, }); require("/PathFinding.js"); -return require("/PathFinding");})(); \ No newline at end of file +return require("/PathFinding");})(); diff --git a/visual/index.html b/visual/index.html index b5c36615..e7a408c8 100644 --- a/visual/index.html +++ b/visual/index.html @@ -70,6 +70,8 @@