Advertisement
Guest User

Untitled

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