Advertisement
netgrind

MazeGenerator Class

Dec 15th, 2012
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package {
  2.    
  3.     /**
  4.      * ...
  5.      * @author netgrind (Cale Bradbury)
  6.      *
  7.      * If you find this useful let me know, I'd love to see what you do with it. Use it for whatever! (Some credit would be nice though :3)
  8.      *
  9.      * The only function you need to call for a maze is gatMaze.
  10.      * Gat is a spelling mistake for get that I deceide to leave in as I created this for a gun game thing droqen and I were messing around with
  11.      *
  12.      * The function returns an array of 0's and 1's, 0 being solid space (player never touches) and 1's being where the player can be
  13.      *
  14.      * roomSize is number of tiles in a room, it gets around that number as a rectangle (25 could be 5x5 room or 3x8)
  15.      * rooms is the number of rooms it plops down
  16.      * hall length is a buffer of solid around the room so halls can form
  17.      * pillars is how many pillars it just randomly tries to place down all over the map
  18.      * boarder is a boarder of solid around the full map
  19.      * link attempts is how many times it tries to link rooms together, after all the tries it removes any unlinked bits of room
  20.      *
  21.      * The loadout I'm rocking in the demo is MazeGenerator.gatMaze(100, 10, 2, 100, 1);
  22.      *
  23.      * demo - http://www.netgrindgames.com/cale/LD25.swf
  24.      * controls - arrows, restart for a new map.
  25.      */
  26.     public class MazeGenerator {
  27.        
  28.         public static function gatMaze(roomSize:int, rooms:int, hallLength:int,  pillars:int, boarder:int=0, linkAttempts:int = 50):Array {
  29.            
  30.             //var worldSize:int = Math.sqrt(roomSize) + Math.sqrt(rooms) + Math.sqrt(hallLength);
  31.             //var worldSize:int = (roomSize*.5) + (rooms*.5) + (hallLength*.5);
  32.             var worldSize:int = (roomSize + rooms + (hallLength*rooms*.5))*.25;
  33.             var level:Array = getBlankWorld(worldSize, worldSize);
  34.            
  35.             for (var i:int = 0; i < rooms; i++) {
  36.                 var room:Array = createRoom(roomSize, hallLength);
  37.                 level = mergeArrays(level, room, Math.random()*(level.length-room.length), Math.random()*(level[0].length - room[0].length));
  38.             }//end for
  39.            
  40.             level = changeValue(level, 2, 0);
  41.             level = addPaths(level, hallLength, linkAttempts);
  42.             level = addPillars(level, pillars);
  43.             return mergeArrays(getBlankWorld(worldSize+boarder*2, worldSize+boarder*2),level,boarder,boarder);
  44.         }//ed gatMaze
  45.        
  46.         static public function addPillars(level:Array, pillars:int):Array {
  47.             do {
  48.                
  49.                 pillars--;
  50.                 var i:int = Math.ceil(Math.random() * (level.length - 3)) + 2;
  51.                 var j:int = Math.ceil(Math.random() * (level[0].length - 3)) + 2;
  52.                 if (
  53.                 level[i][j] == 1 &&
  54.                 level[i+1][j] == 1 &&
  55.                 level[i-1][j] == 1 &&
  56.                 level[i-1][j+1] == 1 &&
  57.                 level[i-1][j-1] == 1 &&
  58.                 level[i+1][j-1] == 1 &&
  59.                 level[i+1][j+1] == 1 &&
  60.                 level[i][j+1] == 1 &&
  61.                 level[i][j - 1] == 1) {
  62.                     level[i][j] = 0;
  63.                 }
  64.             }while (pillars > 0 );
  65.             return level;
  66.         }
  67.        
  68.         public static function addPaths(level:Array,path:int, attempts:int):Array {
  69.            
  70.             do {
  71.                 var i:int = Math.floor(Math.random() * level.length);
  72.                 var j:int = Math.floor(Math.random() * level[0].length);
  73.             }while (level[i][j] != 1);
  74.             var hasHitEmpty:Boolean = false;
  75.             for (var k:int = j; k < level[i].length; k++) {
  76.                 if (level[i][k] == 0 ) {//&& level[i][k - path] == 1 && level[i][k+path]==1 ) {
  77.                     hasHitEmpty = true;
  78.                 }else if (hasHitEmpty&&level[i][k] == 1) {
  79.                     for (var n:int = j; n <= k; n++){
  80.                         level[i][n] = 1;
  81.                     }
  82.                     break;
  83.                 }
  84.             }//end for
  85.             if (levelValid(level)) {
  86.                 return level;
  87.             }else {
  88.                 attempts --;
  89.                 if(attempts>0){
  90.                     level = rotateArray(level);
  91.                     level = addPaths(level, path, attempts);
  92.                 }else {
  93.                     var biggest:int = 0;                   
  94.                     for (i = 0; i < level.length; i++) {
  95.                         for (j = 0; j < level[i].length; j++) {
  96.                             if (level[i][j] == 1) {
  97.                                 floodFill(level, i, j, 1, 2);
  98.                                 var size:int = numberOfValue(level, 2);
  99.                                 if (size > biggest) {
  100.                                     biggest = size;
  101.                                     changeValue(level, 3, 0);
  102.                                     changeValue(level, 2, 3);
  103.                                 }else {
  104.                                     changeValue(level,2, 0);
  105.                                 }
  106.                                
  107.                             }
  108.                         }
  109.                     }
  110.                     changeValue(level, 3, 1);
  111.                 }
  112.             }
  113.             return level;
  114.            
  115.         }
  116.        
  117.         public static function levelValid(level:Array):Boolean{
  118.             for (var i:int = 0; i < level.length; i++) {
  119.                 var j:int = level[i].lastIndexOf(1);
  120.                 if(j!=-1){
  121.                     level = floodFill(level, i, j, level[i][j], 9);
  122.                     if (hasNoValue(level, 1)) {
  123.                         changeValue(level, 9, 1);
  124.                         return true;
  125.                     }else {
  126.                         changeValue(level, 9, 1);
  127.                         return false;
  128.                     }
  129.                 }
  130.             }
  131.             return false;
  132.         }
  133.        
  134.         public static function hasNoValue(a:Array, val:*):Boolean {
  135.             for (var i:int = 0; i < a.length; i++) {
  136.                 if (a[i].indexOf(val) != -1) {
  137.                     return false
  138.                 }
  139.             }//end for
  140.             return true;
  141.         }
  142.        
  143.         public static function floodFill(a:Array, i:int, j:int, oldVal:*, newVal:*):Array {
  144.             if(i>-1&& i<a.length && j>-1 && j < a[i].length){
  145.                 if (a[i][j] == oldVal) {
  146.                     a[i][j] = newVal;
  147.                     floodFill(a, i + 1, j, oldVal, newVal);
  148.                     floodFill(a, i - 1, j, oldVal, newVal);
  149.                     floodFill(a, i, j+1, oldVal, newVal);
  150.                     floodFill(a, i, j-1, oldVal, newVal);
  151.                 }
  152.             }
  153.             return a
  154.         }
  155.        
  156.         public static function changeValue(a:Array, oldVal:*, newVal:*):Array{
  157.             for (var i:int = 0; i < a.length; i++) {
  158.                 for (var j:int = 0; j < a[i].length; j++) {
  159.                     if (a[i][j] == oldVal) {
  160.                         a[i][j] = newVal;
  161.                     }
  162.                 }
  163.             }
  164.             return a;
  165.         }
  166.        
  167.         public static function addRoom(parent:Array, room:Array):Array {
  168.             for (var i:int = 0; i < parent.length-room.length-1; i++) {
  169.                 for (var j:int = 0; j < parent[i].length - room[0].length-1; j++) {
  170.                     if (parent[i][j] == 0 &&
  171.                         parent[i + room.length][j] == 0 &&
  172.                         parent[i + room.length][j + room[0].length] == 0 &&
  173.                         parent[i][j + room[0].length] == 0
  174.                         ) {
  175.                            
  176.                             trace(parent);
  177.                             return mergeArrays(parent, room, i, j);
  178.                         }//end if  
  179.                 }//end for             
  180.             }//end for
  181.             return(parent);
  182.         }//end add Room
  183.        
  184.         public static function mergeArrays(parent:Array, child:Array, x:int, y:int):Array {
  185.             for (var i:int = 0; i < child.length; i ++) {
  186.                 for (var j:int = 0; j < child[i].length; j++) {
  187.                     parent[i + x][j + y] = child[i][j];
  188.                 }//end for
  189.             }
  190.             return parent;
  191.         }
  192.        
  193.         public static function createRoom(size:int, hallLength:int):Array {
  194.             var used:int = 0;
  195.             var side:int = Math.sqrt(size);
  196.             var dif:int = side * Math.random() * .5 + .25; 
  197.             var room:Array = getBlankWorld( side - dif, side + dif, 1);
  198.             if (Math.random() < 0.5) {
  199.                 rotateArray(room);
  200.             }
  201.             return mergeArrays(getBlankWorld(room.length+hallLength*2, room[0].length + hallLength*2, 2), room,hallLength, hallLength);
  202.         }//end createRoom;
  203.        
  204.         public static function rotateArray(room:Array):Array {
  205.             var a:Array = new Array();
  206.             for (var i:int = 0; i < room.length; i++) {
  207.                
  208.                 for (var j:int = 0; j < room[0].length; j++) {
  209.                     if (!a[j]) {
  210.                         a[j] = new Array();
  211.                     }
  212.                     a[j][i] = room[i][j];                  
  213.                 }//end for             
  214.             }//end for
  215.             return a;
  216.         }//end rotateArray
  217.        
  218.         public static function getBlankWorld(width:int, height:int, fill:int = 0):Array {
  219.             var a:Array = new Array();
  220.             for (var i:int = 0; i < width; i++) {
  221.                 a.push(new Array());
  222.                 for (var j:int = 0; j < height; j++) {
  223.                     a[i][j] = fill;
  224.                 }//end for
  225.             }//end for
  226.             return a;
  227.         }//end getBlankWorld
  228.        
  229.         public static function numberOfValue(a:Array, value:*):int {
  230.             var c:int = 0;
  231.             for (var i:int = 0; i < a.length; i++) {
  232.                 for (var j:int = 0; j < a[i].length; j++) {
  233.                     if (a[i][j] == value) {
  234.                         c++;
  235.                     }
  236.                 }
  237.             }
  238.             return c;
  239.         }
  240.        
  241.     }
  242.    
  243. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement