{
G—Pascal author Nick Gammon
presents a ‘skeleton’ adventure
for our Pascal programmers to
develop. its a fun game on its
own, and illustrates how easy it
can be to produce such a seem-
ingly complex program using this
language. You can play it as is,
modify it fairly easily for most Pas-
cals, and turn it into a massive
adventure saga...

Fortunately  Pascal turns out to be a very good
adventure—game medium, as this article
illustrates.

Why Pascal?

Pascal makes the job easy because: Its
long data names make the program self-
documenting; the CASE statement is very
useful for decision-making; and its strong
structure makes it easy to debug and
enhance.

for more detailed description of the game, see

http://www.gammon.com.au/GPascal/GPascal%20Adventure.pdf

}

(* ADVENTURE—STYLE GAME  AUTHOR: NICK CANNON *)
(* ported to standard pascal by Trevor Blight *)

program adventure(input, output);

const

  INHAND = -1;
  MAXWORDS=2;
  MAXCARRY=3;
  CARRIED=1;
  NOTCARRIED=2;
  NEARBY=3;

  maxLine = 100;
  nrRooms = 21;

type
   objectType = (NOOBJ, LAMP, BUN, ROD, RING, STATUE, CROWN);
  lineIndex  =  1..maxLine;
  wordIndex = 1..maxwords;

VAR

  {word values}
  WORD: ARRAY [WORDINDEX] OF (allw, lampw, bunw, rodw, ringw, statuew, crownw,
                              movew,
                              scorew, quitw,
                              eatw, northw, southw, eastw, westw, neastw, nwestw,
                              seastw, swestw, upw, downw, enterw, leavew, takew,
                              dropw, inventoryw, lookw, wavew, inspectw,
                              nothingw);

  STARTWORD, ENDWORD:  ARRAY [WORDINDEX] OF lineIndex;
  LINE :ARRAY [lineIndex] OF CHAR;
  PTR : lineIndex;


  {room where the object is, -1 = inhand, 0 => noobject}
  OBJECT:  ARRAY [lamp .. crown] OF -1..nrRooms;

  HOLDING:  0..MAXCARRY;    {nr objects carried}
  SCORE, TURNS: INTEGER;

  OBJ:objectType;

  ROOM, OLDROOM : 0..nrRooms; {0 = no room/end of game}

FUNCTION CARRYING (x: objectType) : boolean;
BEGIN
  CARRYING := OBJECT[x] = INHAND
END; { CARRYING }


FUNCTION INROOM (x: objectType): boolean;
BEGIN
  INROOM := object[x] = ROOM
END; { INROOM }


{line 50}
FUNCTION HERE (x :objectType ): boolean;
BEGIN
  HERE := CARRYING (x) OR INROOM (x)
END; { HERE }


FUNCTION SAYWORD (x: wordIndex): char;
VAR I : lineIndex;
BEGIN
 FOR I := STARTWORD[X] TO ENDWORD[X] - 1 DO
    WRITE (LINE[I]);
 SAYWORD := chr(0)
END; { SAYWORD }


{line 63}
FUNCTION CONVERTOBJECT: objectType;
BEGIN
  OBJ := NOOBJ;
  IF WORD[2] = nothingw THEN
    WRITELN (SAYWORD(1),' WHAT?')
  ELSE if word[2] in [lampw .. crownw] then
    CASE WORD[2] OF
      lampw   : OBJ := LAMP;
      bunw    : OBJ := BUN;
      rodw    : OBJ := ROD;
      ringw   : OBJ := RING;
      statuew : OBJ := STATUE;
      crownw  : OBJ := CROWN
    END; {case}

 CONVERTOBJECT := OBJ
END; { CONVERTOBJECT }


FUNCTION DESCRIBEOBJECT (x: objectType): char;
BEGIN
  CASE x OF
    LAMP:   WRITE ('LAMP');
    BUN:    WRITE ('CREAM BUN');
    ROD:    WRITE ('ROD');
    RING:   WRITE ('GOLD RING');
    STATUE: WRITE ('SILVER STATUE');
    CROWN:  WRITE ('JEWELLED CROWN')
  END;
  DESCRIBEOBJECT := chr(0)
END; { DESCRIBEOBJECT }


{line 94}
FUNCTION GETOBJECT (MUSTBE :integer ): boolean;

BEGIN
  GETOBJECT := FALSE;
  IF CONVERTOBJECT <> noobj THEN BEGIN
    if MUSTBE =  CARRIED then begin
      IF CARRYING(OBJ) THEN
        GETOBJECT := TRUE
      ELSE
        WRITELN('YOU’RE NOT CARRYING IT!');
    end
    else IF NOT HERE(OBJ) THEN
       WRITELN ('I SEE NO ', SAYWORD(2), ' HERE.')
    ELSE if mustbe =  NOTCARRIED then begin
      IF NOT CARRYING(OBJ) THEN
        GETOBJECT := TRUE
      ELSE
        WRITELN ('YOU''RE ALREADY CARRYING IT!')
    end
    ELSE
      GETOBJECT := TRUE
  END
END; { GETOBJECT }


PROCEDURE PICKUP (x: objectType);
BEGIN
  IF HOLDING >= MAXCARRY THEN
    WRITELN ('YOU CAN''T CARRY ANY MORE!')
  ELSE BEGIN
    HOLDING := HOLDING + 1;
    OBJECT[X] := INHAND;
    WRITELN ('TAKEN.')
  END
END; { PICKUP }


{line 113}
PROCEDURE DROPIT (x: objectType);
BEGIN
  HOLDING := HOLDING - 1;
  OBJECT[X] := ROOM;
  WRITELN ('DROPPED.');
  IF ROOM = 1 THEN
    IF (INROOM(RING))
      AND(INROOM(STATUE))
      AND(INROOM(CROWN))
    THEN
      ROOM := 0; (* FINISHED QUEST! *)
END; { DROPIT }


PROCEDURE DESTROY (x: objectType);

BEGIN
  IF CARRYING(X) THEN
    HOLDING := HOLDING - 1;
  OBJECT[X] := 0
END; { DESTROY }


PROCEDURE OK;
BEGIN
  WRITELN; WRITELN; writeln('OK')
END; { OK }


PROCEDURE TAKE;
VAR I : objectType;
BEGIN
  IF WORD[2] = allw THEN BEGIN
    FOR I := LAMP TO CROWN DO
      IF INROOM(I) THEN BEGIN
        WRITE (DESCRIBEOBJECT(I),': ');
        PICKUP(I)
      END
      ELSE BEGIN END
  END
  ELSE
    IF GETOBJECT (NOTCARRIED) THEN
      PICKUP (OBJ)
END; { TAKE }


PROCEDURE DROP;
VAR I: objectType;
BEGIN
  IF WORD[2] = allw THEN
    FOR I := LAMP To CROWN DO
      IF CARRYING(I) THEN BEGIN
        WRITE (DESCRIBEOBJECT(I),': ');
        DROPIT(I)
      END ELSE
  ELSE
    IF GETOBJECT (CARRIED) THEN
      DROPIT (OBJ)
END; { DROP }


PROCEDURE INSPECT;

BEGIN
  IF GETOBJECT (NEARBY) THEN BEGIN
    if OBJ in [ROD, RING, STATUE] then
        WRITELN ('MAGIC SEEMS TO EMANATE FROM THE ', SAYWORD(2), ' ...' )
    else if obj = BUN then
      WRITE ('IT LOOKS TASTY!')
    ELSE
      WRITELN ('YOU SEE NOTHING SPECIAL')
  END
END; { INSPECT }


{line 200}
PROCEDURE LOOK;
BEGIN
  IF WORD[2] = nothingw then
    OLDROOM := 0
  ELSE
    INSPECT
