Advertisement
BloodknightStudios

mazegenerator.cs

Jun 5th, 2014
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.97 KB | None | 0 0
  1. function Maze::onLevelLoaded(%this, %scenegraph)
  2. {
  3.    echo("maze loaded");
  4.    
  5.    $SG = %scenegraph;
  6.  
  7.    //create a copy to show to solve path
  8.    %this.solved = $SG.getGlobalTileMap().createTileLayer(
  9.        %this.getTileCount(), %this.getTileSize() );
  10.    %this.solved.class = "Maze";
  11.    %this.solved.setArea( %this.getArea() );
  12.    %this.solved.setLayer(3);
  13.  
  14.    //fill the grid with trapped cells
  15.    %this.init();  
  16.    
  17.    //create a stack to store cells  
  18.    %this.cellStack = new ScriptObject(Stack);  
  19.    
  20.    //create some index vars to track cell creation
  21.    %this.totalCells = %this.getTileCountX() * %this.getTileCountY();
  22.    
  23.    //randomly create a node to start the maze generation
  24.    %startX = getRandom(0, %this.getTileCountX());
  25.    %startY = getRandom(0, %this.getTileCountY());
  26.    %this.currentCell = %startX SPC %startY;
  27.    
  28.    //we've not seen our first cell, so start the simulation
  29.    %this.visitedCells = 1;
  30.    
  31.    %this.schedule(150, generateMaze);
  32. }
  33.  
  34. function Maze::init(%this)
  35. {
  36.    echo("initializing maze");
  37.  
  38.    for(%i = 0; %i < %this.getTileCountX(); %i++)
  39.    {
  40.       for(%j = 0; %j < %this.getTileCountY(); %j++)
  41.       {
  42.          %this.setStaticTile(%i, %j, SquareBordersImageMap, 15);
  43.          %this.setTileCustomData(%i, %j, "15 0");        
  44.       }      
  45.    }
  46.    
  47.    echo("maze initialized");
  48. }
  49.  
  50. function Maze::generateMaze(%this)
  51. {
  52.    $generateStartTime = getRealTime();
  53.    echo("Generating Maze");
  54.  
  55.    %maxX = %this.getTileCountX();
  56.    %maxY = %this.getTileCountY();
  57.  
  58.    while(%this.visitedCells < %this.totalCells)
  59.    {
  60.       %numIntactNeighbors = 0;
  61.  
  62.       %curX = getWord(%this.currentCell, 0);
  63.       %curY = getWord(%this.currentCell, 1);
  64.      
  65.       //find all neighbors of CurrentCell with all walls intact
  66.       //making sure not to overflow the tilemap
  67.       if( %curX > 0 )
  68.       {
  69.          if( %this.walls( %curX - 1, %curY ) == 15 )
  70.          {
  71.             %intactNeighbors[%numIntactNeighbors] = %curX - 1 SPC %curY;
  72.             %numIntactNeighbors++;
  73.          }
  74.       }
  75.  
  76.       if( %curX < %maxX - 1 )
  77.       {
  78.          if( %this.walls( %curX + 1, %curY ) == 15 )
  79.          {
  80.             %intactNeighbors[%numIntactNeighbors] = %curX + 1 SPC %curY;
  81.             %numIntactNeighbors++;
  82.          }
  83.       }
  84.  
  85.       if( %curY > 0 )
  86.       {
  87.          if( %this.walls( %curX, %curY - 1 ) == 15 )
  88.          {
  89.             %intactNeighbors[%numIntactNeighbors] = %curX SPC %curY - 1;
  90.             %numIntactNeighbors++;
  91.          }
  92.       }
  93.  
  94.       if( %curY < %maxY - 1 )
  95.       {
  96.          if( %this.walls( %curX, %curY + 1 ) == 15 )
  97.          {
  98.            %intactNeighbors[%numIntactNeighbors] = %curX SPC %curY + 1;
  99.            %numIntactNeighbors++;
  100.          }
  101.       }
  102.      
  103.       //if one or more found
  104.       if( %numIntactNeighbors > 0 )
  105.       {
  106.          //choose one at random
  107.          %newCellIndex = getRandom( %numIntactNeighbors - 1 );
  108.          %tempCell = %intactNeighbors[%newCellIndex];
  109.              
  110.          //knock down the wall between it and CurrentCell
  111.          %this.knockDownWalls(%this.currentCell, %tempCell);
  112.          
  113.          //push CurrentCell location on the CellStack  
  114.          %this.cellStack.push(%this.currentCell);
  115.          
  116.          //make the new cell CurrentCell  
  117.          %this.currentCell = %tempCell;
  118.          
  119.          //add 1 to VisitedCells
  120.          %this.visitedCells++;
  121.       }
  122.       else
  123.       {
  124.          %this.currentCell = %this.cellStack.pop();
  125.       }
  126.    }  
  127.    
  128.    echo("Generated in" SPC getRealTime() - $generateStartTime SPC "ms.");  
  129.    %this.updateBorders();
  130. }
  131.  
  132. function Maze::knockDownWalls(%this, %cell1, %cell2)
  133. {  
  134.    %cell1X = getWord(%cell1, 0);
  135.    %cell1Y = getWord(%cell1, 1);
  136.    %cell2X = getWord(%cell2, 0);
  137.    %cell2Y = getWord(%cell2, 1);
  138.    
  139.    %cell1TempData = %this.walls(%cell1X, %cell1Y);
  140.    %cell2TempData = %this.walls(%cell2X, %cell2Y);
  141.        
  142.    if(%cell1X - %cell2X < 0 && %cell1Y - %cell2Y == 0 ) //tile to the right
  143.    {  
  144.       %this.setTileCustomData(%cell1X, %cell1Y, %this.walls(%cell1X, %cell1Y) - 2 );
  145.       %this.setTileCustomData(%cell2X, %cell2Y, %this.walls(%cell2X, %cell2Y) - 8 );        
  146.    }
  147.    
  148.    if(%cell1X - %cell2X > 0 && %cell1Y - %cell2Y == 0 ) //tile to the left
  149.    {
  150.       %this.setTileCustomData(%cell1X, %cell1Y, %this.walls(%cell1X, %cell1Y) - 8 );
  151.       %this.setTileCustomData(%cell2X, %cell2Y, %this.walls(%cell2X, %cell2Y) - 2 );
  152.    }
  153.    
  154.    if(%cell1X - %cell2X == 0 && %cell1Y - %cell2Y < 0 ) //tile above
  155.    {
  156.       %this.setTileCustomData(%cell1X, %cell1Y, %this.walls(%cell1X, %cell1Y) - 4 );
  157.       %this.setTileCustomData(%cell2X, %cell2Y, %this.walls(%cell2X, %cell2Y) - 1 );
  158.    }
  159.    
  160.    if(%cell1X - %cell2X == 0 && %cell1Y - %cell2Y > 0 ) //tile below
  161.    {
  162.       %this.setTileCustomData(%cell1X, %cell1Y, %this.walls(%cell1X, %cell1Y) - 1 );
  163.       %this.setTileCustomData(%cell2X, %cell2Y, %this.walls(%cell2X, %cell2Y) - 4 );
  164.    }
  165. }
  166.  
  167. function Maze::walls( %this, %posX, %posY )
  168. {
  169.    return getWord(%this.getTileCustomData(%posX, %posY), 0);
  170. }
  171.  
  172. function Maze::updateBorders( %this )
  173. {
  174.   %maxX = %this.getTileCountX();
  175.   %maxY = %this.getTileCountY();
  176.  
  177.   for( %x = 0; %x < %maxX; %x++ )
  178.   {
  179.     for( %y = 0; %y < %maxY; %y++ )
  180.     {    
  181.       %walls = %this.walls( %x, %y );
  182.      
  183.       %this.setStaticTile( %x, %y, SquareBordersImageMap, %walls );
  184.     }
  185.   }
  186.   %goal = %maxX - 1 SPC %maxY - 1;
  187.   %this.schedule(150, solveMaze, "0 0", %goal);
  188. }
  189.  
  190. function Maze::markVisited(%this, %x, %y)
  191. {  
  192.    %this.setTileCustomData(%x, %y, 1);
  193. }
  194.  
  195. function Maze::visited(%this, %x, %y)
  196. {  
  197.    if(%this.solved.getTileCustomData(%x, %y) == 1)
  198.    {
  199.       return true;
  200.    }
  201.    else
  202.    {
  203.       return false;
  204.    }
  205. }
  206.  
  207. function Maze::solveMaze(%this, %start, %goal)
  208. {
  209.    $solveStartTime = getRealTime();
  210.    echo("Solving Maze.");
  211.  
  212.    %maxX = %this.getTileCountX();
  213.    %maxY = %this.getTileCountY();
  214.    %this.solved.totalCells = %maxX * %maxY;
  215.    
  216.     //create a stack to store cells  
  217.    %this.solved.cellStack = new ScriptObject(Stack);  
  218.    
  219.    %this.solved.currentCell = %start;
  220.    
  221.    %this.solved.visitedCells = 1;
  222.    
  223.    while(%this.solved.currentCell !$= %goal)
  224.    {    
  225.       %this.solved.neighbors = new ScriptObject(Stack);
  226.      
  227.       %curX = getWord(%this.solved.currentCell, 0);
  228.       %curY = getWord(%this.solved.currentCell, 1);
  229.      
  230.       //mark cell visited      
  231.       %this.solved.setStaticTile(%curX, %curY, greenBoxImageMap, 0);    
  232.       %this.solved.setTileCustomData(%curX, %curY, 1);      
  233.      
  234.       //find all neighbors of CurrentCell that are accessible
  235.       //making sure not to overflow the tilemap    
  236.       if( %curX > 0 )
  237.       {
  238.          //if the cell to the left has no right wall
  239.          if( ( %this.walls( %curX - 1, %curY ) & 2 ) == 0 &&
  240.             %this.solved.getTileCustomData(%curX - 1, %curY) != 1)
  241.          {
  242.             %newCell = %curX - 1 SPC %curY;
  243.             %this.solved.neighbors.push(%newCell);
  244.          }
  245.       }
  246.      
  247.       if( %curX < %maxX - 1 )
  248.       {
  249.          //if the cell to the right has no left wall
  250.          if( ( %this.walls( %curX + 1, %curY ) & 8 ) == 0 &&
  251.             %this.solved.getTileCustomData(%curX + 1, %curY) != 1)
  252.          {
  253.             %newCell = %curX + 1 SPC %curY;
  254.             %this.solved.neighbors.push(%newCell);
  255.          }
  256.       }
  257.            
  258.       if( %curY > 0 )
  259.       {
  260.          //if the cell above has no bottom wall
  261.          if( ( %this.walls( %curX, %curY - 1) & 4 ) == 0 &&
  262.             %this.solved.getTileCustomData(%curX, %curY - 1) != 1)
  263.          {
  264.             %newCell = %curX SPC %curY - 1;
  265.             %this.solved.neighbors.push(%newCell);
  266.          }
  267.       }
  268.      
  269.       if( %curY < %maxY - 1 )
  270.       {
  271.          //if the cell below has no top wall
  272.          if( ( %this.walls( %curX, %curY + 1 ) & 1 ) == 0 &&
  273.             %this.solved.getTileCustomData(%curX, %curY + 1) != 1)
  274.          {
  275.             %newCell = %curX SPC %curY + 1;
  276.             %this.solved.neighbors.push(%newCell);
  277.          }
  278.       }
  279.      
  280.       //if one or more found
  281.       if( %this.solved.neighbors.length() > 0 )
  282.       {
  283.          //get the next neighbor
  284.          %tempCell = %this.solved.neighbors.pop();
  285.  
  286.          //push CurrentCell location on the CellStack  
  287.          %this.solved.cellStack.push(%this.solved.currentCell);
  288.  
  289.          //make the new cell CurrentCell  
  290.          %this.solved.currentCell = %tempCell;
  291.       }
  292.       else
  293.       {
  294.          %this.solved.setStaticTile(getWord(%this.solved.currentCell, 0), getWord(%this.solved.currentCell, 1), redBoxImageMap, 0);
  295.          %this.solved.currentCell = %this.solved.cellStack.pop();        
  296.       }      
  297.    }  
  298.    
  299.    echo("Solved in" SPC getRealTime() - $solveStartTime SPC "ms.");  
  300. }
  301.  
  302. /*
  303. Dec Binary
  304. 0      0000
  305. 1      0001
  306. 2      0010
  307. 3      0011
  308. 4      0100
  309. 5      0101
  310. 6      0110
  311. 7      0111
  312. 8      1000
  313. 9      1001
  314. 10     1010
  315. 11     1011
  316. 12     1100
  317. 13     1101
  318. 14     1110
  319. 15     1111
  320. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement