Crazy Maze

by James Hall: L6 Age ~16

Introduction

This is a remarkable program written by James during his first month of learning Pascal. It is fully commented, makes exemplary use of DIV and MOD for locating cells in grids, and uses a three-dimensional array to process the operation of doors. James constructed the maze maps in a spreadsheet and then concatenated the letters in the cells to obtain long strings to copy into the Pascal code.

Spreadsheet view of map

Spreadsheet View of Map 1 ('a' = empty space; 'b' = wall; 'c' = item; 'd' = door1; 'e' = door2)

We include the following screenshot to show the clear instructions that you need to remember when playing the game.

Instructions to play Crazy Maze

Instructions to play Crazy Maze

The final screenshot shows a game in progress to demonstrate that the progress report can improve (albeit somewhat grudgingly) if you persevere and go through a door for easier pickings!

Screenshot of Crazy Maze in Progress

Crazy Maze in Progress

We invite you to read the code and to customise it. It is not necessary to be able to code an entire program like this in order to make useful extensions to it. You might like to offer more encouragement in the early stages for youngsters. You could keep track of the number of moves (or attempted moves), or compute the time taken. Another option is to edit the maze to make it easier or more difficult to navigate by changing letters in the allmaps array.

The Program

program CrazyMaze;
{$mode objfpc}{$H+}
  
{
      Copyright (c) 2010 James Hall
      
      Licensed under the Apache License, Version 2.0 (the "License"); you may not 
      use this file except in compliance with the License, as described at
      http://www.apache.org/licenses/ and http://www.pp4s.co.uk/licenses/
}
  
uses
  crt;  //This crt usage is essential to the program, but is only readily available in Lazarus.
        //(If you want to compile this code on Delphi please refer to the pp4s website.)
var
  X, Y, points, doorhit, currentmap : integer; // X and Y are the co-ordinates of the character, points is self-explanatory,
                                              // doorhit is the door number on which the character is standing, currentmap is the current map number
  name : string;  //Name is the name of the player.
  g:array[1..60,1..20] of char; //This array will contain the grid shown on screen. (Notice how the array is 60X20)
  allmaps:array[1..4,1..5] of string; //This array contains all the map strings.
  doors:array[1..4, 1..2, 1..3] of integer; {This array contains information on the doors in this order:
                                             [map currently in, door number in room, new map info] new map
                                             info has 3 numbers, which specify map to change to, new X value, and new Y value}
  hit, chosenchar : char; //hit contains the character code for which tile the player is currently on or is trying to move to,
                          // chosenchar contains the character the player chooses to play as in the intro
  onDoor, charchosen, updatestatus : boolean; {onDoor is whether the player is on a door or not, charchosen is
                                               whether the character has yet chosen a character to play as, updatestatus stores
                                               whether a player has passed a new points boundary yet}

procedure f_intro;   //This procedure runs at the beginning of the game.
var
 keyo : char;   //keyo stores the character on the keyboard that the player has pushed
 currentchar : integer;  //stores the character number the player has cycled through to during character selection