END; { LOOK }


PROCEDURE CRAZY;
BEGIN
  CASE TURNS MOD 4 OF
    0 : WRITELN ('DON''T BE RIDICULOUS!');
    1 : WRITELN ('NICE TRY.');
    2 : WRITELN ('I WOULDN''T!');
    3 : WRITELN ('THAT''S A *VERY* SILLY IDEA!')
  END
END; { CRAZY }


PROCEDURE DONTUNDERSTAND;
BEGIN
  CASE TURNS MOD 4 OF
    0 : WRITELN ('WHAT?');
    1 : WRITELN ('PARDON?');
    2 : WRITELN ('I DON''T UNDERSTAND THAT!');
    3 : WRITELN ('EH?')
  END
END; { DONTUNDERSTAND }


{line 228}
PROCEDURE GETWORD (x: wordIndex);
VAR
  I    : lineIndex;
  c    : char;
  inwd : packed array[1..3] of char;
BEGIN
  inwd := '   ';
  I := 1;
  WHILE LINE[PTR] = ' ' DO
    PTR := PTR + 1;
  STARTWORD[X] := PTR;
  WHILE (LINE[PTR] <> chr(0)) AND (LINE[PTR] <> ' ') DO BEGIN
    c := line[ptr];
    if c in ['a'..'z'] then
      c := chr(ord(c) + ord('A') - ord('a')); {convert to upper case}
    IF i <= 3 THEN begin
      inwd[i] := c;
      I := I + 1;
    end;
    PTR := PTR + 1
  END; {while}

  if inwd = 'LAM' then word[x] := lampw
  else if (inwd = 'BUN') or (inwd = 'CRE') then word[x] := bunw
  else if inwd = 'ROD'   then word[x] := rodw
  else if (inwd = 'RIN') or (inwd = 'GOL') then word[x] := ringw
  else if (inwd = 'SIL') or (inwd = 'STA') then word[x] := statuew
  else if (inwd = 'JEW') or (inwd = 'CRO') then word[x] := crownw
  else if  inwd = 'ALL'  then word[x] := allw
  else if (inwd = 'GO ') or (inwd = 'RUN') or (inwd = 'WAL') or
          (inwd = 'MOV') or (inwd = 'CRA') then word[x] := movew
  else if (inwd = 'QUI') or (inwd = 'Q  ') then word[x] := quitw
  else if (inwd = 'EAT')  then word[x] := eatw
  else if (inwd = 'NOR') or (inwd = 'N  ')  then word[x] := northw
  else if (inwd = 'SOU') or (inwd = 'S  ')  then word[x] := southw
  else if (inwd = 'EAS') or (inwd = 'E  ')  then word[x] := eastw
  else if (inwd = 'WES') or (inwd = 'W  ')  then word[x] := westw
  else if (inwd = 'NE ')  then word[x] := neastw
  else if (inwd = 'NW ')  then word[x] := nwestw
  else if (inwd = 'SE ')  then word[x] := seastw
  else if (inwd = 'SW ')  then word[x] := swestw
  else if (inwd = 'UP ') or (inwd = 'U  ')  then word[x] := upw
  else if (inwd = 'DOW') or (inwd = 'D  ')  then word[x] := downw
  else if (inwd = 'ENT') or (inwd = 'IN ') then word[x] := enterw
  else if (inwd = 'LEA') or (inwd = 'OUT') then word[x] := leavew
  else if (inwd = 'TAK') or (inwd = 'T  ') or
          (inwd = 'GET') or (inwd = 'PIC')  then word[x] := takew
  else if (inwd = 'DRO') or (inwd = 'PUT') or
          (inwd = 'PLA') or (inwd = 'THR')  then word[x] := dropw
  else if (inwd = 'SCO')  then word[x] := scorew
  else if (inwd = 'INV') or (inwd = 'I  ')  then word[x] := inventoryw
  else if (inwd = 'LOO') or (inwd = 'L  ')  then word[x] := lookw
  else if (inwd = 'WAV')  then word[x] := wavew
  else if (inwd = 'INS')  then word[x] := inspectw
  else word[x] := nothingw;

  ENDWORD[X] := PTR
