Advertisement
Guest User

Untitled

a guest
May 5th, 2012
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // javascript-astar
  2. // http://github.com/bgrins/javascript-astar
  3. // Freely distributable under the MIT License.
  4. // Includes Binary Heap (with modifications) from Marijn Haverbeke.
  5. // http://eloquentjavascript.net/appendix2.html
  6.  
  7.  
  8. var GraphNodeType = {
  9.     OPEN: 0,
  10.     WALL: 1
  11. };
  12.  
  13. // Creates a Graph class used in the astar search algorithm.
  14. function Graph(grid) {
  15.     var nodes = [];
  16.  
  17.     var row, rowLength, len = grid.length;
  18.     console.log("Length:" + len);
  19.     for (var x = 0; x < len; ++x) {
  20.         row = grid[x];
  21.         rowLength = row.length;
  22.         nodes[x] = new Array(rowLength);
  23.         for (var y = 0; y < rowLength; ++y) {
  24.             nodes[x][y] = new GraphNode(x, y, row[y]);
  25.         }
  26.     }
  27.  
  28.     this.input = grid;
  29.     this.nodes = nodes;
  30. }
  31.  
  32. Graph.prototype.toString = function() {
  33.     var graphString = "\n";
  34.     var nodes = this.nodes;
  35.     var rowDebug, row, y, l;
  36.     for (var x = 0, len = nodes.length; x < len; x++) {
  37.         rowDebug = "";
  38.         row = nodes[x];
  39.         for (y = 0, l = row.length; y < l; y++) {
  40.             rowDebug += row[y].type + " ";
  41.         }
  42.         graphString = graphString + rowDebug + "\n";
  43.     }
  44.     return graphString;
  45. };
  46.  
  47. function GraphNode(x,y,type) {
  48.     this.data = { };
  49.     this.x = x;
  50.     this.y = y;
  51.     this.pos = {
  52.         x: x,
  53.         y: y
  54.     };
  55.     this.type = type;
  56. }
  57.  
  58. GraphNode.prototype.toString = function() {
  59.     return "[" + this.x + " " + this.y + "]";
  60. };
  61.  
  62. GraphNode.prototype.isWall = function() {
  63.     return this.type == GraphNodeType.WALL;
  64. };
  65.  
  66.  
  67. function BinaryHeap(scoreFunction){
  68.     this.content = [];
  69.     this.scoreFunction = scoreFunction;
  70. }
  71.  
  72. BinaryHeap.prototype = {
  73.     push: function(element) {
  74.         // Add the new element to the end of the array.
  75.         this.content.push(element);
  76.  
  77.         // Allow it to sink down.
  78.         this.sinkDown(this.content.length - 1);
  79.     },
  80.     pop: function() {
  81.         // Store the first element so we can return it later.
  82.         var result = this.content[0];
  83.         // Get the element at the end of the array.
  84.         var end = this.content.pop();
  85.         // If there are any elements left, put the end element at the
  86.         // start, and let it bubble up.
  87.         if (this.content.length > 0) {
  88.              this.content[0] = end;
  89.              this.bubbleUp(0);
  90.         }
  91.         return result;
  92.     },
  93.     remove: function(node) {
  94.         var i = this.content.indexOf(node);
  95.    
  96.         // When it is found, the process seen in 'pop' is repeated
  97.         // to fill up the hole.
  98.         var end = this.content.pop();
  99.  
  100.         if (i !== this.content.length - 1) {
  101.             this.content[i] = end;
  102.            
  103.             if (this.scoreFunction(end) < this.scoreFunction(node)) {
  104.                 this.sinkDown(i);
  105.             }
  106.             else {
  107.                 this.bubbleUp(i);
  108.             }
  109.         }
  110.     },
  111.     size: function() {
  112.         return this.content.length;
  113.     },
  114.     rescoreElement: function(node) {
  115.         this.sinkDown(this.content.indexOf(node));
  116.     },
  117.     sinkDown: function(n) {
  118.         // Fetch the element that has to be sunk.
  119.         var element = this.content[n];
  120.  
  121.         // When at 0, an element can not sink any further.
  122.         while (n > 0) {
  123.  
  124.             // Compute the parent element's index, and fetch it.
  125.             var parentN = ((n + 1) >> 1) - 1,
  126.                 parent = this.content[parentN];
  127.             // Swap the elements if the parent is greater.
  128.             if (this.scoreFunction(element) < this.scoreFunction(parent)) {
  129.                 this.content[parentN] = element;
  130.                 this.content[n] = parent;
  131.                 // Update 'n' to continue at the new position.
  132.                 n = parentN;
  133.             }
  134.  
  135.             // Found a parent that is less, no need to sink any further.
  136.             else {
  137.                 break;
  138.             }
  139.         }
  140.     },
  141.     bubbleUp: function(n) {
  142.         // Look up the target element and its score.
  143.         var length = this.content.length,
  144.             element = this.content[n],
  145.             elemScore = this.scoreFunction(element);
  146.        
  147.         while(true) {
  148.             // Compute the indices of the child elements.
  149.             var child2N = (n + 1) << 1, child1N = child2N - 1;
  150.             // This is used to store the new position of the element,
  151.             // if any.
  152.             var swap = null;
  153.             // If the first child exists (is inside the array)...
  154.             if (child1N < length) {
  155.             // Look it up and compute its score.
  156.             var child1 = this.content[child1N],
  157.                 child1Score = this.scoreFunction(child1);
  158.  
  159.             // If the score is less than our element's, we need to swap.
  160.             if (child1Score < elemScore)
  161.                 swap = child1N;
  162.             }
  163.  
  164.             // Do the same checks for the other child.
  165.             if (child2N < length) {
  166.                 var child2 = this.content[child2N],
  167.                     child2Score = this.scoreFunction(child2);
  168.                 if (child2Score < (swap === null ? elemScore : child1Score)) {
  169.                     swap = child2N;
  170.                 }
  171.             }
  172.  
  173.             // If the element needs to be moved, swap it, and continue.
  174.             if (swap !== null) {
  175.                 this.content[n] = this.content[swap];
  176.                 this.content[swap] = element;
  177.                 n = swap;
  178.             }
  179.  
  180.             // Otherwise, we are done.
  181.             else {
  182.                 break;
  183.             }
  184.         }
  185.     }
  186. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement