Maze
(source: t15.org)
New
←
↑
↓
→ -
Noop button
I started from the PHP maze generator I found here: http://dev.horemag.net/2008/03/01/php-maze-generation-class/.
EDIT: changed the output to PNG instead of SVG (for better cross browser compatibility).
EDIT 2: added a header for fixing IE cookie compatibility. Should now work correctly in all major browsers.
The image does not refresh if you take the same direction twice (due to the anchor links). Press F5 the second time, or play the maze on my stackoverflow profile.
EDIT 3: Added a no-op button for easily being able to take the same direction twice (see comments below).
<?php
// based upon the maze generator by Evgeni Vasilev (PHP Adaptation)
// see http://dev.horemag.net/2008/03/01/php-maze-generation-class/
class Maze
{
var $maze = array();
var $mx = 0;
var $my = 0;
var $xplayer = 1;
var $yplayer = 1;
function Maze($mx, $my)
{
$mx +=2;
$my +=2;
$this->mx = $mx;
$this->my = $my;
$dx = array( 0, 0, -1, 1 );
$dy = array( -1, 1, 0, 0 );
$todo = array();
$todonum = 0;
for ($x = 0; $x < $mx; ++$x){
for ($y = 0; $y < $my; ++$y){
if ($x == 0 || $x == $mx-1 || $y == 0 || $y == $my-1) {
$this->maze[$x][$y] = 32;
} else {
$this->maze[$x][$y] = 63;
}
}
}
$x = rand(1, $mx-2); $y = rand(1, $my-2);
$x = 1; $y = 1;
$this->maze[$x][$y] &= ~48;
for ($d = 0; $d < 4; ++$d){
if (($this->maze[$x + $dx[$d]][$y + $dy[$d]] & 16) != 0) {
$todo[$todonum++] = (($x + $dx[$d]) << 16) | ($y + $dy[$d]);
$this->maze[$x + $dx[$d]][$y + $dy[$d]] &= ~16;
}
}
while ($todonum > 0) {
$n = rand(0, $todonum-1);
$x = $todo[$n] >> 16;
$y = $todo[$n] & 65535;
$todo[$n] = $todo[--$todonum];
do {
$d = rand(0, 3);
} while (($this->maze[$x + $dx[$d]][$y + $dy[$d]] & 32) != 0);
$this->maze[$x][$y] &= ~((1 << $d) | 32);
$this->maze[$x + $dx[$d]][$y + $dy[$d]] &= ~(1 << ($d ^ 1));
for ($d = 0; $d < 4; ++$d){
if (($this->maze[$x + $dx[$d]][$y + $dy[$d]] & 16) != 0) {
$todo[$todonum++] = (($x + $dx[$d]) << 16) | ($y + $dy[$d]);
$this->maze[$x + $dx[$d]][$y + $dy[$d]] &= ~16;
}
}
}
$this->maze[1][1] &= ~1;
$this->maze[$mx-2][$my-2] &= ~2;
}
function _drawLine($img,$color, $x1, $y1, $x2, $y2)
{
imageline($img, $x1, $y1, $x2, $y2, $color);
}
function _drawPlayer($img, $x, $y, $r, $colorborder, $colorfill)
{
imagefilledellipse($img, $x, $y, $r, $r, $colorfill);
imageellipse($img, $x, $y, $r, $r, $colorborder);
}
function _drawWin($img, $color)
{
imagestring($img, 5, 170, 90, "YOU WIN!", $color);
}
function movePlayerDown()
{
if ($this->yplayer+1 < $this->my-1 && ($this->maze[$this->xplayer][$this->yplayer] & 2) == 0)
$this->yplayer++;
}
function movePlayerUp()
{
if ($this->yplayer-1 > 0 && ($this->maze[$this->xplayer][$this->yplayer] & 1) == 0)
$this->yplayer--;
}
function movePlayerRight()
{
if ($this->xplayer+1 < $this->mx-1 && ($this->maze[$this->xplayer][$this->yplayer] & 8) == 0)
$this->xplayer++;
}
function movePlayerLeft()
{
if ($this->xplayer-1 > 0 && ($this->maze[$this->xplayer][$this->yplayer] & 4) == 0)
$this->xplayer--;
}
function renderImage($xs, $ys)
{
$off = 0;
$w = ($this->mx*$xs)+($off*2); $h = ($this->my*$ys)+($off*2);
$img = imagecreatetruecolor($w, $h);
imagesetthickness($img, 2);
$fg = imagecolorallocate($img, 0, 0, 0);
$bg = imagecolorallocate($img, 248, 248, 248);
$red = imagecolorallocate($img, 255, 0, 0);
imagefill($img, 0, 0, $bg);
if (($this->xplayer == $this->mx-2) && ($this->yplayer == $this->my-2)) {
$this->_drawWin($img, $red);
return $img;
}
for ($y = 1; $y < $this->my-1; ++$y) {
for ($x = 1; $x < $this->mx-1; ++$x){
if (($this->maze[$x][$y] & 1) != 0)
$this->_drawLine ($img, $fg, $x * $xs + $off, $y * $ys + $off, $x * $xs + $xs + $off, $y * $ys + $off);
if (($this->maze[$x][$y] & 2) != 0)
$this->_drawLine ($img, $fg, $x * $xs + $off, $y * $ys + $ys + $off, $x * $xs + $xs + $off, $y * $ys + $ys + $off);
if (($this->maze[$x][$y] & 4) != 0)
$this->_drawLine ($img, $fg, $x * $xs + $off, $y * $ys + $off, $x * $xs + $off, $y * $ys + $ys + $off);
if (($this->maze[$x][$y] & 8) != 0)
$this->_drawLine ($img, $fg, $x * $xs + $xs + $off, $y * $ys + $off, $x * $xs + $xs + $off, $y * $ys + $ys + $off);
if ($x == $this->xplayer && $y == $this->yplayer) {
$this->_drawPlayer ($img, $x * $xs + ($xs/2), $y * $ys + ($ys/2), 14, $fg, $red);
}
}
}
return $img;
}
}
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
session_start();
$orig_url = $_SERVER['HTTP_REFERER'];
if (!isset($_SESSION['maze']) || strpos($orig_url, 'resetmaze')){
$_SESSION['maze'] = new Maze(25,10);
}
$maze = $_SESSION['maze'];
if (strpos($orig_url, 'playerdown')) { $maze->movePlayerDown(); }
if (strpos($orig_url, 'playerup')) { $maze->movePlayerUp(); }
if (strpos($orig_url, 'playerright')) { $maze->movePlayerRight(); }
if (strpos($orig_url, 'playerleft')) { $maze->movePlayerLeft(); }
$img = $maze->renderImage(16,16);
header("Content-Type: image/png");
imagepng($img);
imagedestroy($img);
?>