<?/* Maze Generator v1.0 http://iceyboard.no-ip.org/projects/maze_generator/ Copyright (C) 2006-2008 Robson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. The license can be viewed at http://www.gnu.org/licenses/gpl-2.0.txt*/// don't allow too much processing on the server// if you run this script on your computer, you can remove thisset_time_limit(20);// this checks to see if any spaces are left in the arrayfunctionhas_spaces($array){// loop through each recordforeach($arrayas$record){// check if there is space anywhere inside that recordif(in_array(' ',$record))// if so, save that$spaces=TRUE;}// return if the array has space availablereturn$spaces;}// check user entered dataif(intval($_GET['size'])>=5&&intval($_GET['size']<=60))$size=$_GET['size'];else$size=20;if($size<6)$size=6;// the moon shape requires more space if($_GET['shape']=='moon'&&$size<10)$size=10;if(intval($_GET['size_corridor'])>0&&intval($_GET['size_corridor'])<=100)$thickness=$_GET['size_corridor'];else$thickness=10;if(intval($_GET['corridors'])>=0)$straight=intval($_GET['corridors']);else$straight=3;$image_size=($size*$thickness)+1;// create the blank image$im=imagecreate($image_size,$image_size);$add=ceil($thickness/2);// allocate colours to the image// white first, so that's the background$white=imagecolorallocate($im,255,255,255);$black=imagecolorallocate($im,0,0,0);$red=imagecolorallocate($im,255,0,0);$green=imagecolorallocate($im,0,255,0);$blue=imagecolorallocate($im,0,0,255);// various directions that we can go$directions=array(array(0,1,'down','up'),array(1,0,'right','left'),array(0,-1,'up','down'),array(-1,0,'left','right'));// fill with spacesfor($n=0;$n<$size;$n++)// rooms in the maze$squares[$n]=array_fill(0,$size,' ');// create an identical array that will contain the solution $path=$squares;// removes squares in the grid to create shapesswitch($_GET['shape']){// or is it a half-strike? ;)case'strike':for($a=0;$a<$size-floor($size/5);$a++){for($b=0;$b<$a;$b++){$squares[$b][$a+floor($size/5)]=2;$squares[$a+floor($size/5)][$b]=2;}}$begin=array(0,0);$end=array($size-1,$size-1);break;case'diamond':$mid=floor($size/2);if(!($size%2))$even=1;for($a=0;$a<$size-$mid;$a++){for($b=0;$b<$a;$b++){$squares[$b][$a+$mid]=2;$squares[$a+$mid][$b]=2;$squares[$mid-($a+$even)][$b]=2;$squares[$a+$mid][$size-($b+1)]=2;}}$begin=array($mid,0);$end=array($mid,$size-1);break;// star is a diamond with a small square in the middle// that creates eight pointscase'star':$mid=floor($size/2);if(!($size%2))$even=1;for($a=0;$a<$size-$mid;$a++){for($b=0;$b<$a;$b++){$squares[$b][$a+$mid]=2;$squares[$a+$mid][$b]=2;$squares[$mid-($a+$even)][$b]=2;$squares[$a+$mid][$size-($b+1)]=2;}}for($a=intval($size*0.16);$a<intval($size*0.84);$a++){for($b=intval($size*0.16);$b<intval($size*0.84);$b++)$squares[$a][$b]=' ';}$begin=array($mid,0);$end=array($mid,$size-1);break;// triangle slices off the top right corner// similar to a sandwich containercase'triangle':for($a=0;$a<$size;$a++){for($b=0;$b<$a;$b++)$squares[$a][$b]=2;}$begin=array(0,0);$end=array($size-1,$size-1);break;// circles are a bit trickier because it's necessary to work out// the cells that are included inside the circlecase'circle':$mid=$image_size/2;for($a=0;$a<$size;$a++){for($b=0;$b<$size;$b++){$x_dst=($a*$thickness)-$mid;$y_dst=($b*$thickness)-$mid;$distance=sqrt(($x_dst*$x_dst)+($y_dst*$y_dst));if($distance>($image_size*0.48))$squares[$a][$b]=2;}}if($size>=50)$begin=array(floor($size/2),2);else$begin=array(floor($size/2),1);if($size>=55)$end=array(floor($size/2),$size-2);else$end=array(floor($size/2),$size-1);break;// moon is a circle with a small circle just off center to the rightcase'moon':$mid=$image_size/2;for($a=0;$a<$size;$a++){for($b=0;$b<$size;$b++){$x_dst=($a*$thickness)-$mid;$y_dst=($b*$thickness)-$mid;$distance=sqrt(($x_dst*$x_dst)+($y_dst*$y_dst));if($distance>($image_size*0.48))$squares[$a][$b]=2;}}$mid=$image_size/2;$left=$image_size*0.75;for($a=0;$a<$size;$a++){for($b=0;$b<$size;$b++){$x_dst=($a*$thickness)-$left;$y_dst=($b*$thickness)-$mid;$distance=sqrt(($x_dst*$x_dst)+($y_dst*$y_dst));if($distance<($image_size*0.45))$squares[$a][$b]=2;}}$begin=array(floor($size/2),1);$end=array(floor($size/2),$size-1);break;// the two rooms shape has two corridors// although one usually gets closed offcase'two-rooms':for($a=0;$a<ceil($size/2)+2;$a++){for($b=0;$b<ceil($size/2)+2;$b++){$squares[$size-$a][$b]=2;$squares[$a][$size-$b]=2;}}for($a=0;$a<floor($size/2);$a++){for($b=intval($size/4);$b<intval($size*0.75);$b++){$squares[intval($size*0.25)][$b]=' ';$squares[intval($size*0.75)][$b]=' ';$squares[$b][intval($size*0.25)]=' ';$squares[$b][intval($size*0.75)]=' ';$squares[intval($size*0.25)+1][$b]=' ';$squares[intval($size*0.75)+1][$b]=' ';$squares[$b][intval($size*0.25)+1]=' ';$squares[$b][intval($size*0.75)+1]=' ';}}$begin=array(0,0);$end=array($size-1,$size-1);break;// six rooms doesn't actually exist, but everything has a purpose case'six-rooms':exit(chr(82).chr(111).chr(98).chr(115).chr(111).chr(110));break;// four rooms is four filled squares and one thick square to make the corridorscase'four-rooms':$center=floor($size/2);$quarter=floor($size/4);for($n=0;$n<$size;$n++){if($n<>$quarter&&$n<>$size-$quarter&&$n<>$quarter+1&&$n<>$size-$quarter-1){$squares[$n][$center]=2;$squares[$center][$n]=2;$squares[$n][$center-1]=2;$squares[$center-1][$n]=2;$squares[$n][$center+1]=2;$squares[$center+1][$n]=2;}}$begin=array(0,0);$end=array($size-1,$size-1);break;case'l':for($n=$size-intval($size*0.75);$n<$size;$n++){for($b=0;$b<intval($size*0.75);$b++)$squares[$n][$b]=2;}$begin=array(0,0);$end=array($size-1,$size-1);break;// box is cretaed by placing a square in the middlecase'box':for($n=$size-intval($size*0.75);$n<intval($size*0.75);$n++){for($b=$size-intval($size*0.75);$b<intval($size*0.75);$b++)$squares[$n][$b]=2;}$begin=array(0,0);$end=array($size-1,$size-1);break;// the default has all the squares showndefault:$begin=array(0,0);$end=array($size-1,$size-1);break;}// generate paths around the griddo{// find an available starting squaredo{// random cell$start=array(mt_rand(0,$size-1),mt_rand(0,$size-1));// if the first, use any, if not, pick an already taken cell to startif((!$started&&$squares[$start[0]][$start[1]]==' ')||$squares[$start[0]][$start[1]]==1)$current=$start;}while($current<>$start);$squares[$current[0]][$current[1]]=1;$started=true;do{// shuffle the directions based on twisted value// lower means more shuffling and more direction changesif(!mt_rand(0,$straight))shuffle($directions);// loop through the directions (up, down, left, right) foreach($directionsas$way){$next[0]=$current[0]+$way[0];$next[1]=$current[1]+$way[1];// check if this cell is emptyif($squares[$next[0]][$next[1]]==' '){// yes, so move the path into this cell$sq[$current[0]][$current[1]][$way[2]]=1;$sq[$next[0]][$next[1]][$way[3]]=1;$current=$next;$squares[$next[0]][$next[1]]=1;break;}}}while($current==$next&&has_spaces($squares));// when there are no spaces left, exit this loop }while(has_spaces($squares));// draw the borders of the squares to create the maze wallsfor($a=0;$a<count($squares);$a++){for($b=0;$b<count($squares);$b++){// only draw borders on cells which have pathsif($squares[$a][$b]==1){// check directionsif(!$sq[$a][$b]['down'])imageline($im,$a*$thickness,($b+1)*$thickness,($a+1)*$thickness,($b+1)*$thickness,$black);if(!$sq[$a][$b]['up'])imageline($im,$a*$thickness,$b*$thickness,($a+1)*$thickness,$b*$thickness,$black);if(!$sq[$a][$b]['left'])imageline($im,$a*$thickness,$b*$thickness,$a*$thickness,($b+1)*$thickness,$black);if(!$sq[$a][$b]['right'])imageline($im,($a+1)*$thickness,$b*$thickness,($a+1)*$thickness,($b+1)*$thickness,$black);}}}// add the start and end dots// green = start / red = endimagefilledellipse($im,($begin[0]*$thickness)+$add,($begin[1]*$thickness)+$add,$thickness*0.75,$thickness*0.75,$green);imagefilledellipse($im,($end[0]*$thickness)+$add,($end[1]*$thickness)+$add,$thickness*0.75,$thickness*0.75,$red);// solve the mazeif($_GET['solution']){$step=$begin;$path[$step[0]][$step[1]]=1;// solvedo{$is_backtrack=false;$here=$step;// go downif($sq[$step[0]][$step[1]]['down']&&$path[$step[0]][$step[1]+1]==0)$step[1]+=1;// go rightelseif($sq[$step[0]][$step[1]]['right']&&$path[$step[0]+1][$step[1]]==0)$step[0]+=1;// go upelseif($sq[$step[0]][$step[1]]['up']&&$path[$step[0]][$step[1]-1]==0)$step[1]-=1;// go leftelseif($sq[$step[0]][$step[1]]['left']&&$path[$step[0]-1][$step[1]]==0)$step[0]-=1;if($step<>$here)// if an available cell was found, move the current position to there$path[$step[0]][$step[1]]=1;else{$is_backtrack=true;$path[$step[0]][$step[1]]=2;// go upif($sq[$step[0]][$step[1]]['up']&&$path[$step[0]][$step[1]-1]==1)$step[1]-=1;// go downelseif($sq[$step[0]][$step[1]]['down']&&$path[$step[0]][$step[1]+1]==1)$step[1]+=1;// go leftelseif($sq[$step[0]][$step[1]]['left']&&$path[$step[0]-1][$step[1]]==1)$step[0]-=1;// go rightelseif($sq[$step[0]][$step[1]]['right']&&$path[$step[0]+1][$step[1]]==1)$step[0]+=1;}// was this a backtrack from a dead end if($is_backtrack){// if they want to see backtracksif($_GET['backtrack']){// creates three dots each time and nice rounded cornersimagesetstyle($im,array($white,$white,$red));// display the backtrackimageline($im,($here[0]*$thickness)+($thickness/2),($here[1]*$thickness)+($thickness/2),($step[0]*$thickness)+($thickness/2),($step[1]*$thickness)+($thickness/2),IMG_COLOR_STYLED);}else// if the user doesn't want to see backtracks, just override the green with whiteimageline($im,($here[0]*$thickness)+($thickness/2),($here[1]*$thickness)+($thickness/2),($step[0]*$thickness)+($thickness/2),($step[1]*$thickness)+($thickness/2),$white);}else{// creates three dots each time and nice rounded cornersimagesetstyle($im,array($white,$white,$blue));// this is a potential correct path, so colour inimageline($im,($here[0]*$thickness)+($thickness/2),($here[1]*$thickness)+($thickness/2),($step[0]*$thickness)+($thickness/2),($step[1]*$thickness)+($thickness/2),IMG_COLOR_STYLED);}// loop until we reach the end }while($step<>$end);}// output as a png graphicheader('Content-type: image/png');// echo out the contents of the imageimagepng($im);?>