begin
  Writeln;
  Writeln; // This section writes the text you can see here as a starting screen to the command prompt.
  Writeln ('           ###  ####   ##   #####  #   #     ');
  Writeln ('          #     #  #  #  #     #    # #      ');
  Writeln ('          #     ####  ####    #      #       ');
  Writeln ('          #     # #   #  #   #       #       ');
  Writeln ('           ###  #  #  #  #  #####    #       ');
  Writeln ('                                             ');
  Writeln ('            #     #   ##   #####  ###        ');
  Writeln ('            ##   ##  #  #     #   #          ');
  Writeln ('            # # # #  ####    #    ###        ');
  Writeln ('            #  #  #  #  #   #     #          ');
  Writeln ('            #     #  #  #  #####  ###        ');
  Writeln ('                                             ');
  Writeln ('                                             ');
  Writeln ('                                             ');
  Writeln ('                 Written by James            ');
  Writeln ('                                             ');
  Writeln ('                                             ');
  Writeln ('             <press enter to continue>       ');

  readln;   //This waits until the player presses enter before continuing.
  clrscr(); //This completely clears the command prompt of all text.
  Writeln;
  Write ('Please enter your name: ');  //prompts player to enter their name
  readln(name);       //stores their name in the name variable
  writeln;
  writeln ('Welcome ' + name + '!');  //Welcomes the player
  writeln;
  writeln ('Please choose a character:');
  writeln ('(Cycle through characters with the Arrow keys. Press Space to confirm)');
  writeln;
  cursoroff;    //turns the cursor off in the command prompt, which means the flashing bar does not show where text has been entered
  gotoXY (5,9); //this puts the cursor position to the 5th column across, 9th row down, in the command prompt.
              // GotoXY(X,Y) can be thought of as going to grid co-ordinates.
  Write ('<-   +   ->');
  currentchar := 1;     //sets default character number
  chosenchar := '+';    //sets default character

  repeat  //repeats the following until the player presses the space bar
    if KeyPressed then  //If the player is pressing any keyboard key
      begin
        keyo := readkey;   //The key being pressed is stored in keyo.
        gotoXY (10,9);     //puts cursor at 10th column, 9th row
        case keyo of
         'M' : currentchar := currentchar+1;  //If the key being pressed is the Right arrow key, the character number currently being shown is increased.
         'K' : currentchar := currentchar-1;  //If the key being pressed is the Left arrow key, the character number currently being shown is decreased.
         ' ' : charchosen := True;            //If the space bar is pressed then the repeat loop is ended (please see the loop condition).
        end;
        currentchar := ((currentchar+3) mod 4)+1;  //This makes sure the current char number is only 1,2,3, or 4.
                                                   // As there are only currently 4 choices for characters this code
                                                   //makes it so that when the number increases over 4 it reverts to 1, and when it goes below 1 it goes to 4.
        case currentchar of
          1 : chosenchar := ('+');           //This case statement changes the value of currentchar to the char specified by the current char number.
          2 : chosenchar := ('!');
          3 : chosenchar := ('$');
          4 : chosenchar := ('3');
        end;
        write (chosenchar);             //This writes the new chosen character symbol on screen, over the old one.
      end;
    until charchosen = True;  //repeated until the player presses space
  gotoXY (1,12);
  writeln ('You have chosen "' + chosenchar + '" as your character.'); //tells the player which character they have selected
  writeln;
  writeln;
  Writeln ('<press enter to continue>');
  readln;
  clrscr();  //clears all text to start a new "page"

  Writeln;
  Writeln('Instructions');
  Writeln('------------');
  gotoXY(1,5);
  Writeln('Use the WASD keys for moving Up, Left, Down, and Right respectively.');
  writeln;
  writeln;
  writeln('Guide to objects:');
  writeln;
  write('   ');
  textbackground (white);  //changes the background colour of text entered to white
  write (' ');
  textbackground (black);  //reverts the text background colour to black
  writeln('   ->    This is a wall. You cannot go through it. Period.');
  writeln;
  write('   ');
  textbackground (yellow);   //changes the background colour of text entered to yellow
  write ('*');
  textbackground (black);   //reverts the text background colour to black
  writeln('   ->    This is a door. You can use it to go to another room.');
  writeln;
  write('   ');
  textbackground (yellow);   //changes the background colour of text entered to yellow
  write (' ');
  textbackground (black);  //reverts the text background colour to black
  writeln('   ->    This is an item. Walk over it to pick it up, and gain points.');
  writeln;
  gotoXY(1,18);
  writeln('Press Enter to start the game!');
  readln;
  clrscr();
end;     //the end of the input procedure

procedure f_input;   //This procedure determines what input the player enters, and acts upon it.
Var
   key : char;     //key contains the character being pushed on the keyboard
