Thread: MazeGenerator
View Single Post
  #14  
Old 10-11-2010, 08:19 AM
fowlplay4 fowlplay4 is offline
team canada
fowlplay4's Avatar
Join Date: Jul 2004
Location: Canada
Posts: 5,200
fowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond reputefowlplay4 has a reputation beyond repute
You inspired me to take a shot at the maze generator thing.

Uses.. Depth-first search algorithm

The grid output is a fairly simple array.

grid[y][x][wall direction (0 to 3)] == wall alive boolean

My implementation does have it's limitations however I narrowed out the maximum size to be 35 by 35 but depending on your application (random dungeon level generator for example) that should be more than enough.

PHP Code:
function onCreated() {
  
// Generate Maze
  
temp.maze generateMaze(3535);
  
// For added fun!
  
randomDestruction(temp.maze.link(), 20);
  
// Example output
  
drawGrid(temp.maze.link());
}

public function 
generateMaze(temp.widthtemp.height) {
  
// Generate Blank Grid
  
temp.cells  = new[temp.height][temp.width][5];
  
// Begin Adding Rows
  
for (temp.0temp.temp.widthtemp.y++) {
    
// Begin Adding Columns
    
for (temp.0temp.temp.heighttemp.x++) {
      
// Generate Cells
      
temp.cell = {1111false};
      
// Add Cell to Column
      
temp.cells[temp.y][temp.x] = temp.cell;
      
temp.i++;
    }
  }
  
// Pick Exit
  
temp.exit_x int(random(0temp.width));
  
temp.exit_y int(random(0temp.height));
  
// Mark Exit
  
temp.cells[temp.exit_y][temp.exit_x][4] = true;
  
// Begin Carving
  
carveMaze(temp.cells.link(), temp.exit_xtemp.exit_y);
  
// Trim Visited Fat
  
for (temp.0temp.temp.widthtemp.y++) {
    for (
temp.0temp.temp.heighttemp.x++) {
      
temp.cells[temp.y][temp.x].delete(4);
    }
  }
  
// Return Grid
  
return temp.cells;
}

function 
carveMaze(cellscxcy) {
  
// Determine Grids Width and Height
  
temp.height cells.size();
  
temp.width  cells[0].size();
  
// Find Unvisited Neighbour Cells
  
for (temp.0temp.4temp.i++) {
    
temp.tx cx vecx(temp.i);
    
temp.ty cy vecy(temp.i);
    if (
cells[ty][tx].size() == 5) {
      if (
cells[ty][tx][4] == false) {
        
temp.unvisited.add(temp.i);
      }
    }
  }
  
// Check if has Unvisited Neighbours
  
temp.neighbours temp.unvisited.size();
  if (
temp.neighbours 0) {
    
// Pick Unvisited Neighbour
    
temp.neighbour temp.unvisited[int(random(0temp.neighbours))];
    
temp.tx cx vecx(temp.neighbour);
    
temp.ty cy vecy(temp.neighbour);
    
// Remove Wall between Neighbours
    
cells[cy][cx][temp.neighbour] = 0;
    
cells[ty][tx][(temp.neighbour 2) % 4] = 0;
    
// Set Neighbour Cell to Visited
    
cells[ty][tx][4] = true;
    
// Continue Carving as Neighbour
    
carveMaze(cells.link(), temp.txtemp.ty);
    
// Continue Carving Local Neighbours
    
if (temp.neighbours 0carveMaze(cells.link(), cxcy);
  }
}

public function 
randomDestruction(cellswalls) {
  
// Determine Grids Width and Height
  
temp.height cells.size();
  
temp.width  cells[0].size();
  
// Check for Proper Cell
  
if (cells[0][0].size() != 4) return false;
  
// Begin Random Destruction
  
while (walls 0) {
    
// Pick a Random Cell
    
temp.cx int(random(0temp.width));
    
temp.cy int(random(0temp.height));
    
// Pick a Random Neighbour
    
temp.neighbour int(random(04));
    
temp.tx cx vecx(temp.neighbour);
    
temp.ty cy vecy(temp.neighbour);
    
// Skip Non-Cells
    
if (cells[temp.tx][temp.ty].size() != 4) continue;
    
// Check if Wall Exists
    
if (cells[temp.cy][temp.cx][temp.neighbour] == true) {
      
// Remove Wall
      
cells[cy][cx][temp.neighbour] = 0;
      
cells[ty][tx][(temp.neighbour 2) % 4] = 0;
      
walls--;
    }
  }  
}

/*
   Example Rendering of a Maze
*/

public function drawGrid(cells) {
  
// Determine Grids Width and Height
  
temp.height cells.size();
  
temp.width  cells[0].size();
  
// Check for Proper Cell
  
if (cells[0][0].size() != 4) return false;
  
// Drawing Configuration
  
temp.cell_width  24;
  
temp.cell_height 24;
  
temp.lw          1;  // Line Width
  // Create Drawing Panel
  
temp.panel = new TDrawingPanel();
  
// Line Drawing Functionality (drawline is a jerk)
  
temp.panel.drawhoriz = function (x1y1width) {
    
this.drawimagestretched(params[0], params[1], width1"whitefill.png"0011);
  };
  
temp.panel.drawvert = function (x1y1height) {
    
this.drawimagestretched(params[0], params[1], 1height"whitefill.png"0011);
  };
  
// Set Panel Size
  
temp.panel.setsize(temp.width temp.cell_widthtemp.height temp.cell_height);
  
// Fill Image
  
temp.panel.drawimagestretched(00temp.width temp.cell_widthtemp.height temp.cell_height"blackfill.png"0011);
  
// Begin Drawing Cells
  
for (temp.0temp.temp.widthtemp.y++) {
    for (
temp.0temp.temp.heighttemp.x++) {
      
temp.cell cells[temp.y][temp.x];
      for (
temp.0temp.4temp.i++) {
        
// Check if Wall on that Direction
        
if (temp.cell[temp.i]) {
          
// Determine Top Corner
          
temp.tx temp.temp.cell_width;
          
temp.ty temp.temp.cell_height;
          
// Draw Walls
          
if (temp.== 0temp.panel.drawhoriz(temp.txtemp.tytemp.cell_width);
          else if (
temp.== 1temp.panel.drawvert(temp.txtemp.tytemp.cell_height);
          else if (
temp.== 2temp.panel.drawhoriz(temp.txtemp.ty temp.cell_height 1temp.cell_width);
          else if (
temp.== 3temp.panel.drawvert(temp.tx temp.cell_width 1temp.tytemp.cell_height);
        }
      }
    }
  }
  
// Save Image (change this to somewhere meaningful to yourself)
  
temp.panel.saveimage("cartridge/testmaze.png");
  
// Destroy Panel
  
temp.panel.destroy();

Attached, images used in script and an example output.

http://img40.imageshack.us/img40/7562/whitefill.png
http://img259.imageshack.us/img259/9659/blackfill.png
Attached Thumbnails
Click image for larger version

Name:	testmaze.png
Views:	340
Size:	14.8 KB
ID:	51825  
__________________
Quote:

Last edited by fowlplay4; 10-11-2010 at 08:51 AM..
Reply With Quote