home *** CD-ROM | disk | FTP | other *** search
- {*
- * Program Title: Wumpus
- * Written by: Gregory Yob
- * More BASIC Computer Games
- * Edited by David H. Ahl
- *
- * Translated into Pascal by Paul H. Gilliam from the
- * BASIC programs 'WUMPUS 1' and 'WUMPUS 2'
- *
- * This game will teach you how to play it.
- * Happy wumpus hunting!
- *
- * 29 June 1980 -corrected minor logic bugs.
- * 29 June 1980 -Modified for Pascal/Z v3.0
- * Pascal/Z does not allow jumps out
- * of Procedures/Functions [A practice
- * I fully agree with!]
- * Donated July, 1980
- *}
- Program Wumpus;
- LABEL 99; { Fatal error }
- CONST
- default = 80;
- {--- define your screen parameters ---}
- s_beglin = 1; { first line } (* ADM-3A Screen parameters *)
- s_endlin = 23; { last line }
- s_begcol = 1; { first column }
- s_endcol = 80; { last column }
-
- TYPE
- alfa = STRING 10; { just the right size }
- Dstring = STRING default;
- str0 = STRING 0;
- str255 = STRING 255;
- room = 1 .. 20;
- tunnel = 1 .. 3;
-
- VAR
- arrowcount : integer;
- bell : char;
- cave : array[room, tunnel] of room;
- cursorhome, { cursor controls }
- cursorup,
- cursordown,
- cursorleft,
- cursorright,
- clearscreen,
- escape : char;
- fatal_error : boolean;
- i, j : integer; { global indexers }
- initlocate : array[1..6] of room;
-
- Procedure KEYIN(VAR cix: char); external;
- (*---Direct Keyboard input of a single char---*)
-
- Function RANDOM(limit: integer): real; external;
- (*---returns a real number from 0.0 to limit---*)
-
- Function length(x: str255): integer; external;
-
- Procedure gotoxy( col, row : integer );
- (* X-coord, Y-coord *)
- begin
- WRITE( chr(27), '=', chr(row+32), chr(col+32))
- end;
-
- Procedure terminit;
- begin
- bell := chr(7);
- escape := chr(27);
- cursorhome := chr(30);
- cursorup := chr(11);;
- cursordown := chr(10);
- cursorleft := chr(8);
- cursorright := chr(12);
- clearscreen := chr(26); { ASCII control-Z }
- end{of terminit};
-
- Procedure CLEAR;
- begin
- Write(clearscreen);
- end;
-
- Procedure clearline( row: integer );
- begin
- gotoxy( s_begcol, row);
- WRITE( ' ':(s_endcol-s_begcol+1) );
- gotoxy( s_begcol, row);
- end;
-
- Function randroom : room; { 1..20 }
- begin
- randroom := trunc(random(20)) + 1
- end { randroom };
-
- Function randtunnel : tunnel; { 1..3 }
- begin
- randtunnel := trunc(random(3)) + 1
- end { randtunnel };
-
- Function wumpmove : integer;
- var i : integer;
- begin
- i := trunc(random(4)) + 1;
- If i > 3 then
- wumpmove := -1
- Else
- wumpmove := i;
- end { wumpmove };
-
- Function QUIRY(sign: Dstring): boolean;
- var ch: char;
- begin
- writeln;
- Repeat
- write(sign);
- KEYIN(ch);writeln(ch);
- writeln;
- Until ch IN ['Y', 'y', 'N', 'n'];
- QUIRY := ch in ['n', 'N'];
- end;
-
- Procedure Instruct;
- {*
- * Attempts to read in an external file to instruct the player
- * as to how to play the game.
- * Instruct will pause for console input whenever it finds the
- * string "$pause" in the first position of a line in the line.
- *}
- var line : Dstring;
- Ifile : text;
- ch : char;
-
- Procedure ShowInstructions;
- begin
- CLEAR;
- Readln(Ifile,line);
- while not eof(Ifile) do
- begin
- If (line = '$pause') or (line = '$PAUSE') then
- begin
- Clearline(s_endlin);
- write('Press <sp> to continue.');KEYIN(ch);
- CLEAR;
- end
- Else
- writeln(line);
- readln(Ifile,line);
- end;{ While }
- End{ShowInstructions};
-
- begin { instruct }
- CLEAR;
- write('Do you want instructions on how to play? ');
- KEYIN(ch);Writeln(ch);
- writeln;
- If (ch='y') or (ch='Y') then
- begin
- RESET('WUMPUS.DOC',Ifile);
- If not EOF(Ifile) then
- ShowInstructions
- Else
- begin
- writeln;
- writeln('Sorry, instructions not availiable yet.');
- end;
- end
- End{of instruct};
-
- Procedure getacave;
- LABEL 9;{ABORT}
- var
- i : room; { 1..20 }
- j : tunnel; { 1..3 }
- k : integer;
- CAVENAME : STRING 5;
- LINE : Dstring;
- cavein : text;
- ch : char;
- begin
- cavename := 'CAVE ';
- Repeat
- Writeln;
- write(bell, 'Enter cave #(0-5) ');
- KEYIN(ch);Writeln(ch);
- Until ch in ['0'..'5'];
- cavename[5] := ch;
- (* OPEN file "cavename" for Read assign cavein *)
- RESET(cavename,cavein);
- fatal_error := EOF(cavein);
- If fatal_error then {ABORT}
- begin
- writeln;
- writeln('Fatal error - file not found');
- {ABORT}goto 9;
- end;
- writeln('reading ',cavename);
- readln(cavein, line);
- for i := 1 to 20 do
- for j := 1 to 3 do read(cavein,cave[i,j]);
- writeln;
- writeln('You are in ',line);
- writeln;
- 9:{ABORT}
- End{ of getacave }{ CLOSE(cavein) };
-
- Procedure initsetup;
- var locatesunique : boolean;
- i, j : integer;
- begin
- Repeat
- for i := 1 to 6 do initlocate[i] := randroom;
- locatesunique := true;
- i := 1;
- while locatesunique and (i <= 6) do
- begin
- j := 1;
- while locatesunique and (j <= 6) do
- begin
- If (initlocate[i] = initlocate[j]) and (j <> i) then
- locatesunique := false
- Else
- j := j + 1;
- end;
- i := i + 1
- end
- Until locatesunique
- End { initsetup };
-
- Procedure HuntTheWumpus;
- CONST Title = 'Hunt the Wumpus';
- TYPE long = real;
- VAR i : integer;
- game : (inprogress, youlost, youwon);
- locate : array[1..6] of room;
-
- Procedure warnings;
- var location, i, j: integer;
- begin
- writeln;
- location := locate[1];
- for i := 2 to 6 do
- begin
- for j := 1 to 3 do
- begin
- If cave[location,j] = locate[i] then
- case i of
- 2: writeln('I smell a Wumpus!');
- 3, 4: writeln('I feel a draft!');
- 5, 6: writeln('Bats nearby!');
- End{case};
- end{ for j };
- end{ for i };
- writeln('You are in Room ',location:2);
- write('Tunnels lead to ');
- for i := 1 to 3 do write(cave[location,i]:3);
- writeln;
- End { warnings };
-
- Function WantToShoot : boolean;
- LABEL 4;{EXIT}
- var ch : char;
- begin
- Repeat
- writeln;
- write('Shoot or move (s-m) <esc>');
- KEYIN(ch);writeln;
- If ch = escape then
- begin
- game := youlost;
- { EXIT(HuntTheWumpus) } goto 4;
- end;
- If ch = 'l' then
- begin
- write('you = ',locate[1]:3, ' ':8);
- write(' wumpus = ',locate[2]:3);
- writeln(' pits = ',locate[3]:3,',',locate[4]:3);
- writeln(' bats = ',locate[5]:3,',',locate[6]:3);
- writeln
- end;
- Until ch in ['m', 'M', 's', 'S'];
- WantToShoot := ch in ['S', 's'];
- 4:{EXIT}
- End { WantToShoot };
-
- Procedure movewumpus;
- var i : integer;
- begin
- i := wumpmove;
- If i > 0 then locate[2] := cave[locate[2],i];
- If locate[1] = locate[2] then
- begin
- writeln('Tsk Tsk Tsk - Wumpus got you!');
- game := youlost
- end;
- End { movewumpus };
-
- Function lint( s : alfa;
- var l : long) : integer;
- LABEL 3;{EXIT}
- var
- i, j : integer;
- negitive : boolean;
- ch : char;
- begin
- j := 0;
- l := 0;
- lint := -1;
- negitive := false;
- for i := 1 to length(s) do
- begin
- ch := s[i];
- If ch in ['0'..'9'] then
- begin
- j := j + 1;
- If j > 36 then
- begin lint := -2; {EXIT(lint)}goto 3 end;
- l := l * 10 + (ord(ch) - ord('0'))
- end
- Else
- If ch = '-' then
- begin If negitive then {EXIT(lint)}goto 3 end
- Else {EXIT(lint)}goto 3;
- end;{ FOR }
- If l > maxint then
- lint := j
- Else
- lint := 0;
- If negitive then l := -l;
- 3:{EXIT}
- end{lint};
-
- Procedure doshot;
- var
- path : array[1..5] of integer;
- rooms, i, j, arrow : integer;
- roomok, targethit : boolean;
- l : long;
- ans : alfa;
- begin
- { program the arrow }
- Repeat
- write('No. of rooms (1-5) ');
- readln(ans);
- i := lint(ans, l);
- rooms := trunc(l);
- Until (i = 0) and (rooms >= 1) and (rooms <= 5);
- for i := 1 to rooms do
- begin
- Repeat
- roomok := true;
- write('Room # ');
- readln(ans);
- j := lint(ans, l);
- roomok := (j = 0) and (l > 0) and (l < 21);
- path[i] := trunc(l);
- If i > 2 then
- If path[i] = path[i-2] then
- begin
- writeln('Arrows aren''t that crooked - try another room');
- roomok := false;
- end;
- If not roomok then write(bell);
- Until roomok;
- end;
- { shoot the arrow }
- arrowcount := arrowcount - 1;
- I := 1;
- arrow := locate[1];
- Repeat
- roomok := false;
- for j := 1 to 3 do
- If cave[arrow,j] = path[i] then roomok := true;
- If roomok then
- arrow := path[i]
- Else
- arrow := randroom;
- If arrow = locate[1] then
- begin
- writeln('OUCH! Arrow got YOU!');
- game := youlost
- end
- Else
- If arrow = locate[2] then
- begin
- writeln('Aha! You got the Wumpus!');
- game := youwon
- end;
- i := i + 1;
- Until (i > rooms) or (game <> inprogress);
- Case game of
- inprogress: begin
- If arrowcount=0 then
- begin
- writeln('Out of arrows!!');
- game := youlost;
- end
- Else
- writeln('missed');
- MoveWumpus;
- end;
- youwon: {dummy};
- youlost: MoveWumpus
- end{of Case};
- end { doshot };
-
- Procedure domove;
- var
- room, i, location : integer;
- roomok, movefinished : boolean;
- l : long;
- ans : alfa;
- begin
- location := locate[1];
- Repeat
- write('Where to? ');
- readln(ans);
- roomok := false;
- i := lint(ans, l);
- room := trunc(l);
- If i = 0 then
- begin
- for i := 1 to 3 do
- If room = cave[location,i] then roomok := true;
- If room = location then roomok := true;
- end;{ If i=0 }
- If not roomok then writeln('Not possible');
- Until roomok;
- location := room;
- Repeat
- locate[1] := location;
- movefinished := true;
- If location = locate[2] then
- begin
- writeln('... OOPS! Bumped a Wumpus');
- movewumpus
- end;
- If game = inprogress then
- If (location = locate[3]) or (location = locate[4]) then
- begin
- writeln('YYYIIEEEE . . . Fell in a pit!');
- game := youlost
- end
- Else
- If (location = locate[5]) or (location = locate[6]) then
- begin
- writeln('ZAP -- Super bat snatch! Elsewhereville for you!');
- movefinished := false;
- location := randroom
- end;
- Until movefinished;
- end { do move };
-
- begin { HuntTheWumpus }
- arrowcount := 5;
- for i := 1 to 6 do locate[i] := initlocate[i];
- game := inprogress;
- writeln;
- writeln(Title);
- writeln;
- {} REPEAT
- warnings;
- Case WantToShoot of
- TRUE: If game<>youlost then Doshot;
- FALSE: If game<>youlost then DoMove
- End{of case};
- {} Until game<>inprogress;
- If game = youwon then
- writeln('Hee Hee Hee - The Wumpus''ll getcha next time.')
- Else
- writeln('Ha Ha Ha - You lose!');
- end{ huntthewumpus };
-
- Function newsetup: boolean;
- begin
- newsetup := QUIRY('Same setup (y-n) ');
- end;
-
- Function newcave: boolean;
- begin
- newcave := QUIRY('Same cave (y-n) ');
- end;
-
- Function alldone : boolean;
- begin
- alldone := Quiry('Play again (y-n) ');
- end;
-
- begin{ Main Program Wumpus }
- terminit;
- Instruct;
- Repeat
- getacave;
- If fatal_error then{ABORT}goto 99;
- Repeat
- initsetup;
- Repeat
- HuntTheWumpus;
- Until newsetup;
- Until newcave
- Until alldone;
- 99:{ABORT}
- End{of Wumpus}.
-