<!-- Original:  Jason Hotchkiss (jasonhotchkiss@home.com) -->

<!-- This script and many more are available free online at -->
<!-- The JavaScript Source!! http://javascript.internet.com -->

<!-- Begin
// The binary data for the maze
var map = [
[ 255, 255, 255, 255, 255, 255, 255, 255 ],
[ 162,   8,   3, 248,   0,   0,   0,  17 ],
[ 136, 162, 235, 251, 254, 237, 221, 213 ],
[ 187, 190,  10, 170, 162,  68, 136, 149 ],
[ 136, 130, 186, 170, 171,  86, 170, 181 ],
[ 238, 250, 130,   0,  10,  68, 136, 149 ],
[ 130, 130,  30, 255, 250, 238, 221, 213 ],
[ 186, 190, 248, 128,   2, 137,  17,  21 ],
[ 168,  32,   2,  42, 174, 187, 119, 117 ],
[ 139, 239, 235, 170, 226,  34,  68,  69 ],
[ 250,  40,  32, 170,  42, 190, 255, 213 ],
[ 130, 234, 182, 162, 170, 138,   0,  21 ],
[ 170, 136,  34,  62, 170,  34, 255, 253 ],
[ 168, 191, 168, 160, 131, 234, 162,  35 ],
[ 175, 160, 170, 175, 170,  14, 186, 233 ],
[ 168,  42,  42, 234, 170, 224, 130,  37 ],
[ 163, 171, 162,   0,  34,  63, 187, 181 ],
[ 190,  34,  63, 127, 254, 138, 160, 133 ],
[ 162, 234, 160,  16,  34,  40, 189,  85 ],
[ 138, 170, 175, 213, 226, 238, 165, 125 ],
[ 248, 162,  40,  84,  34,   8,   8,  37 ],
[ 130,  43, 171,  85, 163, 235, 251, 169 ],
[ 175, 234,  33,  20, 130,   9,   1,  15 ],
[ 160,  66, 173, 246, 174, 253, 125,  97 ],
[ 191,  94,  32, 162,  32,   5,  69,  45 ],
[ 162,  75, 234,  43, 238, 213,  21, 105 ],
[ 168, 106,  42, 238,   2,  17,  68,  37 ],
[ 175, 202, 130,   2, 171,  95,  95, 141 ],
[ 168, 154, 254, 190, 171, 113,  18, 213 ],
[ 130,   2,   0, 128,   2,   4,  70,   5 ],
[ 255, 255, 255, 255, 255, 255, 255, 255 ]
];

// The visible part of the map
var aspect = [];

// The character map of the viewport
var view = [];

var exitx=24,exity=57,xpos,ypos,dir,mapon,steps,cheats;

// Function to initialise the variables.
function start() {
xpos = 1;
ypos = 1;
dir=2;
steps=0;
cheats=0;
setTimeout("draw()",100);
}

// function to lookup contents of a position in the map
function getGrid(x,y) {
if( x<0 || x>30 || y<0 || y>63 )
return true;
if( ((map[x][Math.floor(y/8)]) & (128>>>(y%8))) > 0 )
return true;
return false;
}

// function to render a wall
function render( col, len, data ) {
var i;
for( i=0; i<14; ++i )
view[i] = view[i].substr(0,col) + data[i] + view[i].substr(col+len,27-col-len);
}