Begin
   textcolor (white);  //changes the colour of text entered to white
   textbackground (black);  //changes the background colour of text entered to black
   if KeyPressed then  //If a key is being pressed on the keyboard then do this.
    begin
      key := ReadKey;   //currently pushed key is stored in the "key" variable
      gotoXY (X,Y);     //goes to the current X and Y co-ordinate of the character
        case g[X,Y] of     //This case basically erases the character from its current position.
        'a' : write (' ');
        'b' : write (' ');
        end;
        case key of        //This case increases/decreases the X/Y values
                           // of the player based on which key is input
                           // (using standard wsad configuration)
         'w', 'W' : Y := Y - 1;
         's', 'S' : Y := Y + 1;
         'a', 'A' : X := X - 1;
         'd', 'D' : X := X + 1;
        end;
       hit := g[X,Y];     //The new tile's character code is accessed from the grid array, (using the X and Y values) and is stored is hit
       if hit = 'b' then  //If the new tile stood on is a Wall tile (character code 'b') then the X and Y
                          // values are returned to the characters old position, as wall's tiles cannot be moved into.
        begin
          case key of
          'w', 'W' : Y := Y + 1;
          's', 'S' : Y := Y - 1;
          'a', 'A' : X := X + 1;
          'd', 'D' : X := X - 1;
          end;
        end;
       if hit = 'c' then  //If the new tile stood on is an Item tile (character code 'c') then the following happens.
        begin
         g[X,Y] := 'a';   {The tile is is replaced in the grid array by an empty tile (character code 'a').
                           This is only temporary while this map is shown so the next line changes
                           it more permanently, allowing map changes to occur.}

         {The next line of code, put simply, accesses the allmaps array strings and replaces the
          'c' of the new tile with an 'a' permanently during the rest of the program.}
         allmaps[currentmap, (1+(Y-1-((Y-1)mod 4))div 4)][((Y-1)mod 4)*60+X]:='a';
         points := points + 1;   //increases the current points number by 1
         gotoXY (70,1);
         write (points);  //This goes to the points position on screen and replaces the old points number with the new points number.
         updatestatus := TRUE; //This tells the program that the points value has changed, and so a points boundary check is needed.
        end;
      if (hit = 'd') OR (hit = 'e') then  onDoor := True; //If the new tile stood on is a door tile ('character code 'd' or 'e')
                                                          // then the program is told that the player is on a door, and a map change is needed.
      gotoXY (X,Y);   // goes to the new X and Y co-ordinates
      write (chosenchar); //writes in the player's character
    end;
End; //end of the input procedure

Procedure f_floor;   //This procedure uses the grid array's character codes and turns them into a map on screen.
var
t,o:integer;   //t and o are variables used in for loops
Begin
  t := 1;
  o := 1;
  {The rest of the procedure basically cycles through each point on the first line, and "draws" a tile based on the grid's array.
  after this it then goes to the second line and "draws" all the points. This repeats until all of the 60X20 tiles are drawn.}

  for t:=1 to 20 do    //repeats until all rows up to the 20th are "drawn"
    begin
      while o < 61 do     //repeats until all columns up to the 60th are "drawn" for one row
        begin
          gotoXY (o,t);   //goes to a new position (based on the loops) in the command prompt
          if g[o,t]= 'b' then  //if the grid array says that this spot should be a wall (code 'b') then a wall is "drawn"
           begin
            highvideo();
            textcolor (black);
            textbackground (white);
            write (' ');
           end;
          if g[o,t]= 'a' then  //If the grid array says that this spot should be an empty space (code 'a') then an empty space is "drawn".
           begin
            highvideo();
            textcolor (white);
            textbackground (black);
            write (' ');
           end;
          if g[o,t]= 'c' then  //If the grid array says that this spot should be an item (code 'c') then an item is "drawn".
           begin
            highvideo();
            textcolor (white);
            textbackground (yellow);
            write (' ');
           end;
          if (g[o,t]= 'd') OR (g[o,t]= 'e') then  //If the grid array says that this spot should be a door (code 'd' or 'e') then a door is "drawn".
           begin
            textcolor (white);
            textbackground (yellow);
            write ('*');
           end;
          o := o +1;  //increases the column up to
        end;
      o := 1; //resets the column number
    end;
End; //end of the floor procedure

