Robson » Code Viewer

<?

/*
   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 this
  set_time_limit(20);

  // this checks to see if any spaces are left in the array
  function has_spaces($array)
  {
      // loop through each record
      foreach($array as $record)
      {
          // check if there is space anywhere inside that record
          if (in_array(' ', $record))
              // if so, save that
              $spaces = TRUE;
      }
      // return if the array has space available
      return $spaces;
  }

  // check user entered data

  if (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 spaces
  for ($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 shapes
     
  switch ($_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 points
      case '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 container
      case '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 circle
      case '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 right
      case '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 off
      case '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 corridors
      case '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 middle
      case '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 shown
      default:
          $begin = array(0, 0);
          $end = array($size-1, $size-1);            
      break;
  }    
 
  // generate paths around the grid
     
  do
  {
      // find an available starting square
      do
      {
          // 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 start
          if ((!$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 changes
          if (!mt_rand(0, $straight))
              shuffle($directions);
             
          // loop through the directions (up, down, left, right)    
          foreach ($directions as $way)
          {
              $next[0] = $current[0] + $way[0];
              $next[1] = $current[1] + $way[1];
              // check if this cell is empty
              if ($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