END; { GETWORD }


{line 247}
PROCEDURE GETLINE;

VAR
  I : lineIndex;
  n : wordIndex;
BEGIN
  REPEAT
    WRITELN; write('> ');
    i := 1;
    while not eoln and (i < maxLine) do begin
      READ(LINE[i]);
      i := i+1;
    end; {while}
    readln;
    LINE[i] := CHR(0);
    PTR := 1;
    FOR n := 1 TO MAXWORDS DO
      GETWORD (n);

    WHILE LINE[PTR] = ' ' DO
      PTR := PTR + 1;
    IF LINE[PTR] <> CHR(0) THEN BEGIN
      WORD[1] := nothingw;
      WRITELN;
      WRITE('PLEASE USE NO MORE THAN ', MAXWORDS, ' WORDS');
      WRITELN;
      WRITELN;
    END
    else if word[1] = nothingw then
      dontunderstand;
  UNTIL WORD[1] <> nothingw
END; { GETLINE }


PROCEDURE INSTRUCTIONS;
BEGIN
  WRITELN ('YOUR QUEST IS TO EXPLORE THE CAVE OF THE EVIL UR—LORD, AND');
  WRITELN( 'BRING BACK TO THE EDGE OF THE CLIFF THE FOLLOWING VALUABLES:');
  WRITELN; WRITELN;
  WRITELN(' 1. THE WHITE GOLD RING;');
  WRITELN(' 2. THE SACRED SILVER STATUE;');
  WRITELN(' 3. THE JEWELLED CROWN OF THE UR—LORD.');
  WRITELN; WRITELN;
  WRITELN('BE CAREFUL ....');
  WRITELN; WRITELN;
END; { INSTRUCTIONS }


PROCEDURE DESCRIBEROOM;

