From 3e821c013ddf0431697f6b793ba0f244e5e35983 Mon Sep 17 00:00:00 2001 From: Mike Smart Date: Wed, 11 Apr 2018 10:28:04 +0100 Subject: [PATCH 1/6] some semicolon housekeeping and tests for enableSync mode --- src/easystar.js | 73 ++--- test/easystartest.js | 703 ++++++++++++++++++++++++------------------- 2 files changed, 416 insertions(+), 360 deletions(-) diff --git a/src/easystar.js b/src/easystar.js index 8323066..1e2e462 100755 --- a/src/easystar.js +++ b/src/easystar.js @@ -6,7 +6,7 @@ * Implementation By Bryce Neal (@prettymuchbryce) **/ -var EasyStar = {} +var EasyStar = {}; var Instance = require('./instance'); var Node = require('./node'); var Heap = require('heap'); @@ -72,14 +72,14 @@ EasyStar.js = function() { */ this.enableDiagonals = function() { diagonalsEnabled = true; - } + }; /** * Disable diagonal pathfinding. */ this.disableDiagonals = function() { diagonalsEnabled = false; - } + }; /** * Sets the collision grid that EasyStar uses. @@ -103,8 +103,8 @@ EasyStar.js = function() { /** * Sets the tile cost for a particular tile type. * - * @param {Number} The tile type to set the cost for. - * @param {Number} The multiplicative cost associated with the given tile. + * @param {Number} tileType The tile type to set the cost for. + * @param {Number} cost The multiplicative cost associated with the given tile. **/ this.setTileCost = function(tileType, cost) { costMap[tileType] = cost; @@ -116,7 +116,7 @@ EasyStar.js = function() { * * @param {Number} x The x value of the point to cost. * @param {Number} y The y value of the point to cost. - * @param {Number} The multiplicative cost associated with the given point. + * @param {Number} cost The multiplicative cost associated with the given point. **/ this.setAdditionalPointCost = function(x, y, cost) { if (pointsToCost[y] === undefined) { @@ -135,14 +135,14 @@ EasyStar.js = function() { if (pointsToCost[y] !== undefined) { delete pointsToCost[y][x]; } - } + }; /** * Remove all additional point costs. **/ this.removeAllAdditionalPointCosts = function() { pointsToCost = {}; - } + }; /** * Sets a directional condition on a tile @@ -238,17 +238,6 @@ EasyStar.js = function() { * **/ this.findPath = function(startX, startY, endX, endY, callback) { - // Wraps the callback for sync vs async logic - var callbackWrapper = function(result) { - if (syncEnabled) { - callback(result); - } else { - setTimeout(function() { - callback(result); - }); - } - } - // No acceptable tiles were set if (acceptableTiles === undefined) { throw new Error("You can't set a path without first calling setAcceptableTiles() on EasyStar."); @@ -267,7 +256,7 @@ EasyStar.js = function() { // Start and end are the same tile. if (startX===endX && startY===endY) { - callbackWrapper([]); + callback([]); return; } @@ -282,7 +271,7 @@ EasyStar.js = function() { } if (isAcceptable === false) { - callbackWrapper(null); + callback(null); return; } @@ -297,7 +286,7 @@ EasyStar.js = function() { instance.startY = startY; instance.endX = endX; instance.endY = endY; - instance.callback = callbackWrapper; + instance.callback = callback; instance.openList.push(coordinateToNode(instance, instance.startX, instance.startY, null, STRAIGHT_COST)); @@ -469,13 +458,13 @@ EasyStar.js = function() { var isTileWalkable = function(collisionGrid, acceptableTiles, x, y, sourceNode) { var directionalCondition = directionalConditions[y] && directionalConditions[y][x]; if (directionalCondition) { - var direction = calculateDirection(sourceNode.x - x, sourceNode.y - y) + var direction = calculateDirection(sourceNode.x - x, sourceNode.y - y); var directionIncluded = function () { for (var i = 0; i < directionalCondition.length; i++) { if (directionalCondition[i] === direction) return true } return false - } + }; if (!directionIncluded()) return false } for (var i = 0; i < acceptableTiles.length; i++) { @@ -493,14 +482,14 @@ EasyStar.js = function() { * -1, 1 | 0, 1 | 1, 1 */ var calculateDirection = function (diffX, diffY) { - if (diffX === 0 && diffY === -1) return EasyStar.TOP - else if (diffX === 1 && diffY === -1) return EasyStar.TOP_RIGHT - else if (diffX === 1 && diffY === 0) return EasyStar.RIGHT - else if (diffX === 1 && diffY === 1) return EasyStar.BOTTOM_RIGHT - else if (diffX === 0 && diffY === 1) return EasyStar.BOTTOM - else if (diffX === -1 && diffY === 1) return EasyStar.BOTTOM_LEFT - else if (diffX === -1 && diffY === 0) return EasyStar.LEFT - else if (diffX === -1 && diffY === -1) return EasyStar.TOP_LEFT + if (diffX === 0 && diffY === -1) return EasyStar.TOP; + else if (diffX === 1 && diffY === -1) return EasyStar.TOP_RIGHT; + else if (diffX === 1 && diffY === 0) return EasyStar.RIGHT; + else if (diffX === 1 && diffY === 1) return EasyStar.BOTTOM_RIGHT; + else if (diffX === 0 && diffY === 1) return EasyStar.BOTTOM; + else if (diffX === -1 && diffY === 1) return EasyStar.BOTTOM_LEFT; + else if (diffX === -1 && diffY === 0) return EasyStar.LEFT; + else if (diffX === -1 && diffY === -1) return EasyStar.TOP_LEFT; throw new Error('These differences are not valid: ' + diffX + ', ' + diffY) }; @@ -544,13 +533,13 @@ EasyStar.js = function() { return (dx + dy); } }; -} - -EasyStar.TOP = 'TOP' -EasyStar.TOP_RIGHT = 'TOP_RIGHT' -EasyStar.RIGHT = 'RIGHT' -EasyStar.BOTTOM_RIGHT = 'BOTTOM_RIGHT' -EasyStar.BOTTOM = 'BOTTOM' -EasyStar.BOTTOM_LEFT = 'BOTTOM_LEFT' -EasyStar.LEFT = 'LEFT' -EasyStar.TOP_LEFT = 'TOP_LEFT' +}; + +EasyStar.TOP = 'TOP'; +EasyStar.TOP_RIGHT = 'TOP_RIGHT'; +EasyStar.RIGHT = 'RIGHT'; +EasyStar.BOTTOM_RIGHT = 'BOTTOM_RIGHT'; +EasyStar.BOTTOM = 'BOTTOM'; +EasyStar.BOTTOM_LEFT = 'BOTTOM_LEFT'; +EasyStar.LEFT = 'LEFT'; +EasyStar.TOP_LEFT = 'TOP_LEFT'; diff --git a/test/easystartest.js b/test/easystartest.js index f932812..7936b96 100644 --- a/test/easystartest.js +++ b/test/easystartest.js @@ -1,349 +1,416 @@ -describe("EasyStar.js", function() { +describe('EasyStar.js', function () { - beforeEach(function() { }); + beforeEach(function () { }); - it("It should find a path successfully with corner cutting enabled.", function(done) { - var easyStar = new EasyStar.js(); - easyStar.enableDiagonals(); - var map = [[1,0,0,0,0], - [0,1,0,0,0], - [0,0,1,0,0], - [0,0,0,1,0], - [0,0,0,0,1]]; + it('It should find a path successfully with corner cutting enabled.', function (done) { + var easyStar = new EasyStar.js(); + easyStar.enableDiagonals(); + var map = [[1, 0, 0, 0, 0], + [0, 1, 0, 0, 0], + [0, 0, 1, 0, 0], + [0, 0, 0, 1, 0], + [0, 0, 0, 0, 1]]; - easyStar.setGrid(map); + easyStar.setGrid(map); - easyStar.enableCornerCutting(); + easyStar.enableCornerCutting(); - easyStar.setAcceptableTiles([1]); + easyStar.setAcceptableTiles([1]); - easyStar.findPath(0,0,4,4,onPathFound); + easyStar.findPath(0, 0, 4, 4, onPathFound); - easyStar.calculate(); + easyStar.calculate(); - function onPathFound(path) { - expect(path).not.toBeNull(); - expect(path.length).toEqual(5); - expect(path[0].x).toEqual(0); - expect(path[0].y).toEqual(0); - expect(path[3].x).toEqual(3); - expect(path[3].y).toEqual(3); - done() - } - }); + function onPathFound (path) { + expect(path).not.toBeNull(); + expect(path.length).toEqual(5); + expect(path[0].x).toEqual(0); + expect(path[0].y).toEqual(0); + expect(path[3].x).toEqual(3); + expect(path[3].y).toEqual(3); + done(); + } + }); + + it('It should fail to find a path successfully with corner cutting disabled.', function (done) { + var easyStar = new EasyStar.js(); + easyStar.enableDiagonals(); + var map = [[1, 0, 0, 0, 0], + [0, 1, 0, 0, 0], + [0, 0, 1, 0, 0], + [0, 0, 0, 1, 0], + [0, 0, 0, 0, 1]]; + + easyStar.setGrid(map); + + easyStar.disableCornerCutting(); + + easyStar.setAcceptableTiles([1]); + + easyStar.findPath(0, 0, 4, 4, onPathFound); + + easyStar.calculate(); + + function onPathFound (path) { + expect(path).toBeNull(); + done(); + } + }); + + it('It should find a path successfully.', function (done) { + var easyStar = new EasyStar.js(); + var map = [[1, 1, 0, 1, 1], + [1, 1, 0, 1, 1], + [1, 1, 0, 1, 1], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1]]; + + easyStar.setGrid(map); + + easyStar.setAcceptableTiles([1]); + + easyStar.findPath(1, 2, 3, 2, onPathFound); + + easyStar.calculate(); + + function onPathFound (path) { + expect(path).not.toBeNull(); + expect(path.length).toEqual(5); + expect(path[0].x).toEqual(1); + expect(path[0].y).toEqual(2); + expect(path[2].x).toEqual(2); + expect(path[2].y).toEqual(3); + done(); + } + }); + + it('It should be able to cancel a path.', function (done) { + var easyStar = new EasyStar.js(); + var map = [[1, 1, 0, 1, 1], + [1, 1, 0, 1, 1], + [1, 1, 0, 1, 1], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1]]; + + easyStar.setGrid(map); + + easyStar.setAcceptableTiles([1]); + + var id = easyStar.findPath(1, 2, 3, 2, onPathFound); + + easyStar.cancelPath(id); + + easyStar.calculate(); + + function onPathFound (path) { + fail('path wasn\'t cancelled'); + } + + setTimeout(done, 0); + }); + + it('Paths should have different IDs.', function () { + var easyStar = new EasyStar.js(); + var map = [[1, 1, 0, 1, 1], + [1, 1, 0, 1, 1], + [1, 1, 0, 1, 1], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1]]; + + easyStar.setGrid(map); + + easyStar.setAcceptableTiles([1]); + + var id1 = easyStar.findPath(1, 2, 3, 2, onPathFound); + var id2 = easyStar.findPath(3, 2, 1, 2, onPathFound); + expect(id1).toBeGreaterThan(0); + expect(id2).toBeGreaterThan(0); + expect(id1).not.toEqual(id2); + + function onPathFound (path) { + } + }); + + it('It should be able to avoid a separate point successfully.', function (done) { + var easyStar = new EasyStar.js(); + var map = [[1, 1, 0, 1, 1], + [1, 1, 0, 1, 1], + [1, 1, 0, 1, 1], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1]]; + + easyStar.setGrid(map); + + easyStar.avoidAdditionalPoint(2, 3); + + easyStar.setAcceptableTiles([1]); + + easyStar.findPath(1, 2, 3, 2, onPathFound); + + easyStar.calculate(); - it("It should fail to find a path successfully with corner cutting disabled.", function(done) { - var easyStar = new EasyStar.js(); - easyStar.enableDiagonals(); - var map = [[1,0,0,0,0], - [0,1,0,0,0], - [0,0,1,0,0], - [0,0,0,1,0], - [0,0,0,0,1]]; + function onPathFound (path) { + expect(path).not.toBeNull(); + expect(path.length).toEqual(7); + expect(path[0].x).toEqual(1); + expect(path[0].y).toEqual(2); + expect(path[2].x).toEqual(1); + expect(path[2].y).toEqual(4); + done(); + } + }); - easyStar.setGrid(map); + it('It should work with diagonals', function (done) { + var easyStar = new EasyStar.js(); + easyStar.enableDiagonals(); + var map = [[1, 1, 1, 1, 1], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1]]; + + easyStar.setGrid(map); + + easyStar.setAcceptableTiles([1]); + + easyStar.findPath(0, 0, 4, 4, onPathFound); + + easyStar.calculate(); + + function onPathFound (path) { + expect(path).not.toBeNull(); + expect(path.length).toEqual(5); + expect(path[0].x).toEqual(0); + expect(path[0].y).toEqual(0); + expect(path[1].x).toEqual(1); + expect(path[1].y).toEqual(1); + expect(path[2].x).toEqual(2); + expect(path[2].y).toEqual(2); + expect(path[3].x).toEqual(3); + expect(path[3].y).toEqual(3); + expect(path[4].x).toEqual(4); + expect(path[4].y).toEqual(4); + done(); + } + }); - easyStar.disableCornerCutting(); + it('It should move in a straight line with diagonals', function (done) { + var easyStar = new EasyStar.js(); + easyStar.enableDiagonals(); + var map = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 0, 1, 1, 1, 1, 0, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]; - easyStar.setAcceptableTiles([1]); + easyStar.setGrid(map); - easyStar.findPath(0,0,4,4,onPathFound); + easyStar.enableDiagonals(); - easyStar.calculate(); + easyStar.setAcceptableTiles([1]); - function onPathFound(path) { - expect(path).toBeNull(); - done(); - } - }); + easyStar.findPath(0, 0, 9, 0, onPathFound); - it("It should find a path successfully.", function(done) { - var easyStar = new EasyStar.js(); - var map = [[1,1,0,1,1], - [1,1,0,1,1], - [1,1,0,1,1], - [1,1,1,1,1], - [1,1,1,1,1]]; + easyStar.calculate(); - easyStar.setGrid(map); + function onPathFound (path) { + expect(path).not.toBeNull(); + for (var i = 0; i < path.length; i++) { + expect(path[i].y).toEqual(0); + } + done(); + } + }); - easyStar.setAcceptableTiles([1]); + it('It should return empty path when start and end are the same tile.', function (done) { + var easyStar = new EasyStar.js(); + var map = [[1, 1, 0, 1, 1], + [1, 1, 0, 1, 1], + [1, 1, 0, 1, 1], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1]]; - easyStar.findPath(1,2,3,2,onPathFound); + easyStar.setGrid(map); - easyStar.calculate(); + easyStar.setAcceptableTiles([1]); - function onPathFound(path) { - expect(path).not.toBeNull(); - expect(path.length).toEqual(5); - expect(path[0].x).toEqual(1); - expect(path[0].y).toEqual(2); - expect(path[2].x).toEqual(2); - expect(path[2].y).toEqual(3); - done(); - } - }); + easyStar.findPath(1, 2, 1, 2, onPathFound); - it("It should be able to cancel a path.", function(done) { - var easyStar = new EasyStar.js(); - var map = [[1,1,0,1,1], - [1,1,0,1,1], - [1,1,0,1,1], - [1,1,1,1,1], - [1,1,1,1,1]]; - - easyStar.setGrid(map); - - easyStar.setAcceptableTiles([1]); - - var id = easyStar.findPath(1,2,3,2,onPathFound); - - easyStar.cancelPath(id); - - easyStar.calculate(); - - function onPathFound(path) { - fail("path wasn't cancelled"); - } - - setTimeout(done, 0); - }); - - it("Paths should have different IDs.", function() { - var easyStar = new EasyStar.js(); - var map = [[1,1,0,1,1], - [1,1,0,1,1], - [1,1,0,1,1], - [1,1,1,1,1], - [1,1,1,1,1]]; - - easyStar.setGrid(map); - - easyStar.setAcceptableTiles([1]); - - var id1 = easyStar.findPath(1,2,3,2,onPathFound); - var id2 = easyStar.findPath(3,2,1,2,onPathFound); - expect(id1).toBeGreaterThan(0); - expect(id2).toBeGreaterThan(0); - expect(id1).not.toEqual(id2); - - function onPathFound(path) { - } - }); - - it("It should be able to avoid a separate point successfully.", function(done) { - var easyStar = new EasyStar.js(); - var map = [[1,1,0,1,1], - [1,1,0,1,1], - [1,1,0,1,1], - [1,1,1,1,1], - [1,1,1,1,1]]; - - easyStar.setGrid(map); + easyStar.calculate(); - easyStar.avoidAdditionalPoint(2,3); - - easyStar.setAcceptableTiles([1]); - - easyStar.findPath(1,2,3,2,onPathFound); - - easyStar.calculate(); - - function onPathFound(path) { - expect(path).not.toBeNull(); - expect(path.length).toEqual(7); - expect(path[0].x).toEqual(1); - expect(path[0].y).toEqual(2); - expect(path[2].x).toEqual(1); - expect(path[2].y).toEqual(4); - done(); - } - }); - - it("It should work with diagonals", function(done) { - var easyStar = new EasyStar.js(); - easyStar.enableDiagonals(); - var map = [[1,1,1,1,1], - [1,1,1,1,1], - [1,1,1,1,1], - [1,1,1,1,1], - [1,1,1,1,1]]; - - easyStar.setGrid(map); - - easyStar.setAcceptableTiles([1]); - - easyStar.findPath(0,0,4,4,onPathFound); - - easyStar.calculate(); - - function onPathFound(path) { - expect(path).not.toBeNull(); - expect(path.length).toEqual(5); - expect(path[0].x).toEqual(0); - expect(path[0].y).toEqual(0); - expect(path[1].x).toEqual(1); - expect(path[1].y).toEqual(1); - expect(path[2].x).toEqual(2); - expect(path[2].y).toEqual(2); - expect(path[3].x).toEqual(3); - expect(path[3].y).toEqual(3); - expect(path[4].x).toEqual(4); - expect(path[4].y).toEqual(4); - done(); - } - }); - - it("It should move in a straight line with diagonals", function(done) { - var easyStar = new EasyStar.js(); - easyStar.enableDiagonals(); - var map = [[1,1,1,1,1,1,1,1,1,1], - [1,1,0,1,1,1,1,0,1,1], - [1,1,1,1,1,1,1,1,1,1], - [1,1,1,1,1,1,1,1,1,1], - [1,1,1,1,1,1,1,1,1,1], - [1,1,1,1,1,1,1,1,1,1], - [1,1,1,1,1,1,1,1,1,1], - [1,1,1,1,1,1,1,1,1,1], - [1,1,1,1,1,1,1,1,1,1], - [1,1,1,1,1,1,1,1,1,1]]; - - easyStar.setGrid(map); - - easyStar.enableDiagonals(); - - easyStar.setAcceptableTiles([1]); - - easyStar.findPath(0,0,9,0,onPathFound); - - easyStar.calculate(); - - function onPathFound(path) { - expect(path).not.toBeNull(); - for (var i = 0; i < path.length; i++) { - expect(path[i].y).toEqual(0); + function onPathFound (path) { + expect(path).not.toBeNull(); + expect(path.length).toEqual(0); + done(); } - done(); - } - }); - - it("It should return empty path when start and end are the same tile.", function(done) { - var easyStar = new EasyStar.js(); - var map = [[1,1,0,1,1], - [1,1,0,1,1], - [1,1,0,1,1], - [1,1,1,1,1], - [1,1,1,1,1]]; - - easyStar.setGrid(map); - - easyStar.setAcceptableTiles([1]); - - easyStar.findPath(1,2,1,2,onPathFound); - - easyStar.calculate(); - - function onPathFound(path) { - expect(path).not.toBeNull(); - expect(path.length).toEqual(0); - done(); - } - }); - - it("It should prefer straight paths when possible", function(done) { - var easyStar = new EasyStar.js(); - easyStar.setAcceptableTiles([0]); - easyStar.enableDiagonals(); - easyStar.setGrid([ - [0, 0, 0], - [0, 0, 0], - [0, 0, 0] - ]); - - easyStar.findPath(0, 1, 2, 1, function(path){ - expect(path).not.toBeNull(); - expect(path[1].x).toEqual(1); - expect(path[1].y).toEqual(1); - done(); }); - easyStar.calculate(); - }); + it('It should prefer straight paths when possible', function (done) { + var easyStar = new EasyStar.js(); + easyStar.setAcceptableTiles([0]); + easyStar.enableDiagonals(); + easyStar.setGrid([ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0] + ]); + + easyStar.findPath(0, 1, 2, 1, function (path) { + expect(path).not.toBeNull(); + expect(path[1].x).toEqual(1); + expect(path[1].y).toEqual(1); + done(); + }); + + easyStar.calculate(); + }); - it("It should prefer diagonal paths when they are faster", function(done) { - var easyStar = new EasyStar.js(); - var grid = []; - for (var i = 0; i < 20; i++) { - grid[i] = []; - for (var j = 0; j < 20; j++) { - grid[i][j] = 0; + it('It should prefer diagonal paths when they are faster', function (done) { + var easyStar = new EasyStar.js(); + var grid = []; + for (var i = 0; i < 20; i++) { + grid[i] = []; + for (var j = 0; j < 20; j++) { + grid[i][j] = 0; + } } - } - easyStar.setGrid(grid); - easyStar.setAcceptableTiles([0]); - easyStar.enableDiagonals(); - - easyStar.findPath(4, 4, 2, 2, function(path){ - expect(path).not.toBeNull(); - expect(path.length).toEqual(3); - expect(path[1].x).toEqual(3); - expect(path[1].y).toEqual(3); - done(); + easyStar.setGrid(grid); + easyStar.setAcceptableTiles([0]); + easyStar.enableDiagonals(); + + easyStar.findPath(4, 4, 2, 2, function (path) { + expect(path).not.toBeNull(); + expect(path.length).toEqual(3); + expect(path[1].x).toEqual(3); + expect(path[1].y).toEqual(3); + done(); + }); + + easyStar.calculate(); }); - easyStar.calculate(); - }) - - it("It should handle tiles with a directional condition", function (done) { - var easyStar = new EasyStar.js(); - var grid = [ - [0, 1, 0], - [0, 0, 0], - [0, 0, 0], - ]; - easyStar.setGrid(grid); - easyStar.enableDiagonals(); - easyStar.setAcceptableTiles([0]); - easyStar.setDirectionalCondition(2, 1, [EasyStar.TOP]); - easyStar.setDirectionalCondition(1, 2, [EasyStar.TOP_RIGHT]); - easyStar.setDirectionalCondition(2, 2, [EasyStar.LEFT]); - easyStar.setDirectionalCondition(1, 1, [EasyStar.BOTTOM_RIGHT]); - easyStar.setDirectionalCondition(0, 1, [EasyStar.RIGHT]); - easyStar.setDirectionalCondition(0, 0, [EasyStar.BOTTOM]); - - easyStar.findPath(2, 0, 0, 0, function (path) { - expect(path).not.toBeNull(); - expect(path.length).toEqual(7); - expect(path[3]).toEqual({ x: 2, y: 2}) - done(); - }); - - easyStar.calculate(); - }) - - it("It should handle tiles with a directional condition and no corner cutting", function (done) { - var easyStar = new EasyStar.js(); - easyStar.disableCornerCutting(); - var grid = [ - [0, 1, 0], - [0, 0, 0], - [0, 0, 0], - ]; - easyStar.setGrid(grid); - easyStar.enableDiagonals(); - easyStar.setAcceptableTiles([0]); - easyStar.setDirectionalCondition(2, 1, [EasyStar.TOP]); - easyStar.setDirectionalCondition(1, 1, [EasyStar.RIGHT]); - easyStar.setDirectionalCondition(0, 1, [EasyStar.RIGHT]); - easyStar.setDirectionalCondition(0, 0, [EasyStar.BOTTOM]); - - easyStar.findPath(2, 0, 0, 0, function (path) { - expect(path).not.toBeNull(); - expect(path.length).toEqual(5); - expect(path[2]).toEqual({ x: 1, y: 1}) - done(); - }); - - easyStar.calculate(); - }) + it('It should handle tiles with a directional condition', function (done) { + var easyStar = new EasyStar.js(); + var grid = [ + [0, 1, 0], + [0, 0, 0], + [0, 0, 0], + ]; + easyStar.setGrid(grid); + easyStar.enableDiagonals(); + easyStar.setAcceptableTiles([0]); + easyStar.setDirectionalCondition(2, 1, [EasyStar.TOP]); + easyStar.setDirectionalCondition(1, 2, [EasyStar.TOP_RIGHT]); + easyStar.setDirectionalCondition(2, 2, [EasyStar.LEFT]); + easyStar.setDirectionalCondition(1, 1, [EasyStar.BOTTOM_RIGHT]); + easyStar.setDirectionalCondition(0, 1, [EasyStar.RIGHT]); + easyStar.setDirectionalCondition(0, 0, [EasyStar.BOTTOM]); + + easyStar.findPath(2, 0, 0, 0, function (path) { + expect(path).not.toBeNull(); + expect(path.length).toEqual(7); + expect(path[3]).toEqual({x: 2, y: 2}); + done(); + }); + + easyStar.calculate(); + }); + + it('It should handle tiles with a directional condition and no corner cutting', function (done) { + var easyStar = new EasyStar.js(); + easyStar.disableCornerCutting(); + var grid = [ + [0, 1, 0], + [0, 0, 0], + [0, 0, 0], + ]; + easyStar.setGrid(grid); + easyStar.enableDiagonals(); + easyStar.setAcceptableTiles([0]); + easyStar.setDirectionalCondition(2, 1, [EasyStar.TOP]); + easyStar.setDirectionalCondition(1, 1, [EasyStar.RIGHT]); + easyStar.setDirectionalCondition(0, 1, [EasyStar.RIGHT]); + easyStar.setDirectionalCondition(0, 0, [EasyStar.BOTTOM]); + + easyStar.findPath(2, 0, 0, 0, function (path) { + expect(path).not.toBeNull(); + expect(path.length).toEqual(5); + expect(path[2]).toEqual({x: 1, y: 1}); + done(); + }); + + easyStar.calculate(); + }); + + describe('Synchronous', function () { + it('It should invoke the findPath callback immediately when sync mode is enabled', function () { + var easyStar = new EasyStar.js(); + var result = []; + var grid = [ + [0, 1, 0], + [0, 0, 0], + [0, 0, 0], + ]; + + easyStar.enableSync(); + easyStar.setGrid(grid); + easyStar.setAcceptableTiles([0]); + + easyStar.findPath(0, 0, 1, 1, function (path) { + result.push.apply(result, path); + }); + + easyStar.calculate(); + + // Expect our result to be updated immediately + // after calculate is invoked + expect(result.length).toEqual(3); + expect(result[0]).toEqual({x: 0, y: 0}); + expect(result[1]).toEqual({x: 0, y: 1}); + expect(result[2]).toEqual({x: 1, y: 1}); + }); + }); + + describe('Asynchrounous', function () { + beforeEach(function () { + jasmine.clock().install(); + }); + + afterEach(function () { + jasmine.clock().uninstall(); + }); + + it('It should defer the findPath callback to the next stack when sync mode is not enabled', function () { + var easyStar = new EasyStar.js(); + var result = []; + var grid = [ + [0, 1, 0], + [0, 0, 0], + [0, 0, 0], + ]; + + easyStar.setGrid(grid); + easyStar.setAcceptableTiles([0]); + + easyStar.findPath(0, 0, 1, 1, function (path) { + result.push.apply(result, path); + + expect(path.length).toEqual(3); + expect(path[0]).toEqual({x: 0, y: 0}); + expect(path[1]).toEqual({x: 0, y: 1}); + expect(path[2]).toEqual({x: 1, y: 1}); + }); + + easyStar.calculate(); + + // Expect our result to be deferred until + // it is ready + expect(result.length).toEqual(0); + }); + }); }); From ad5259a851bd2687b2a77d7b5e39fb626330f777 Mon Sep 17 00:00:00 2001 From: Mike Smart Date: Wed, 11 Apr 2018 10:47:29 +0100 Subject: [PATCH 2/6] add findPathSync method with tests and ts definitions --- bin/easystar-0.4.3.js | 46 ++++++++++++++++++++++++++---------------- index.d.ts | 13 ++++++++++++ src/easystar.js | 23 +++++++++++++++++++++ test/easystartest.js | 47 +++++++++++++++++++++---------------------- 4 files changed, 88 insertions(+), 41 deletions(-) diff --git a/bin/easystar-0.4.3.js b/bin/easystar-0.4.3.js index 5ccabb4..7878952 100644 --- a/bin/easystar-0.4.3.js +++ b/bin/easystar-0.4.3.js @@ -150,8 +150,8 @@ var EasyStar = /** * Sets the tile cost for a particular tile type. * - * @param {Number} The tile type to set the cost for. - * @param {Number} The multiplicative cost associated with the given tile. + * @param {Number} tileType The tile type to set the cost for. + * @param {Number} cost The multiplicative cost associated with the given tile. **/ this.setTileCost = function (tileType, cost) { costMap[tileType] = cost; @@ -163,7 +163,7 @@ var EasyStar = * * @param {Number} x The x value of the point to cost. * @param {Number} y The y value of the point to cost. - * @param {Number} The multiplicative cost associated with the given point. + * @param {Number} cost The multiplicative cost associated with the given point. **/ this.setAdditionalPointCost = function (x, y, cost) { if (pointsToCost[y] === undefined) { @@ -272,6 +272,29 @@ var EasyStar = pointsToAvoid = {}; }; + /** + * Find a path and calculate synchronously + * + * @param {Number} startX + * @param {Number} startY + * @param {Number} endX + * @param {Number} endY + * @returns {Array<{ x: Number, y: Number}|null>} + */ + this.findPathSync = function (startX, startY, endX, endY) { + var result = null; + + syncEnabled = true; + + this.findPath(startX, startY, endX, endY, function (path) { + result = path; + }); + + this.calculate(); + + return result; + }; + /** * Find a path. * @@ -285,17 +308,6 @@ var EasyStar = * **/ this.findPath = function (startX, startY, endX, endY, callback) { - // Wraps the callback for sync vs async logic - var callbackWrapper = function (result) { - if (syncEnabled) { - callback(result); - } else { - setTimeout(function () { - callback(result); - }); - } - }; - // No acceptable tiles were set if (acceptableTiles === undefined) { throw new Error("You can't set a path without first calling setAcceptableTiles() on EasyStar."); @@ -312,7 +324,7 @@ var EasyStar = // Start and end are the same tile. if (startX === endX && startY === endY) { - callbackWrapper([]); + callback([]); return; } @@ -327,7 +339,7 @@ var EasyStar = } if (isAcceptable === false) { - callbackWrapper(null); + callback(null); return; } @@ -342,7 +354,7 @@ var EasyStar = instance.startY = startY; instance.endX = endX; instance.endY = endY; - instance.callback = callbackWrapper; + instance.callback = callback; instance.openList.push(coordinateToNode(instance, instance.startX, instance.startY, null, STRAIGHT_COST)); diff --git a/index.d.ts b/index.d.ts index a31b48e..4ea12c3 100644 --- a/index.d.ts +++ b/index.d.ts @@ -122,6 +122,19 @@ export class js { */ stopAvoidingAllAdditionalPoints(): void + /** + * Find a path synchronously. + * + * @param {Number} startX The X position of the starting point. + * @param {Number} startY The Y position of the starting point. + * @param {Number} endX The X position of the ending point. + * @param {Number} endY The Y position of the ending point. + * is found, or no path is found. + * @return {Array<{ x: Number, y: Number }>|null} The result of easystar.calculate(), a path array or null + * + */ + findPathSync(startX: number, startY: number, endX: number, endY: number): Array<{ x: number, y: number }>|null + /** * Find a path. * diff --git a/src/easystar.js b/src/easystar.js index 1e2e462..72a1c21 100755 --- a/src/easystar.js +++ b/src/easystar.js @@ -225,6 +225,29 @@ EasyStar.js = function() { pointsToAvoid = {}; }; + /** + * Find a path and calculate synchronously + * + * @param {Number} startX + * @param {Number} startY + * @param {Number} endX + * @param {Number} endY + * @returns {Array<{ x: Number, y: Number}|null>} + */ + this.findPathSync = function(startX, startY, endX, endY) { + var result = null; + + syncEnabled = true; + + this.findPath(startX, startY, endX, endY, function (path) { + result = path; + }); + + this.calculate(); + + return result; + }; + /** * Find a path. * diff --git a/test/easystartest.js b/test/easystartest.js index 7936b96..6de4f77 100644 --- a/test/easystartest.js +++ b/test/easystartest.js @@ -374,43 +374,42 @@ describe('EasyStar.js', function () { expect(result[1]).toEqual({x: 0, y: 1}); expect(result[2]).toEqual({x: 1, y: 1}); }); - }); - - describe('Asynchrounous', function () { - beforeEach(function () { - jasmine.clock().install(); - }); - afterEach(function () { - jasmine.clock().uninstall(); - }); - - it('It should defer the findPath callback to the next stack when sync mode is not enabled', function () { + it('It should return the path directly from the findPathSync method', function () { var easyStar = new EasyStar.js(); - var result = []; + var result; var grid = [ [0, 1, 0], [0, 0, 0], [0, 0, 0], ]; - easyStar.setGrid(grid); easyStar.setAcceptableTiles([0]); - easyStar.findPath(0, 0, 1, 1, function (path) { - result.push.apply(result, path); + result = easyStar.findPathSync(0, 0, 1, 1); - expect(path.length).toEqual(3); - expect(path[0]).toEqual({x: 0, y: 0}); - expect(path[1]).toEqual({x: 0, y: 1}); - expect(path[2]).toEqual({x: 1, y: 1}); - }); + // Expect our result to be updated immediately + // after calculate is invoked + expect(result.length).toEqual(3); + expect(result[0]).toEqual({x: 0, y: 0}); + expect(result[1]).toEqual({x: 0, y: 1}); + expect(result[2]).toEqual({x: 1, y: 1}); + }); - easyStar.calculate(); + it('It should return null directly from the findPathSync method if the path cannot be found', function () { + var easyStar = new EasyStar.js(); + var result; + var grid = [ + [0, 1, 0], + [1, 1, 0], + [0, 0, 0], + ]; + easyStar.setGrid(grid); + easyStar.setAcceptableTiles([0]); + + result = easyStar.findPathSync(0, 0, 2, 2); - // Expect our result to be deferred until - // it is ready - expect(result.length).toEqual(0); + expect(result).toBeNull(); }); }); }); From db6a9fd2462de735aaae3ef990ee62e752956175 Mon Sep 17 00:00:00 2001 From: Mike Smart Date: Wed, 11 Apr 2018 10:57:25 +0100 Subject: [PATCH 3/6] update docs --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 074d82b..ef1c41c 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,9 @@ easystar.setAdditionalPointCost(x, y, cost); easystar.setTileCost(tileType, multiplicativeCost); ``` ```javascript +easystar.findPathSync(startX, startY, endX, endY); +``` +```javascript easystar.enableSync(); ``` ```javascript From c7a3a763f0e1c2eed269de383766d603c82067b4 Mon Sep 17 00:00:00 2001 From: Mike Smart Date: Wed, 11 Apr 2018 11:01:04 +0100 Subject: [PATCH 4/6] remove redundant describe --- test/easystartest.js | 116 +++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 59 deletions(-) diff --git a/test/easystartest.js b/test/easystartest.js index 6de4f77..eb87e5e 100644 --- a/test/easystartest.js +++ b/test/easystartest.js @@ -347,69 +347,67 @@ describe('EasyStar.js', function () { easyStar.calculate(); }); - describe('Synchronous', function () { - it('It should invoke the findPath callback immediately when sync mode is enabled', function () { - var easyStar = new EasyStar.js(); - var result = []; - var grid = [ - [0, 1, 0], - [0, 0, 0], - [0, 0, 0], - ]; - - easyStar.enableSync(); - easyStar.setGrid(grid); - easyStar.setAcceptableTiles([0]); - - easyStar.findPath(0, 0, 1, 1, function (path) { - result.push.apply(result, path); - }); - - easyStar.calculate(); - - // Expect our result to be updated immediately - // after calculate is invoked - expect(result.length).toEqual(3); - expect(result[0]).toEqual({x: 0, y: 0}); - expect(result[1]).toEqual({x: 0, y: 1}); - expect(result[2]).toEqual({x: 1, y: 1}); - }); + it('It should invoke the findPath callback immediately when sync mode is enabled', function () { + var easyStar = new EasyStar.js(); + var result = []; + var grid = [ + [0, 1, 0], + [0, 0, 0], + [0, 0, 0], + ]; - it('It should return the path directly from the findPathSync method', function () { - var easyStar = new EasyStar.js(); - var result; - var grid = [ - [0, 1, 0], - [0, 0, 0], - [0, 0, 0], - ]; - easyStar.setGrid(grid); - easyStar.setAcceptableTiles([0]); - - result = easyStar.findPathSync(0, 0, 1, 1); - - // Expect our result to be updated immediately - // after calculate is invoked - expect(result.length).toEqual(3); - expect(result[0]).toEqual({x: 0, y: 0}); - expect(result[1]).toEqual({x: 0, y: 1}); - expect(result[2]).toEqual({x: 1, y: 1}); + easyStar.enableSync(); + easyStar.setGrid(grid); + easyStar.setAcceptableTiles([0]); + + easyStar.findPath(0, 0, 1, 1, function (path) { + result.push.apply(result, path); }); - it('It should return null directly from the findPathSync method if the path cannot be found', function () { - var easyStar = new EasyStar.js(); - var result; - var grid = [ - [0, 1, 0], - [1, 1, 0], - [0, 0, 0], - ]; - easyStar.setGrid(grid); - easyStar.setAcceptableTiles([0]); + easyStar.calculate(); - result = easyStar.findPathSync(0, 0, 2, 2); + // Expect our result to be updated immediately + // after calculate is invoked + expect(result.length).toEqual(3); + expect(result[0]).toEqual({x: 0, y: 0}); + expect(result[1]).toEqual({x: 0, y: 1}); + expect(result[2]).toEqual({x: 1, y: 1}); + }); - expect(result).toBeNull(); - }); + it('It should return the path directly from the findPathSync method', function () { + var easyStar = new EasyStar.js(); + var result; + var grid = [ + [0, 1, 0], + [0, 0, 0], + [0, 0, 0], + ]; + easyStar.setGrid(grid); + easyStar.setAcceptableTiles([0]); + + result = easyStar.findPathSync(0, 0, 1, 1); + + // Expect our result to be updated immediately + // after calculate is invoked + expect(result.length).toEqual(3); + expect(result[0]).toEqual({x: 0, y: 0}); + expect(result[1]).toEqual({x: 0, y: 1}); + expect(result[2]).toEqual({x: 1, y: 1}); + }); + + it('It should return null directly from the findPathSync method if the path cannot be found', function () { + var easyStar = new EasyStar.js(); + var result; + var grid = [ + [0, 1, 0], + [1, 1, 0], + [0, 0, 0], + ]; + easyStar.setGrid(grid); + easyStar.setAcceptableTiles([0]); + + result = easyStar.findPathSync(0, 0, 2, 2); + + expect(result).toBeNull(); }); }); From 28122c353c9fa47e1b8fb8978835843627756155 Mon Sep 17 00:00:00 2001 From: Mike Smart Date: Wed, 11 Apr 2018 11:01:50 +0100 Subject: [PATCH 5/6] remive redundant comment --- test/easystartest.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/easystartest.js b/test/easystartest.js index eb87e5e..37b56fc 100644 --- a/test/easystartest.js +++ b/test/easystartest.js @@ -387,8 +387,6 @@ describe('EasyStar.js', function () { result = easyStar.findPathSync(0, 0, 1, 1); - // Expect our result to be updated immediately - // after calculate is invoked expect(result.length).toEqual(3); expect(result[0]).toEqual({x: 0, y: 0}); expect(result[1]).toEqual({x: 0, y: 1}); From 94dd38e1d23b584d19846b0f971a6055a949eeec Mon Sep 17 00:00:00 2001 From: Mike Smart Date: Wed, 11 Apr 2018 12:10:01 +0100 Subject: [PATCH 6/6] build --- bin/easystar-0.4.3.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/easystar-0.4.3.min.js b/bin/easystar-0.4.3.min.js index 164e752..644cb6c 100644 --- a/bin/easystar-0.4.3.min.js +++ b/bin/easystar-0.4.3.min.js @@ -1 +1 @@ -var EasyStar=function(t){function n(o){if(e[o])return e[o].exports;var r=e[o]={exports:{},id:o,loaded:!1};return t[o].call(r.exports,r,r.exports,n),r.loaded=!0,r.exports}var e={};return n.m=t,n.c=e,n.p="",n(0)}([function(t,n,e){var o={},r=e(1),i=e(2),s=e(3);const u=0,a=1;t.exports=o;var l=1;o.js=function(){var t,n,e,c=1,f=1.4,h=!1,p={},d={},v={},y={},T=!0,g={},x=[],O=Number.MAX_VALUE,b=!1;this.setAcceptableTiles=function(t){t instanceof Array?e=t:!isNaN(parseFloat(t))&&isFinite(t)&&(e=[t])},this.enableSync=function(){h=!0},this.disableSync=function(){h=!1},this.enableDiagonals=function(){b=!0},this.disableDiagonals=function(){b=!1},this.setGrid=function(n){t=n;for(var e=0;et[0].length-1||o>t.length-1||i>t[0].length-1||u>t.length-1)throw new Error("Your start or end point is outside the scope of your grid.");if(n===i&&o===u)return void f([]);for(var p=t[u][i],d=!1,v=0;v0&&m(r,i,0,-1,c*F(i.x,i.y-1)),i.x0&&m(r,i,-1,0,c*F(i.x-1,i.y)),b&&(i.x>0&&i.y>0&&(T||A(t,e,i.x,i.y-1,i)&&A(t,e,i.x-1,i.y,i))&&m(r,i,-1,-1,f*F(i.x-1,i.y-1)),i.x0&&(T||A(t,e,i.x,i.y-1,i)&&A(t,e,i.x+1,i.y,i))&&m(r,i,1,-1,f*F(i.x+1,i.y-1)),i.x>0&&i.yn?1:0},p=function(t,n,e,o,r){var i;if(null==e&&(e=0),null==r&&(r=s),e<0)throw new Error("lo must be non-negative");for(null==o&&(o=t.length);ee;0<=e?n++:n--)l.push(n);return l}.apply(this).reverse(),a=[],o=0,r=i.length;oy;r=0<=y?++f:--f)T.push(l(t,e));return T},g=function(t,n,e,o){var r,i,u;for(null==o&&(o=s),r=t[e];e>n&&(u=e-1>>1,i=t[u],o(r,i)<0);)t[e]=i,e=u;return t[e]=r},x=function(t,n,e){var o,r,i,u,a;for(null==e&&(e=s),r=t.length,a=n,i=t[n],o=2*n+1;ot[0].length-1||o>t.length-1||r>t[0].length-1||u>t.length-1)throw new Error("Your start or end point is outside the scope of your grid.");if(n===r&&o===u)return void a([]);for(var h=t[u][r],f=!1,p=0;p0&&m(i,r,0,-1,c*E(r.x,r.y-1)),r.x0&&m(i,r,-1,0,c*E(r.x-1,r.y)),b&&(r.x>0&&r.y>0&&(T||P(t,e,r.x,r.y-1,r)&&P(t,e,r.x-1,r.y,r))&&m(i,r,-1,-1,h*E(r.x-1,r.y-1)),r.x0&&(T||P(t,e,r.x,r.y-1,r)&&P(t,e,r.x+1,r.y,r))&&m(i,r,1,-1,h*E(r.x+1,r.y-1)),r.x>0&&r.yn?1:0},p=function(t,n,e,o,i){var r;if(null==e&&(e=0),null==i&&(i=s),e<0)throw new Error("lo must be non-negative");for(null==o&&(o=t.length);ee;0<=e?n++:n--)l.push(n);return l}.apply(this).reverse(),a=[],o=0,i=r.length;oy;i=0<=y?++h:--h)T.push(l(t,e));return T},g=function(t,n,e,o){var i,r,u;for(null==o&&(o=s),i=t[e];e>n&&(u=e-1>>1,r=t[u],o(i,r)<0);)t[e]=r,e=u;return t[e]=i},x=function(t,n,e){var o,i,r,u,a;for(null==e&&(e=s),i=t.length,a=n,r=t[n],o=2*n+1;o