PHP Maze

Hit Reload (F5) to view different maze.

maze.php Source Code


<?php
header('Content-type: image/png'); // PHP Maze (C) 2011 Russell Sasamori
// k=maze size, s=array size, r=cell size (in pixels), count=cells visited.
$k=19;$s=$k*2+3;$r=10;$count=1;
$im = @imagecreatetruecolor($r*$s+1,$r*$s+1)
	or die('Cannot initialize new GD image stream');
$c1 = imagecolorallocate($im,255,255,255); // Paint background white.
imagefilledrectangle($im,0,0,$r*$s+1,$r*$s+1,$c1);
$a=array(); // A [Row][Col] array of cells (0=open, 1=filled) of the maze.
for($y=0;$y<$s;$y++) { // Initialize array to all 1 (green).
	for($x=0;$x<$s;$x++) {
		$a[$y][$x]=1;
	}
}
for($x=0;$x<$s;$x++) { // Clear rim to 0, to serve as a barricade.
	$a[0][$x]=0;$a[$s-1][$x]=0;
	$a[$x][0]=0;$a[$x][$s-1]=0;
}
$x=$y=($k-1)>>1;$a[$y*2+2][$x*2+2]=0; // start from center
while(1) { // Open paths for k^2 cells.
	do { // Dig as far as possible until we reach a cul-de-sac.
		$d=rand(0,3); // Pick initial direction raqndomly.
		for($i=0;$i<4;$i++) { // Look for a good direction.
			if($d==0 && $a[$y*2+2][$x*2+4]) { // right
				$a[$y*2+2][$x++*2+3]=0;$a[$y*2+2][$x*2+2]=0;
				$i=5;$count++;break; // found
			} elseif($d==1 && $a[$y*2][$x*2+2]) { // up
				$a[$y--*2+1][$x*2+2]=0;$a[$y*2+2][$x*2+2]=0;
				$i=5;$count++;break; // found
			} elseif($d==2 && $a[$y*2+2][$x*2]) { // left
				$a[$y*2+2][$x--*2+1]=0;$a[$y*2+2][$x*2+2]=0;
				$i=5;$count++;break; // found
			} elseif($d==3 && $a[$y*2+4][$x*2+2]) { // down
				$a[$y++*2+3][$x*2+2]=0;$a[$y*2+2][$x*2+2]=0;
				$i=5;$count++;break; // found
			}
			$d=($d+1)%4; // wrap right->up->left->down->right
		} // for
	} while ($i!=4); // i=4 means we are stuck
	if($count>=$k*$k) { // Did we visit k^2 cells?
		break; // while(1) The entire maze has been created.
	}
	$x=rand(0,$k-1);$y=rand(0,$k-1); // Pick random cell on maze.
	// Scan left-to-right top-to-botton for a dug cell with at least
	while($a[$y*2+2][$x*2+2] || // one expandable neighbor
		!$a[$y*2+2][$x*2+4] && !$a[$y*2][$x*2+2] &&
		!$a[$y*2+2][$x*2] && !$a[$y*2+4][$x*2+2]) {
		if(++$x>=$k) { // wrap right edge to left edge
			$x=0;
			if(++$y>=$k) { // wrap bottom to top
				$y=0;
			}
		}
	}
} // while(1)
$a[1][2]=0;$a[$k*2+1][$k*2]=0; // Draw entrance and exit.
$c2 = imagecolorallocate($im, 0, 200, 0); // Paint wall green.
for($y=0;$y<$s;$y++) { // Dump array content on screen.
	for($x=0;$x<$s;$x++) {
		if($a[$y][$x]) {
			imagefilledrectangle($im,$x*$r,$y*$r,($x+1)*$r-1,
			($y+1)*$r-1,$c2);
		}
	}
}
imagepng($im);
imagedestroy($im);
?>

Last modified 07/22/2011

Home