VAR I: objectType;
BEGIN

  IF (ROOM > 4) AND (NOT HERE(LAMP)) THEN
    WRITELN ('IT''S TOO DARK TO SEE!')
  ELSE BEGIN
    WRITE ('YOU ARE ');
    CASE ROOM OF
      1:    WRITELN ('AT A PLATEAU NEAR A CLIFF. A ROCKY PATH LEADS SOUTH.');

      2:    WRITELN ('ON A ROCKY PATH LEADING NORTH AND CURVING TO THE EAST. THERE IS A SLIGHT BREEZE.');

      3:    WRITELN ('AT THE ENTRANCE TO A DARK CAVE. A ROCKY PATH TO THE WEST CURVES NORTH.');

      4:    WRITELN ('JUST INSIDE A DARK CAVE. LIGHT COMES FROM AN ENTRANCE TO THE WEST. THERE IS A DANK, MOULDY SMELL. A TUNNEL LEADS SOUTH.');

      5:    WRITELN ('IN A LOW NORTH/SOUTH TUNNEL.');
      6:    WRITELN ('IN AN OVAL CAVERN WITH AN EXIT To THE NORTH. THERE IS A FORBIDDING STONE STAIRCASE LEADING DOWN.');

      7:    WRITELN ('IN A HIGH, SQUARE CAVE WITH WALLS OF FROZEN ICE. THERE ARE PASSAGES IN MANY DIRECTIONS, AND A STAIRWAY LEADING UP.');

      8:    WRITELN ('IN A TRIANGULAR SIDE—CHAMBER.');
      9:    WRITELN ('IN A MUSTY—SMELLING ALCOVE.');
      10:   WRITELN ('IN A EERIE CHAMBER - SMALL SQUEALING SOUNDS COME FROM THE WALLS.');

      11:   WRITELN ('PASSING THROUGH AN ENORMOUS CAVE WITH A DOUBLE PILLAR OF GREEN STONE DOWN THE CENTRE. A BIG ARCH LEADS NORTH AND DANK TUNNELS LEADS FROM THE SOUTHEAST AND SOUTHWEST CORNERS.');

      12:   WRITELN ('CROUCHED IN A MALODOUROUS TUNNEL. THE ONLY EXIT IS THE WAY YOU CAME.');

      13:   BEGIN
              WRITELN ('A ROOM WHICH APPEARS TO ONLY HAVE AN EXIT IN THE NORTHWEST CORNER.');
              writeln('HOWEVER YOU GET THE IMPRESSION THAT OTHERS HAVE SOMEHOW TRAVELLED ONWARDS');
              writeln('THROUGH THIS ROOM - THE EXACT METHOD THEY USED IS NOT APPARENT.');
            end;

      14:   WRITELN ('A SECRET ROOM REACHED ONLY BY MAGIC MEANS. A HIGH PASSAGE EXITS TO THE NORTHEAST.');

      15:   WRITELN ('A DEPRESSING OCTAGONAL ROOM. EERIE PASSAGES LEAD NORTH AND SOUTHWEST.');

      16:   WRITELN ('AN ENORMOUS MISTY CAVERN — THE ROOF IS SO HIGH THAT MIST OBSCURES IT. PASSAGES LEAD NORTH AND SOUTH.');
      17:   WRITELN ('A TINY BOX-SHAPED ROOM. A DOOR LEADS SOUTH AND STAIRS LEAD DOWN.');

      18:   WRITELN ('A BIZZARE ROOM WITH A SMELL OF CHLORINE. A PATH LEADS NORTH AND STAIRS LEAD UP.');

      19:   WRITELN ('A STEAMY CHAMBER WITH WARM WALLS. FOOTSTEPS IN THE DUST SEEM TO LEAD WEST AND COME FROM THE SOUTH.');
      20:   WRITELN ('A LARGE ROOM, LITTERED WITH ALABASTER SLABS. DOORS LEAD EAST AND WEST.');
      21:   WRITELN ('THE THRONE ROOM OF THE EVIL UR—LORD! A LOW DOOR LEADS EAST.')
    END; { case }

    FOR I := LAMP TO CROWN Do
      IF INROOM(I) THEN begin
        WRITELN;
        writeln ('THERE IS A ', DESCRIBEOBJECT(I), ' HERE!')
      end;
  END;
  OLDROOM := ROOM
END; { DESCRIBEROOM }


PROCEDURE EAT;

BEGIN
  IF GETOBJECT(NEARBY) THEN BEGIN
    IF OBJ = BUN THEN BEGIN
      WRITELN ('THANKS! YOU WERE RATHER HUNGRY!');
      DESTROY(BUN)
    END
    ELSE
      CRAZY
  END
END; { EAT }


PROCEDURE FORCE;
BEGIN
  WRITELN ('AN INVISIBLE FORCE PREVENTS YOU FROM PASSING.')
END; { FORCE }


PROCEDURE NOWAY;
BEGIN
  WRITELN ('YOU CANNOT GO THAT WAY.')
END; { NOWAY }


PROCEDURE NORTH;
BEGIN
  if room in [1,2,5,6,7,11,15,16,18] then
    CASE ROOM OF
      1  : CRAZY;
      2  : ROOM := 1;
      5  : ROOM := 4;
      6  : ROOM := 5;
      7  : ROOM := 9;
      11 : ROOM := 7;
      15 : ROOM := 16;
      16 : IF CARRYING(RING) THEN
             FORCE
           ELSE
             ROOM := 17;
      18 : IF CARRYING(STATUE) THEN
             ROOM := 19
           ELSE FORCE
    END {case}
    else NOWAY
END; { NORTH }