Procedure f_gridsetup(mapchoice:integer); {This procedure takes the current map's code strings and puts them into the grids array,
                                          mapchoice is simply which map's strings are to be inserted into the grids array. }
var
j, k:integer; //counter variables
//The following loops are designed to take each of the five map strings for the selected map, and place them into the grid array in their correct places.
//Each map string covers 4 lines of the map (20 in all).

begin
for j:=1 to 4 do      //repeats until the first 4 lines of the grid array are filled
 begin
   for k:=1 to 60 do    //repeats until the end of the line
    begin
     g[k, j] := allmaps[mapchoice,1][(j*60-60+k)];  {grid array[X,Y] is given the value in the first string. This works
                                                    in a way such that the first 60 characters of the string are for the first line,
                                                    then charcters 61 to 120 are for the second line, 121 to 180 for the third,
                                                    and 181 to 240 for the fourth.}
    end;
 end;
for j:=1 to 4 do     //repeats until the second 4 lines of the grid array are filled
 begin
   for k:=1 to 60 do
    begin
     g[k, j+4] := allmaps[mapchoice,2][(j*60-60+k)];  //the only part changed from the first loop is that grid[k,j] has become grid[k,j+4]
    end;
 end;
for j:=1 to 4 do   //repeats until the third 4 lines of the grid array are filled
 begin
  for k:=1 to 60 do
   begin
    g[k, j+8] := allmaps[mapchoice,3][(j*60-60+k)];
   end;
 end;
for j:=1 to 4 do  //repeats until the fourth 4 lines of the grid array are filled
 begin
  for k:=1 to 60 do
   begin
    g[k, j+12] := allmaps[mapchoice,4][(j*60-60+k)];
   end;
 end;
for j:=1 to 4 do  //repeats until the last 4 lines of the grid array are filled
 begin
  for k:=1 to 60 do
   begin
    g[k, j+16] := allmaps[mapchoice,5][(j*60-60+k)];
   end;
 end;
end;  //end of the gridsetup procedure

procedure f_currentstatus;  //this procedure writes a comment at the bottom of the screen based on their points total
var
  pointsrank : integer;   //points rank will be used to contain an altered points value
begin
  pointsrank := points div 46;  //divides points by 46, ignoring any remainders
  textcolor (white);   //changes text colour to white
  textbackground (black);  //changes text background coour to black
  gotoXY (3,22);
  //Next line removes any previous comment written at the bottom of the screen.
  Write('                                                                                ');

  gotoXY (3,22);
  Case pointsrank of          //Depending on how many points the player has, a different comment is written.
    0 : write('You only have that many points? For shame ' + name + ', for shame.'); //for less than 46 points
    1 : write('Oh, so you got some points. Big woop.'); //for 46 to 91 points
    2 : write('Getting better, I suppose. Keep up the good work ' + name + '!'); //for 92 to 137 points
    3 : write('Wow, so many points...'); //for 138 to 183 points
    4 : write('Sooooooo nearly there.'); //for 184 to 229 points
    5 : write('Congratulations ' + name + '! You have won!!!!!!'); //for 230 points (max points)
  end;
end; //end of the updatestatus procedure

begin   //Beginning of the program
  highvideo();
  f_intro;  //runs the intro
  {The following places the string codes for the maps into the allmaps array.
  The characters mean: 'a' = empty space; 'b' = wall; 'c' = item; 'd' = door1; 'e' = door2.
  To make these strings I used Microsoft Excel. I wrote in the letters on a grid of cells, and
   then concatenated them into strings. I then copied the concatenated strings into here.}
  allmaps[1,1]  := 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaabaaaabaaaaaaacccbaaaaaabcaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbaabcbaababbbaabcccbacabbabbbaaaaabbbbbbbbabbbbbbbbbbbbaabb';
  allmaps[1,2]  := 'bbaabcbaabababbabcccbaaabbabbbabbaabaaaaaababbbbbbbbcccbccbbbbaabcbaabababaabbbbbbbbbbabaaabaaababbbbababbbbbbbbbccbccbbbbaabbbaababaaaaaaabaaabbbababbbacabacccbabaaaaaaaaabbabccbbbbaaaababbabbbbbbbabaaabbbabaaabacababbbbabbbbbbbbbbbbabbbbb';
  allmaps[1,3]  := 'bbaaaababaaaaaaaabbbbbabbbabbbabacababbbbaaaaaaaaaaaabaaaaadbbabbaaababbbbbbaaaaaaabbbabaaabacababbbbbbbbbbbbaaaababbbbbbbabbbbbbabaccabbbbbbbaaaaababbbacababbbbbbbbbbbbbbbababaabbbbabbaaaaababbaaaaaaababbbbbaaabacababaaaaaaaabbaacbabaaaabb';
  allmaps[1,4]  := 'bbabbaaababaccabbbbbbbbbbbcbbbabacabababbbbababaabcbabbbbabbbbabbcccbababbbbbbbcbbaaabcbaaabacabaaababbababbabcbaaaababbbbabbcccbabaaaabbbbabbababcbabbbacabbbbbabbababbabbbbbaababbbbabbbbbbabbbbabbbbabbabababaaabaaaaaaaaabbabaaaaacccbaababb';
  allmaps[1,5]  := 'bbabbbbbbacccbabaababbabaaabbbabbbbbbbbbbbbabbbbbbbbababbabbbbaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaabbbbbabaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbebbbbbbb';
  allmaps[2,1]  := 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbaaaaaacacaccacaacaacccaaaaacaaaaaaacacccacccaacaaccccaaabb';
  allmaps[2,2]  := 'bbaaaaaacacacaacaacaacacaaaaacaaaaaaacacacacacaacaaacacaaabbbbaaaaaacccaccacaacaacacaaaaaacaacaacaacacacccaacaaacacaaabbbbaaaaaacacacaacaacaacacaaaaaacacacacaacacacacaacaaacacaaabbbbbbbbaacacaccaccaccacccaaaaaaacaaacaaacccacaacaccaccccaaabb';
  allmaps[2,3]  := 'daaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbabbbbaaaaaaaaaabaaabaaaaaaaaaaaabbbbabbbabbbbaaaaaaaaaaaabababbbbaaabbbbbbababbbababbbbbabbaaaaaaabbaaaaaabbbbbbbbbbabababbbbaaaaaaaababaaaaababbbaaabbbbbbbbaaaabbbbbaaaaaaaaababababb';
  allmaps[2,4]  := 'bbaaabbbbabaaabbbbbbbbbbbbbbbbbbbbbbbbbaaaaabbbbbbbababaaabbbbaaabbababbbbbaaaaaaabbaaaaaaaaaaaaaababbbbbaaaaabababababbbbaaabbabaaaaaaabbbbbabbabbbbbbbbbbbbaaabaaabaabaabababababbbbaaabbabbbbbbbbbaaabaaaabaaaaaaaababbbbbabababbbababaaababb';
  allmaps[2,5]  := 'bbaaabbabbbbbbbbbababbbbbbabbbbbbaaaaaabbababaabaababbbbbabbbbaaaaaaaaaaaaaaaabaaaaaaaaaaaaababaabaaaabaaaaaaabaaaaababbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbebbbbbbbbbb';
  allmaps[3,1]  := 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbabbbbbbbbbaaaaaaabaaaaaabaaaaaaabbbaaaaaabaaaaabbaaabaaaaabbaaaaaabbbbacccccababaababababbbbbbbabbbbbbbbbabbaabababbbaaaabbbbabb';
  allmaps[3,2]  := 'bbacccccababbbbabababaaabbbaaaaaabbababaaababaaabbbbabbbbabbbbacccccabaaabbabababaabbabbbaaabbbababababbbabaabbbbbbbbbbbbbacccccababaabaaababaabaaaababaabbababaaabaaabbabbbabaaaabbbbacccccababaaaabbbabaaaababbababbaaaababababbbbabaaaaabbabb';
  allmaps[3,3]  := 'bbacccccababbbbbbababbabbbaaaabaabbababababaaabbababababbabbbbacccccababbbaaaabaaaabbbabbbbaaababaaababbabbbbbababaababbbbacccccababbbabbbbabbabbbaaabbabbbababbbaababaaaaabababbaaebbacccccababbaabbbbbbbaaabababaaaaaabbbabbaaabbbbbbbababaabb';
  allmaps[3,4]  := 'bbacccccabaaaaabbabbabaaaaababbbbbbbbababbbbbbaaaaabababbabbbbacccccababbbabbaaaababbbbbaaaaaaaaaaaaaaaaaaaaabbbabbbbabbbbacccccabababaababbbbabbaabaabbbbbbbbbabbbbbbabbbbbababbabbbbacccccababaaaaaabaaaaaaabbaabbbabababaaabbbbaaaaaaabaaaabb';
  allmaps[3,5]  := 'bbacccccaaabbbbbbbbabbbbbbbaaaabaabababbbabbabbbbbbbbbbbbabbbbaaaaaaabaaaabaaaaabaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';
  allmaps[4,1]  := 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbabbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb';
  allmaps[4,2]  := 'bbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb';
  allmaps[4,3]  := 'bbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb';
  allmaps[4,4]  := 'bbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb';
  allmaps[4,5]  := 'bbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';

  //initialisation
  cursoroff;         //turns the cursor off, to prevent flashing while playing
  currentmap := 1;   //sets the current map to the first map
  X := 3;            //sets the starting X co-ordinate to 3
  Y:= 3;             //sets the starting Y co-ordinate to 3
  points := 0;       //sets points at 0


  {This section sets up the door array. The first number represents which room the door is in,
  the second number represents the door number (1st or 2nd), and the third number in the array
  is used to store three pieces of information about that specified door (see below)}
  doors[1,1,1] := 2;  //new map number
  doors[1,1,2] := 2;  //new x co-ordinate
  doors[1,1,3] := 9;  //new y co-ordinate
  doors[1,2,1] := 3;
  doors[1,2,2] := 53;
  doors[1,2,3] := 2;
  doors[2,1,1] := 1;  //example; this line specifies the the 2nd room's 1st door leads the player to map 1
  doors[2,1,2] := 59;
  doors[2,1,3] := 9;
  doors[2,2,1] := 4;
  doors[2,2,2] := 50;
  doors[2,2,3] := 2;
  doors[3,1,1] := 1;
  doors[3,1,2] := 53;
  doors[3,1,3] := 19; //example2; this line specifies the the 3rd room's 1st door will change the player's Y co-ordinate to 19 in the new map
  doors[3,2,1] := 4;
  doors[3,2,2] := 2;
  doors[3,2,3] := 11;
  doors[4,1,1] := 2;
  doors[4,1,2] := 50;
  doors[4,1,3] := 19;
  doors[4,2,1] := 3;
  doors[4,2,2] := 59;
  doors[4,2,3] := 11;

  //The following puts writes the words "Points: 0" in the top right of the command prompt.
  gotoXY (62,1);
  textcolor (white);
  textbackground (black);
  Write ('Points:');
  Write (' 0');

  f_gridsetup(currentmap); //calls the gridsetup procedure
  f_floor;   //calls the floor porcedure

  //initially places the character on screen
  gotoXY (X,Y);
  textcolor (white);
  textbackground (black);
  write (chosenchar);

  f_currentstatus;//primarily updates the status

  //The rest if the program is repeated until the program is closed.
  repeat
    f_input; //checks if any input is entered by running the input procedure
    if (onDoor = True) then  //if the character is on a door then do this
      begin
        case hit of
          'd' : doorhit := 1;  //If the door is a 'd' door, then the character is said to be on door1.
          'e' : doorhit := 2;  //If the door is an 'e' door, then the character is said to be on door2.
        end;
        X := doors[currentmap,doorhit,2]; //new X co-ordinate is taken from the doors array based on which door is stood on
        Y := doors[currentmap,doorhit,3]; //new Y co-ordinate is taken from the doors array based on which door is stood on
        clrscr(); //The whole screen is cleared.
        f_gridsetup(doors[currentmap,doorhit,1]); //The grid array is replaced with the new map strings.
        f_floor; //The new map is drawn based on the grid array.
        hit := 'a';  //tells the character it is on an empty space
        onDoor := False; //tells the character it is no longer on a door space
        currentmap := doors[currentmap,doorhit,1]; //currentmap is replaced with the new map number
        //redraws the Character,the word "points", and the status since the entire command prompt has been emptied
        gotoXY (X,Y);
        textcolor (white);
        textbackground (black);
        write (chosenchar);
        gotoXY (62,1);
        Write ('Points: ', points);
        f_currentstatus;
      end;

    if (updatestatus = true) then   //If the points total has changed then do this.
      begin
        f_currentstatus;        //Update the status comment.
        updatestatus := false;  //Tell the program that comment is up to date.
      end;
    delay (60); //waits for 60 milliseconds before restarting loop
  until 1=2; //goes back to the repeat until the program is closed, or if 1 ever equals 2
end.  //end of the program


Remarks

Can you think of a program like this that you could write?

Programming - a skill for life!

Seven programs including GameOfLife, PixelSort and SuperHappyFunLand by James Hall