// function to update the display
function draw() {
var atexit;
mapon = false;

// Fill the 'aspect' array with positions of visible walls
switch(dir) {
case 0: 
aspect = [  getGrid(xpos,ypos-1),getGrid(xpos,ypos+1),getGrid(xpos-1,ypos-1),
getGrid(xpos-1,ypos),getGrid(xpos-1,ypos+1),getGrid(xpos-2,ypos-1),
getGrid(xpos-2,ypos),getGrid(xpos-2,ypos+1),getGrid(xpos-3,ypos-1),
getGrid(xpos-3,ypos),getGrid(xpos-3,ypos+1),getGrid(xpos-4,ypos) ];
atexit = (xpos == exitx + 1 && ypos == exity );
break;
case 1:
aspect = [  getGrid(xpos-1,ypos),getGrid(xpos+1,ypos),getGrid(xpos-1,ypos+1),
getGrid(xpos,ypos+1),getGrid(xpos+1,ypos+1),getGrid(xpos-1,ypos+2),
getGrid(xpos,ypos+2),getGrid(xpos+1,ypos+2),getGrid(xpos-1,ypos+3),
getGrid(xpos,ypos+3),getGrid(xpos+1,ypos+3),getGrid(xpos,ypos+4) ];
atexit = (xpos == exitx && ypos == exity-1 );
break;
case 2:
aspect = [  getGrid(xpos,ypos+1),getGrid(xpos,ypos-1),getGrid(xpos+1,ypos+1),
getGrid(xpos+1,ypos),getGrid(xpos+1,ypos-1),getGrid(xpos+2,ypos+1),
getGrid(xpos+2,ypos),getGrid(xpos+2,ypos-1),getGrid(xpos+3,ypos+1),
getGrid(xpos+3,ypos),getGrid(xpos+3,ypos-1),getGrid(xpos+4,ypos) ];
atexit = (xpos == exitx - 1 && ypos == exity );
break;
case 3:
aspect = [  getGrid(xpos+1,ypos),getGrid(xpos-1,ypos),getGrid(xpos+1,ypos-1),
getGrid(xpos,ypos-1),getGrid(xpos-1,ypos-1),getGrid(xpos+1,ypos-2),
getGrid(xpos,ypos-2),getGrid(xpos-1,ypos-2),getGrid(xpos+1,ypos-3),
getGrid(xpos,ypos-3),getGrid(xpos-1,ypos-3),getGrid(xpos,ypos-4) ];
atexit = (xpos == exitx && ypos == exity+1 );
break;
}

// initialise the view data
view = [    "\\                         /","  \\                     /  ",
"    \\                 /    ","      \\             /      ",
"        \\         /        ","          \\     /          ",
"            \\ /            ","            / \\            ",
"          /     \\          ","        /         \\        ",
"      /             \\      ","    /                 \\    ",
"  /                     \\  ","/                         \\" ];

// paint in the visible walls
if( !aspect[0] ) 
render( 0,3, ["   ","==\\","..|","..|","..|","..|","..|","..|","..|","..|","..|","..|","==/","   " ] );
if( !aspect[1] ) 
render( 24,3,["   ","/==","|..","|..","|..","|..","|..","|..","|..","|..","|..","|..","\\==","   " ] );
if( !aspect[2] ) 
render( 2,5, ["     ","\\    ","|    ","|===\\","|...|","|...|","|...|","|...|","|...|","|...|","|===/","|    ","/    ","     " ] );
if( !aspect[4] ) 
render( 20,5,["     ","    /","    |","/===|","|...|","|...|","|...|","|...|","|...|","|...|","\\===|","    |","    \\","     " ] );
if( aspect[3] ) {
render( 2,23,[  "                       ", "=======================", ".......................",
".......................", ".......................", ".......................",
".......................", ".......................", ".......................",
".......................", ".......................", ".......................",
"=======================",
"                       " ] );
}
else {
if( !aspect[5] )
render( 6,3, ["   ","   ","   ","\\  ","|=\\","|.|","|.|","|.|","|.|","|=/","/  ","   ","   ","   " ] );
if( !aspect[7] )
render( 18,3,["   ","   ","   ","  /","/=|","|.|","|.|","|.|","|.|","\\=|","  \\","   ","   ","   " ] );
if( aspect[6] ) {
if( atexit ) {
render( 6,15,[  "               ","               ","               ",
       "===============",".             .",". *********** .",
       ". THE WAY OUT .",". *********** .",".             .",
       ".             .","===============","               ",
       "               ","               " ] );
}
else {
render( 6,15,[  "               ","               ","               ",
       "===============","...............","...............",
       "...............","...............","...............",
       "...............","===============","               ",
       "               ","               " ] );
}
}
else {
if( !aspect[8] )
render( 8,3, ["   ","   ","   ","   ","\\  ","|=\\","|.|","|.|","|=/","/  ","   ","   ","   ","   "] );
if( !aspect[10] )
render( 16,3,["   ","   ","   ","   ","  /","/=|","|.|","|.|","\\=|","  \\","   ","   ","   ","   "] );
if( aspect[9] ) {
render( 8,11,[  "           ","           ","           ","           ",
       "===========","...........","...........","...........",
       "...........","===========","           ","           ",
       "           ","           " ] );
}
else {
if( aspect[11] )
render( 10,7,[  "       ","       ","       ","       ","       ",
           "=======",".......",".......","=======","       ",
           "       ","       ","       ","       " ] );
      }
   }
}

// write data to viewport
var s = "";
var i;
for( i=0; i<14; ++i ) s=s+"  "+view[i]+"  \n";
if(document.layers)
{
document.layers["viewport"].document.open();
document.layers["viewport"].document.write("<pre>"+s+"</pre>");
document.layers["viewport"].document.close();
}
else {
viewport.innerHTML = "<pre>"+s+"</pre>";
}

// display hint
var dist = Math.floor(Math.sqrt((xpos-exitx)*(xpos-exitx) + (ypos-exity)*(ypos-exity)));
var direction = ", exit lies "+dist+" steps to ";
if( xpos>exitx) direction += "north";
if( xpos<exitx) direction += "south";
if( ypos>exity) direction += "west";
if( ypos<exity) direction += "east";

if(document.layers) {
document.layers["readout"].document.open();
document.layers["readout"].document.write("Facing " + ["north","east","south","west"][dir] + direction);
document.layers["readout"].document.close();
}
else {
readout.innerHTML = "Facing " + ["north","east","south","west"][dir] + direction;
   }
}

// Turn around
function turn(x) {
dir += x;
if(dir<0) dir=3;
if(dir>3) dir=0;
draw();
}

// move forward
function move() {
// check there is no wall in front of player
if( !aspect[3] ) {
// change position
switch(dir) {
case 0: xpos--; break;
case 1: ypos++; break;
case 2: xpos++; break;
case 3: ypos--; break;
}
steps++;

// repaint
draw();

// check for completion
if( xpos == exitx && ypos == exity ) {
// finished!
alert(  "Well done! you reached the exit in "+steps+" steps,\n"+
"and you looked at the map "+cheats+" times.\n"+
"Press OK to see if you can do any better." );
start();
      }
   }
}

// show the map
function cheat() {
if( mapon ) {
// hide the map if it is already displayed
draw();
}
else {
// build the map
var x,y,s="";
for(x=xpos-10;x<xpos+10;++x) {
for(y=ypos-10;y<ypos+10;++y) {
if(getGrid(x,y))
s=s+"X";
else if( x==xpos && y==ypos ) {
if(document.layers)
// netscape does not support arrow characters
  s=s+"*"
else
  s=s+["?","?","?","?"][dir];
}
else if( x==exitx && y==exity ) {
if(document.layers)
s=s+"@";
else
s=s+"?";
}
else
s=s+" ";
}
s=s+"\n";
}

// show the map
if( document.layers ) {
document.layers["viewport"].document.open();
document.layers["viewport"].document.write("<pre>"+s+"</pre>");
document.layers["viewport"].document.close();
}
else {
viewport.innerHTML = "<pre>"+s+"</pre>";
}
mapon=true;
cheats++;
   }
}
// go!
start();
//  End -->