{line 477}
PROCEDURE SOUTH;
BEGIN
  if room in [1,4,5,9,7,16,17,19] then
    CASE ROOM OF
      1  : ROOM := 2;
      4  : ROOM := 5;
      5  : ROOM := 6;
      9  : ROOM := 7;
      7  : ROOM := 11;
      16 : ROOM := 15;
      17 : ROOM := 16;
      19 : IF CARRYING(STATUE) THEN
             ROOM := 18
           ELSE
             FORCE
    END {case}
  ELSE NOWAY
END; {south}


PROCEDURE EAST;
BEGIN
  if room in [2,3,7,8,20,21] then
    CASE ROOM OF
      2  : ROOM := 3;
      3  : ROOM := 4;
      7  : room := 10;
      8  : room := 7;
      20 : room := 19;
      21 : ROOM := 20;
    END {case}
  ELSE NOWAY
END; {east}


PROCEDURE WEST;
BEGIN
  if room in [1,3,4,10,7,19,20] then
    CASE ROOM OF
      1  : CRAZY;
      3  : ROOM := 2;
      4  : ROOM := 3;
      10 : ROOM := 7;
      7  : ROOM := 8;
      19 : ROOM := 20;
      20 : ROOM := 21;
    END {case}
  ELSE NOWAY
END; {west}


PROCEDURE UP;
BEGIN
  if room in [7,18] then
    CASE ROOM OF
      7  : ROOM := 6;
      18 : ROOM := 17
    END {case}
    ELSE NOWAY
END; {up}


PROCEDURE DOWN;
BEGIN
  if room in [6,17] then
    CASE ROOM OF
      6 : ROOM := 7;
      17 : ROOM := 18
    END {case}
  ELSE NOWAY
END; {down}


PROCEDURE NORTHEAST;
BEGIN
  if room in [12,14] then
    CASE ROOM OF
      12 : ROOM := 11;
      14 : ROOM := 15
    END {case}
  ELSE NOWAY
END; {northeast}


PROCEDURE NORTHWEST;
BEGIN
  if room in [13] then
    CASE ROOM OF
      13:ROOM := 11
    END {case}
  ELSE NOWAY
END; {northwest}


PROCEDURE SOUTHEAST;
BEGIN
  if room in [11] then
    CASE ROOM OF
      11 : ROOM := 13
    END {CASE}
  else  NOWAY
END; {southeast}


PROCEDURE SOUTHWEST;
BEGIN
  if room in [11,15] then
    CASE ROOM OF
      11 : ROOM := 12;
      15 : ROOM := 14
    END {CASE}
  else NOWAY
END; {southwest}


PROCEDURE enter;
BEGIN
  if room in [3] then
    CASE ROOM OF
      3 : ROOM := 4
    END {CASE}
  else NOWAY
END; {enter}


PROCEDURE leave;
BEGIN
  if room in [4] then
    CASE ROOM OF
      4 : ROOM := 3
    END {CASE}
  else NOWAY
END; {leave}


PROCEDURE WAVE;
BEGIN
  IF GETOBJECT(CARRIED) THEN BEGIN
    IF OBJ = ROD THEN BEGIN
      if room in [13,14] then
        CASE ROOM OF
          13 : ROOM := 14;
          14 : ROOM := 13
        END {case}
        else
          WRITELN ('NOTHTNG HAPPENS HERE.')
    END
    ELSE
      WRITELN ('WAVING THE ',SAYWORD(2),
               ' IS NOT VERY REWARDING!');
  END;
  IF ROOM <> OLDROOM THEN begin
    WRITELN('THERE IS A BLINDING FLASH OF LIGHT A LOUD BURPING NOISE,');
    WRITELN('AND YOU SUDDENLY FIND ...');
    writeln; writeln;
  end;
end; {wave}


