
BEACON1 can describe a room. BEACON2 lets the player walk about the island, which means putting part one's work to use: reading the command a key at a time, splitting it, looking up each word in a table, and acting on the tokens.
Make a new work file, BEACON2. Open the editor, and read the whole of BEACON1 in with CONTROL and K, then CONTROL and R: Turbo asks Read block from file:, and you answer BEACON1. Now change it as below. Each game section starts this way from the last.
BEACON knows 55 words. They are in alphabetical order, so that S9's binary search can find any of them in six comparisons, and beside each is its token, S8's number for what it means:
| Tokens | Kind | Words |
|---|---|---|
| 1 to 6 | directions | N NORTH, S SOUTH, E EAST, W WEST, U UP, D DOWN |
| 7 to 19 | other verbs | GO, LOOK L, INVENTORY I, TAKE GET, DROP, EXAMINE X, OPEN PRISE, UNLOCK, LIGHT IGNITE, FILL, READ, QUIT Q, XYZZY |
| 20 to 31 | nouns | CROWBAR, LANTERN, OIL CAN, LOGBOOK LOG BOOK, MATCHES, KEY, DOOR, CUPBOARD, DRAWER, LAMP, BOAT, SHIP |
| 40, 41 | prepositions | WITH, IN INTO |
| 50 | noise | THE, A, AN, AT, TO |
Two things are chosen with care. A direction's token is its number in the exits: NORTH is 1 and Exits[1] is north, so moving needs no table of its own. And the token says what kind of word it is: under 20 a verb, under 40 a noun, under 50 a preposition, and 50 noise. S10 kept a separate list of kinds; here the number is enough.
Synonyms are simply two entries with the same token. A one-letter word is a synonym too, as in Alice and the March Hare.
All 55 go in now, even though most of the verbs do nothing until S19 and S20, so that the table is typed once and stays in order.
GetLine is S4's line reader, taking only letters and spaces, and up to 38 of them: DELETE works, and the player's words appear in capitals.
Find is S9's binary search, returning the token rather than the place. Its table holds Str9s, so Parse cuts each word to nine letters before looking it up.
Parse is S10's, deciding kind by the token's size.
Walk takes a direction: if the exit is 0, You can't go that way., otherwise move and Look.
Act is a case on the verb. Anything not yet written gets You can't do that yet., through the case's else.
The top of the program, before Wrap, becomes:
program Beacon;
const
Rooms = 12;
Count = 55;
type
Str255 = string[255];
Str40 = string[40];
Str16 = string[16];
Str9 = string[9];
Room = record
Name: Str16;
Exits: array[1..6] of Byte;
end;
const
Words: array[1..Count] of Str9 =
('A', 'AN', 'AT', 'BOAT', 'BOOK',
'CAN', 'CROWBAR', 'CUPBOARD', 'D',
'DOOR', 'DOWN', 'DRAWER', 'DROP',
'E', 'EAST', 'EXAMINE', 'FILL',
'GET', 'GO', 'I', 'IGNITE', 'IN',
'INTO', 'INVENTORY', 'KEY', 'L',
'LAMP', 'LANTERN', 'LIGHT', 'LOG',
'LOGBOOK', 'LOOK', 'MATCHES', 'N',
'NORTH', 'OIL', 'OPEN', 'PRISE',
'Q', 'QUIT', 'READ', 'S', 'SHIP',
'SOUTH', 'TAKE', 'THE', 'TO', 'U',
'UNLOCK', 'UP', 'W', 'WEST',
'WITH', 'X', 'XYZZY');
Token: array[1..Count] of Byte =
(50, 50, 50, 30, 23,
22, 20, 27, 6,
26, 6, 28, 11,
3, 3, 12, 16,
10, 7, 9, 15, 41,
41, 9, 25, 8,
29, 21, 15, 23,
23, 8, 24, 1,
1, 22, 13, 13,
18, 18, 17, 2, 31,
2, 10, 50, 50, 5,
14, 5, 4, 4,
40, 12, 19);
var
Map: array[1..Rooms] of Room;
Msg: file of Str255;
Here, V, N1, P, N2: Integer;
Quit: Boolean;
Line: Str40;
Wrap, Say, Load and Look stay as they were. After Load, add:
procedure GetLine(var S: Str40);
var
Ch: Char;
begin
S := '';
repeat
Read(Kbd, Ch);
Ch := UpCase(Ch);
if (Ch in [#8, #25])
and (Length(S) > 0) then
begin
Write(#8, ' ', #8);
S[0] := Pred(S[0]);
end
else if (Ch in [' ', 'A'..'Z'])
and (Length(S) < 38) then
begin
Write(Ch);
S := S + Ch;
end;
until Ch = #13;
Writeln;
end;
function Find(W: Str9): Integer;
var
Lo, Hi, Mid, Found: Integer;
begin
Found := 0;
Lo := 1;
Hi := Count;
while (Found = 0) and (Lo <= Hi) do
begin
Mid := (Lo + Hi) div 2;
if Words[Mid] = W then
Found := Token[Mid]
else if Words[Mid] < W then
Lo := Mid + 1
else
Hi := Mid - 1;
end;
Find := Found;
end;
function Parse(S: Str40): Boolean;
var
W: Str40;
K, Pl: Integer;
Ok: Boolean;
begin
V := 0; N1 := 0; P := 0; N2 := 0;
Ok := True;
S := S + ' ';
while Ok and (S <> '') do
begin
Pl := Pos(' ', S);
W := Copy(S, 1, Pl - 1);
Delete(S, 1, Pl);
if W <> '' then
begin
K := Find(Copy(W, 1, 9));
if K = 0 then
begin
Writeln('I don''t know the word ',
W, '.');
Ok := False;
end
else if K < 20 then
V := K
else if K < 40 then
begin
if P = 0 then
N1 := K
else
N2 := K;
end
else if K < 50 then
P := K;
end;
end;
Parse := Ok;
end;
After Look, add:
procedure Walk(D: Integer);
var
Dest: Integer;
begin
Dest := Map[Here].Exits[D];
if Dest = 0 then
Writeln('You can''t go that way.')
else
begin
Here := Dest;
Look;
end;
end;
procedure Act;
begin
case V of
1..6: Walk(V);
7: if (N1 > 0) or (P > 0) then
Writeln('Which way?')
else
Writeln('Go where?');
8: Look;
18: Quit := True;
else
Writeln('You can''t do that yet.');
end;
end;
And the main program becomes:
begin
Load;
Here := 1;
Quit := False;
Writeln('BEACON');
Look;
repeat
Write('> ');
GetLine(Line);
if Parse(Line) then
if V = 0 then
Writeln('There is no verb in that.')
else
Act;
until Quit;
Close(Msg);
end.
Starting from
BEACON1, read into a new work file BEACON2 as above. Save before you run.
What you should see
The beach, and a >. N takes you to the cliff path, W to the keeper's front room, L looks again. GO NORTH works, because NORTH is the verb that counts; GO alone asks Go where?. TAKE LAMP gets You can't do that yet., FROB gets I don't know the word FROB., and Q ends the game.
Walk, take out the Look; after Here := Dest;. Walk north, then type L. Where are you?Act, change 1..6: to 1..4:. What do U and D do now?Wrap, change both 40s to 30.18.1 When there is no way in the direction asked, list the ways there are: You can go: WEST. (The words for the directions are in the table: NORTH is Words[35].)
18.2 Count the commands typed, and print the count after Q.
18.3 Print each room's name in capitals.
Worked solutions are in Appendix II.
| Symptom | Cause |
|---|---|
Error 5: ')' expected in the table | More words than Count says, or fewer. |
BEACON2 reads a command a key at a time, splits it with Pos, finds each word by binary search in a sorted table of 55, and works out verb, noun, preposition and noun from the tokens' sizes. A direction's token is its exit number, so moving is one line.
S19, Things: six things to find, carry and drop.
This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.