From 1f9224ee82cef57fe12ff0cd584c2db3d7e556a1 Mon Sep 17 00:00:00 2001 From: TiTi Date: Wed, 4 Jun 2014 00:58:21 +0200 Subject: [PATCH 1/9] Code formatting - Only use one var when possible - Define one var on each line (child1N) - Avoid comments on 2 lines for a few chars - Remove unecessary empty lines --- astar.js | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/astar.js b/astar.js index ece7d08..301afe0 100644 --- a/astar.js +++ b/astar.js @@ -56,13 +56,11 @@ var astar = { astar.init(graph); options = options || {}; - var heuristic = options.heuristic || astar.heuristics.manhattan; - var closest = options.closest || false; + var heuristic = options.heuristic || astar.heuristics.manhattan, + closest = options.closest || false; - var openHeap = astar.heap(); - - // set the start node to be the closest if required - var closestNode = start; + var openHeap = astar.heap(), + closestNode = start; // set the start node to be the closest if required start.h = heuristic(start, end); @@ -84,7 +82,7 @@ var astar = { // Find all neighbors for the current node. var neighbors = graph.neighbors(currentNode); - for(var i=0, il = neighbors.length; i < il; i++) { + for(var i = 0, il = neighbors.length; i < il; ++i) { var neighbor = neighbors[i]; if(neighbor.closed || neighbor.isWall()) { @@ -94,8 +92,8 @@ 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; + var gScore = currentNode.g + neighbor.getCost(currentNode), + beenVisited = neighbor.visited; if(!beenVisited || gScore < neighbor.g) { @@ -322,7 +320,6 @@ BinaryHeap.prototype = { // Update 'n' to continue at the new position. n = parentN; } - // Found a parent that is less, no need to sink any further. else { break; @@ -337,11 +334,11 @@ BinaryHeap.prototype = { while(true) { // Compute the indices of the child elements. - var child2N = (n + 1) << 1, child1N = child2N - 1; - // This is used to store the new position of the element, - // if any. - var swap = null; - var child1Score; + var child2N = (n + 1) << 1, + child1N = child2N - 1; + // This is used to store the new position of the element, if any. + var swap = null, + child1Score; // If the first child exists (is inside the array)... if (child1N < length) { // Look it up and compute its score. @@ -369,7 +366,6 @@ BinaryHeap.prototype = { this.content[swap] = element; n = swap; } - // Otherwise, we are done. else { break; From eb5a7dcd54c470ebd95015e0bd0c2221049e1f17 Mon Sep 17 00:00:00 2001 From: TiTi Date: Thu, 12 Jun 2014 19:50:42 +0200 Subject: [PATCH 2/9] Remove extra spaces --- astar.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/astar.js b/astar.js index 301afe0..90dc740 100644 --- a/astar.js +++ b/astar.js @@ -134,15 +134,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); + 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); + 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)); } } From 4db8e5fd78d1f4d0ae9928dd8e64dadc4da3a5b6 Mon Sep 17 00:00:00 2001 From: TiTi Date: Thu, 12 Jun 2014 19:52:12 +0200 Subject: [PATCH 3/9] Fix jshint var is already defined --- test/tests.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/test/tests.js b/test/tests.js index ab2d822..0e3a0ba 100644 --- a/test/tests.js +++ b/test/tests.js @@ -92,11 +92,11 @@ function runSearch(graph, start, end, options) { if (!(graph instanceof Graph)) { graph = new Graph(graph); } - var start = graph.grid[start[0]][start[1]]; - var end = graph.grid[end[0]][end[1]]; - var sTime = new Date(); - var result = astar.search(graph, start, end, options); - var eTime = new Date(); + start = graph.grid[start[0]][start[1]]; + end = graph.grid[end[0]][end[1]]; + var sTime = new Date(), + result = astar.search(graph, start, end, options), + eTime = new Date(); return { result: result, text: pathToString(result), @@ -132,7 +132,9 @@ test( "GPS Pathfinding", function() { function CityGraph(data, links) { this.nodes = []; - var cities = this.cities = {}; + this.links = links; + this.cities = {}; + for (var i = 0; i < data.length; ++i) { var city = data[i], obj = new CityNode(city.name, city.lat, city.lng); @@ -141,11 +143,8 @@ test( "GPS Pathfinding", function() { this.nodes.push(obj); } - cities[obj.name] = obj; + this.cities[obj.name] = obj; } - - this.cities = cities; - this.links = links; } CityGraph.prototype.neighbors = function (node) { From 2aba351bf40d95b6c2e628ba8b1d9154ca40243a Mon Sep 17 00:00:00 2001 From: TiTi Date: Mon, 16 Jun 2014 23:15:31 +0200 Subject: [PATCH 4/9] Untabify demo.js No code change. Only replace tabulations. Thx Notepad2 --- demo/demo.js | 200 +++++++++++++++++++++++++-------------------------- 1 file changed, 100 insertions(+), 100 deletions(-) diff --git a/demo/demo.js b/demo/demo.js index bf0df4a..c6e9bb4 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -1,13 +1,13 @@ -/* demo.js http://github.com/bgrins/javascript-astar - MIT License +/* demo.js http://github.com/bgrins/javascript-astar + MIT License - Set up the demo page for the A* Search + Set up the demo page for the A* Search */ window.log = function(){ - if(this.console){ - console.log( Array.prototype.slice.call(arguments) ); - } + if(this.console){ + console.log( Array.prototype.slice.call(arguments) ); + } }; var WALL = 0; @@ -15,23 +15,23 @@ var OPEN = 1; var generateRandom = function (width, height, wallFrequency) { - var nodes = []; + var nodes = []; for (var x=0; x < width; x++) { - var nodeRow = []; - var gridRow = []; - - for(var y=0; y < height; y++) { - - var isWall = Math.floor(Math.random()*(1/wallFrequency)); - if(isWall == 0) { - nodeRow.push(WALL); - } - else { - nodeRow.push(OPEN); - } - } - nodes.push(nodeRow); + var nodeRow = []; + var gridRow = []; + + for(var y=0; y < height; y++) { + + var isWall = Math.floor(Math.random()*(1/wallFrequency)); + if(isWall == 0) { + nodeRow.push(WALL); + } + else { + nodeRow.push(OPEN); + } + } + nodes.push(nodeRow); } @@ -59,7 +59,7 @@ $(function() { var grid = new GraphSearch($grid, opts, astar.search); $("#btnGenerate").click(function() { - grid.initialize(); + grid.initialize(); }); $selectWallFrequency.change(function() { @@ -113,11 +113,11 @@ GraphSearch.prototype.setOption = function(opt) { GraphSearch.prototype.initialize = function() { var self = this; - this.grid = []; - var nodes = []; - var $graph = this.$graph; + this.grid = []; + var nodes = []; + var $graph = this.$graph; - $graph.empty(); + $graph.empty(); var cellWidth = ($graph.width()/this.opts.gridSize)-2; // -2 for border var cellHeight = ($graph.height()/this.opts.gridSize)-2; @@ -127,36 +127,36 @@ GraphSearch.prototype.initialize = function() { for(var x=0;x"); - var nodeRow = []; - var gridRow = []; - - for(var y=0;yG: " + node.g + "
H: " + node.h; } - if (debug) { - $(this).html(debug); - } - }); + if (debug) { + $(this).html(debug); + } + }); } }; @@ -222,29 +222,29 @@ GraphSearch.prototype.nodeFromElement = function($cell) { GraphSearch.prototype.animateNoPath = function() { var $graph = this.$graph; var jiggle = function(lim, i) { - if(i>=lim) { $graph.css("top", 0).css("left", 0); return; } - if(!i) i=0; - i++; - $graph.css("top", Math.random()*6).css("left", Math.random()*6); - setTimeout( function() { jiggle(lim, i) }, 5 ); + if(i>=lim) { $graph.css("top", 0).css("left", 0); return; } + if(!i) i=0; + i++; + $graph.css("top", Math.random()*6).css("left", Math.random()*6); + setTimeout( function() { jiggle(lim, i) }, 5 ); }; jiggle(15); }; GraphSearch.prototype.animatePath = function(path) { - var grid = this.grid; - var timeout = 1000 / grid.length; - var elementFromNode = function(node) { - return grid[node.x][node.y]; - }; + var grid = this.grid; + var timeout = 1000 / grid.length; + var elementFromNode = function(node) { + return grid[node.x][node.y]; + }; var self = this; // will add start class if final var removeClass = function(path, i) { - if(i>=path.length){ // finished removing path, set start positions + if(i>=path.length){ // finished removing path, set start positions return setStartClass(path, i); } elementFromNode(path[i]).removeClass(css.active); - setTimeout( function() { removeClass(path, i+1) }, timeout*path[i].cost); + setTimeout( function() { removeClass(path, i+1) }, timeout*path[i].cost); } var setStartClass = function(path, i){ if(i === path.length){ @@ -253,11 +253,11 @@ GraphSearch.prototype.animatePath = function(path) { } } var addClass = function(path, i) { - if(i>=path.length) { // Finished showing path, now remove - return removeClass(path, 0); - } - elementFromNode(path[i]).addClass(css.active); - setTimeout( function() { addClass(path, i+1) }, timeout*path[i].cost); + if(i>=path.length) { // Finished showing path, now remove + return removeClass(path, 0); + } + elementFromNode(path[i]).addClass(css.active); + setTimeout( function() { addClass(path, i+1) }, timeout*path[i].cost); }; addClass(path, 0) From 30e1032f5f11240c26a6511b1a8c1efa27830869 Mon Sep 17 00:00:00 2001 From: TiTi Date: Mon, 16 Jun 2014 23:42:39 +0200 Subject: [PATCH 5/9] demo.js code formatting Ability to put breakpoints into setTimeout functions --- demo/demo.js | 121 ++++++++++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 60 deletions(-) diff --git a/demo/demo.js b/demo/demo.js index c6e9bb4..73e7242 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -10,43 +10,38 @@ window.log = function(){ } }; -var WALL = 0; -var OPEN = 1; +var WALL = 0, + OPEN = 1; var generateRandom = function (width, height, wallFrequency) { - var nodes = []; + for (var x = 0; x < width; x++) { + var nodeRow = [], + gridRow = []; - for (var x=0; x < width; x++) { - var nodeRow = []; - var gridRow = []; - - for(var y=0; y < height; y++) { - + for (var y = 0; y < height; y++) { var isWall = Math.floor(Math.random()*(1/wallFrequency)); - if(isWall == 0) { + if (isWall == 0) { nodeRow.push(WALL); } - else { + else { nodeRow.push(OPEN); } } nodes.push(nodeRow); } - return new Graph(nodes); }; $(function() { - var $grid = $("#search_grid"); - var $selectWallFrequency = $("#selectWallFrequency"); - var $selectGridSize = $("#selectGridSize"); - var $checkDebug = $("#checkDebug"); - var $searchDiagonal = $("#searchDiagonal"); - var $checkClosest = $("#checkClosest"); - + var $grid = $("#search_grid"), + $selectWallFrequency = $("#selectWallFrequency"), + $selectGridSize = $("#selectGridSize"), + $checkDebug = $("#checkDebug"), + $searchDiagonal = $("#searchDiagonal"), + $checkClosest = $("#checkClosest"); var opts = { wallFrequency: $selectWallFrequency.val(), @@ -111,28 +106,26 @@ GraphSearch.prototype.setOption = function(opt) { } }; GraphSearch.prototype.initialize = function() { - - var self = this; this.grid = []; - var nodes = []; - var $graph = this.$graph; + var self = this, + nodes = [], + $graph = this.$graph; $graph.empty(); - var cellWidth = ($graph.width()/this.opts.gridSize)-2; // -2 for border - var cellHeight = ($graph.height()/this.opts.gridSize)-2; - var $cellTemplate = $("").addClass("grid_item").width(cellWidth).height(cellHeight); - var startSet = false; + var cellWidth = ($graph.width()/this.opts.gridSize)-2, // -2 for border + cellHeight = ($graph.height()/this.opts.gridSize)-2, + $cellTemplate = $("").addClass("grid_item").width(cellWidth).height(cellHeight), + startSet = false; - for(var x=0;x"); + for(var x = 0; x < this.opts.gridSize; x++) { + var $row = $("
"), + nodeRow = [], + gridRow = []; - var nodeRow = []; - var gridRow = []; - - for(var y=0;yG: " + node.g + "
H: " + node.h; } @@ -213,7 +211,6 @@ GraphSearch.prototype.drawDebugInfo = function(show) { $(this).html(debug); } }); - } }; GraphSearch.prototype.nodeFromElement = function($cell) { @@ -222,18 +219,20 @@ GraphSearch.prototype.nodeFromElement = function($cell) { GraphSearch.prototype.animateNoPath = function() { var $graph = this.$graph; var jiggle = function(lim, i) { - if(i>=lim) { $graph.css("top", 0).css("left", 0); return; } + if(i>=lim) { $graph.css("top", 0).css("left", 0); return; } if(!i) i=0; i++; $graph.css("top", Math.random()*6).css("left", Math.random()*6); - setTimeout( function() { jiggle(lim, i) }, 5 ); + setTimeout(function() { + jiggle(lim, i); + }, 5); }; jiggle(15); }; GraphSearch.prototype.animatePath = function(path) { - var grid = this.grid; - var timeout = 1000 / grid.length; - var elementFromNode = function(node) { + var grid = this.grid, + timeout = 1000 / grid.length, + elementFromNode = function(node) { return grid[node.x][node.y]; }; @@ -244,25 +243,27 @@ GraphSearch.prototype.animatePath = function(path) { return setStartClass(path, i); } elementFromNode(path[i]).removeClass(css.active); - setTimeout( function() { removeClass(path, i+1) }, timeout*path[i].cost); - } - var setStartClass = function(path, i){ - if(i === path.length){ + setTimeout(function() { + removeClass(path, i+1); + }, timeout*path[i].cost); + }; + var setStartClass = function(path, i) { + if(i === path.length) { self.$graph.find("." + css.start).removeClass(css.start); elementFromNode(path[i-1]).addClass(css.start); } - } - var addClass = function(path, i) { + }; + var addClass = function(path, i) { if(i>=path.length) { // Finished showing path, now remove return removeClass(path, 0); } elementFromNode(path[i]).addClass(css.active); - setTimeout( function() { addClass(path, i+1) }, timeout*path[i].cost); + setTimeout(function() { + addClass(path, i+1); + }, timeout*path[i].cost); }; - addClass(path, 0) + addClass(path, 0); this.$graph.find("." + css.start).removeClass(css.start); this.$graph.find("." + css.finish).removeClass(css.finish).addClass(css.start); }; - - From 286160ea15e0c03e2b2418f26cb0f84aace8a9d8 Mon Sep 17 00:00:00 2001 From: TiTi Date: Tue, 17 Jun 2014 00:02:56 +0200 Subject: [PATCH 6/9] Fix jshint warnings in demo.js --- demo/demo.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/demo/demo.js b/demo/demo.js index 73e7242..18867eb 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -21,7 +21,7 @@ var generateRandom = function (width, height, wallFrequency) { for (var y = 0; y < height; y++) { var isWall = Math.floor(Math.random()*(1/wallFrequency)); - if (isWall == 0) { + if (isWall === 0) { nodeRow.push(WALL); } else { @@ -96,7 +96,7 @@ var css = { start: "start", finish: "finish", wall: "wall", active: "active" }; function GraphSearch($graph, options, implementation) { this.$graph = $graph; this.search = implementation; - this.opts = $.extend({wallFrequency:.1, debug:true, gridSize:10}, options); + this.opts = $.extend({wallFrequency:0.1, debug:true, gridSize:10}, options); this.initialize(); } GraphSearch.prototype.setOption = function(opt) { @@ -131,7 +131,7 @@ GraphSearch.prototype.initialize = function() { gridRow.push($cell); var isWall = Math.floor(Math.random()*(1/self.opts.wallFrequency)); - if(isWall == 0) { + if(isWall === 0) { nodeRow.push(WALL); $cell.addClass(css.wall); } @@ -184,7 +184,7 @@ GraphSearch.prototype.cellClicked = function($end) { var fTime = performance ? performance.now() : new Date().getTime(), duration = (fTime-sTime).toFixed(2); - if(!path || path.length == 0) { + if(path.length === 0) { $("#message").text("couldn't find a path (" + duration + "ms)"); this.animateNoPath(); } @@ -239,7 +239,7 @@ GraphSearch.prototype.animatePath = function(path) { var self = this; // will add start class if final var removeClass = function(path, i) { - if(i>=path.length){ // finished removing path, set start positions + if(i >= path.length) { // finished removing path, set start positions return setStartClass(path, i); } elementFromNode(path[i]).removeClass(css.active); @@ -254,7 +254,7 @@ GraphSearch.prototype.animatePath = function(path) { } }; var addClass = function(path, i) { - if(i>=path.length) { // Finished showing path, now remove + if(i >= path.length) { // Finished showing path, now remove return removeClass(path, 0); } elementFromNode(path[i]).addClass(css.active); From bf46862988edfa497b3e05b9fda4934a0a2c1884 Mon Sep 17 00:00:00 2001 From: TiTi Date: Tue, 17 Jun 2014 00:03:29 +0200 Subject: [PATCH 7/9] Refactor drawDebugInfo --- demo/demo.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/demo/demo.js b/demo/demo.js index 18867eb..31b874a 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -101,9 +101,7 @@ function GraphSearch($graph, options, implementation) { } GraphSearch.prototype.setOption = function(opt) { this.opts = $.extend(this.opts, opt); - if(opt["debug"]||opt["debug"]==false) { - this.drawDebugInfo(opt["debug"]); - } + this.drawDebugInfo(); }; GraphSearch.prototype.initialize = function() { this.grid = []; @@ -190,16 +188,14 @@ GraphSearch.prototype.cellClicked = function($end) { } else { $("#message").text("search took " + duration + "ms."); - if(this.opts.debug) { - this.drawDebugInfo(this.opts.debug); - } + this.drawDebugInfo(); this.animatePath(path); } }; -GraphSearch.prototype.drawDebugInfo = function(show) { +GraphSearch.prototype.drawDebugInfo = function() { this.$cells.html(" "); var that = this; - if(show) { + if(this.opts.debug) { that.$cells.each(function(i) { var node = that.nodeFromElement($(this)), debug = false; From 7d7b44707212cf576b6b23258cd5904004b97a45 Mon Sep 17 00:00:00 2001 From: TiTi Date: Tue, 17 Jun 2014 00:08:11 +0200 Subject: [PATCH 8/9] Fix .cost vs .getCost() --- demo/demo.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/demo.js b/demo/demo.js index 31b874a..968639c 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -241,7 +241,7 @@ GraphSearch.prototype.animatePath = function(path) { elementFromNode(path[i]).removeClass(css.active); setTimeout(function() { removeClass(path, i+1); - }, timeout*path[i].cost); + }, timeout*path[i].getCost()); }; var setStartClass = function(path, i) { if(i === path.length) { @@ -256,7 +256,7 @@ GraphSearch.prototype.animatePath = function(path) { elementFromNode(path[i]).addClass(css.active); setTimeout(function() { addClass(path, i+1); - }, timeout*path[i].cost); + }, timeout*path[i].getCost()); }; addClass(path, 0); From 71ecf8e6e6fc9b0af1c397553a080ed1a4bd8932 Mon Sep 17 00:00:00 2001 From: TiTi Date: Tue, 17 Jun 2014 00:23:01 +0200 Subject: [PATCH 9/9] Code formatting (benchmark.js) --- benchmark/benchmark.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/benchmark/benchmark.js b/benchmark/benchmark.js index 8daf24d..5bb1359 100644 --- a/benchmark/benchmark.js +++ b/benchmark/benchmark.js @@ -6,18 +6,18 @@ $(function() { } running = true; - var graph = new Graph(grid); - var start = graph.grid[0][0]; - var end = graph.grid[140][140]; - var results = []; - var times = 0; - + var graph = new Graph(grid), + start = graph.grid[0][0], + end = graph.grid[140][140], + results = [], + times = 0; + for (var i = 0; i < 1000; i++) { - var startTime = performance ? performance.now() : new Date().getTime(); - var result = astar.search(graph, start, end); - var endTime = performance ? performance.now() : new Date().getTime(); + var startTime = performance ? performance.now() : new Date().getTime(), + result = astar.search(graph, start, end), + endTime = performance ? performance.now() : new Date().getTime(); times = times + (endTime - startTime); - + results.push( '
  • Found path with ' + result.length + ' steps. ' + 'Took ' + (endTime - startTime).toFixed(2) + ' milliseconds.
  • '