Robson » Code Viewer
- Path: code/maze.php
- Lines: 452
- Size: 16.39kB
<? /* 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