PROCEDURE GIVESCORE;
BEGIN
  SCORE := 0;
  IF OBJECT[STATUE] = 1 THEN
    SCORE := SCORE + 100;
  IF OBJECT[RING] = 1 THEN
    SCORE := SCORE + 100;
  IF OBJECT[CROWN] = 1 THEN
    SCORE := SCORE + 100;
  IF CARRYING(STATUE) THEN
    SCORE := SCORE + 100;
  IF CARRYING(RING) THEN
    SCORE := SCORE + 10;
  IF CARRYING(CROWN) THEN
    SCORE := SCORE + 10;
  WRITELN;
  WRITELN ('YOUR SCORE IS ', SCORE, ' POINTS, IN ',
           TURNS, ' TURNS')
END; { GIVESCORE }


PROCEDURE QUIT;
VAR REPLY: CHAR;
BEGIN
  GIVESCORE;
  writeln;
  WRITE ('DO YOU WANT TO QUIT NOW? Y/N ');
  READLN (REPLY);
  If REPLY in ['Y','y'] THEN
    ROOM := 0
  ELSE
    OK
END; { QUIT }


{line 632}
PROCEDURE INVENTORY;
VAR
  COUNT : INTEGER;
  I : objectType;
BEGIN
  COUNT := 0;
  FOR I := LAMP TO CROWN DO
    IF CARRYING(I) THEN BEGIN
      IF COUNT = 0 THEN
        WRITELN ('YOU ARE CARRYING ');
      COUNT := COUNT + 1;
      WRITELN ('  ', DESCRIBEOBJECT(I))
    END;
  IF COUNT = 0 THEN
    WRITELN ('YOU AREN''T CARRYING ANYTHING!')
END; { INVENTORY }


{line 648}
PROCEDURE VERB;
VAR I : 0..maxwords;
BEGIN
  WRITELN;
  i := 1;
  if WORD[1] =  movew then begin
    IF WORD[2] = nothingw THEN begin
      WRITELN (SAYWORD(1),' WHERE?');
      i :=  0
    END
    ELSE
      i := 2
  END; {if}
  IF I <> 0 THEN
    if word[i] in [scorew .. inspectw] then
      CASE WORD[I] OF
        scorew : GIVESCORE;
        quitw  : QUIT;
        eatw   : EAT;
        northw : NORTH;
        southw : SOUTH;
        eastw  : EAST;
        westw  : WEST;
        neastw : NORTHEAST;
        nwestw : NORTHWEST;
        seastw : SOUTHEAST;
        swestw : SOUTHWEST;
        upw    : UP;
        downw  : DOWN;
        enterw : enter;
        leavew : leave;
        takew  : TAKE;
        dropw  : DROP;
        inventoryw : INVENTORY;
        lookw  : LOOK;
        wavew  : WAVE;
        inspectw : INSPECT
      END {case}
    else DONTUNDERSTAND
END; {verb}


PROCEDURE INITIALISE;
VAR I : objectType;
BEGIN
  page;
  ROOM := 3;
  OLDROOM := 0;
  SCORE := 0;
  HOLDING := 0;
  TURNS := 0;
  FOR I := LAMP To CROWN DO
    OBJECT[I] := 0;
  OBJECT[LAMP] := 1;
  OBJECT[BUN] := 6;
  OBJECT[ROD] := 9;
  OBJECT[RING] :=8;
  OBJECT[STATUE] := 12;
  OBJECT[CROWN] := 21;
END; { INITIALISE }


(* ______________________________
      PROGRAM STARTS HERE
 ______________________________ *)

BEGIN
  INITIALISE;
  INSTRUCTIONS;
  REPEAT
    TURNS := TURNS + 1;
    IF ROOM <> OLDROOM THEN
      DESCRIBEROOM;
    GETLINE;
    VERB
  UNTIL ROOM = 0;
  page;
  GIVESCORE;
  IF SCORE = 300 THEN begin
    writeln; writeln;
    writeln('CONGRATULATIONS!!');
    writeln;writeln;
    writeln('YOU HAVE COMPLETED YOUR QUEST!');
    writeln; writeln;
  END;
END.


{
Local Variables:
   pascal-indent-level: 2
End:
}
