Advertisement
Guest User

Untitled

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