home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol021 / wumpus.pas < prev   
Pascal/Delphi Source File  |  1984-04-29  |  12KB  |  504 lines

  1. {*
  2.  *  Program Title:    Wumpus
  3.  *  Written by:        Gregory Yob
  4.  *            More BASIC Computer Games
  5.  *            Edited by David H. Ahl
  6.  *
  7.  * Translated into Pascal by Paul H. Gilliam from the
  8.  * BASIC programs 'WUMPUS 1' and 'WUMPUS 2'
  9.  *
  10.  * This game will teach you how to play it.
  11.  * Happy wumpus hunting!
  12.  *
  13.  *   29 June 1980    -corrected minor logic bugs.
  14.  *   29 June 1980    -Modified for Pascal/Z v3.0
  15.  *             Pascal/Z does not allow jumps out
  16.  *             of Procedures/Functions [A practice
  17.  *             I fully agree with!]
  18.  *  Donated July, 1980
  19.  *}
  20. Program  Wumpus;
  21. LABEL    99;        { Fatal error }
  22. CONST
  23.   default = 80;
  24.   {---   define your screen parameters   ---}
  25.   s_beglin =  1;    { first line }      (* ADM-3A Screen parameters *)
  26.   s_endlin = 23;    { last  line }
  27.   s_begcol =  1;    { first column }
  28.   s_endcol = 80;    { last column  }
  29.  
  30. TYPE    
  31.   alfa    = STRING 10;        { just the right size }
  32.   Dstring = STRING default;
  33.   str0    = STRING 0;
  34.   str255  = STRING 255;
  35.   room     = 1 .. 20;
  36.   tunnel   = 1 .. 3;
  37.  
  38. VAR
  39.  arrowcount    : integer;
  40.  bell        : char;
  41.  cave        : array[room, tunnel] of room;
  42.  cursorhome,        { cursor controls }
  43.  cursorup,
  44.  cursordown,
  45.  cursorleft,
  46.  cursorright,  
  47.  clearscreen,
  48.  escape        : char;
  49.  fatal_error    : boolean;
  50.  i, j        : integer;    { global indexers }
  51.  initlocate    : array[1..6] of room;
  52.  
  53. Procedure KEYIN(VAR cix: char); external;
  54. (*---Direct Keyboard input of a single char---*)
  55.  
  56. Function RANDOM(limit: integer): real; external;
  57. (*---returns a real number from 0.0 to limit---*)
  58.  
  59. Function length(x: str255): integer; external;
  60.  
  61. Procedure gotoxy( col, row : integer );
  62. (*         X-coord, Y-coord    *)
  63. begin
  64.   WRITE( chr(27), '=', chr(row+32), chr(col+32))
  65. end;
  66.  
  67. Procedure terminit;
  68. begin 
  69.  bell := chr(7);
  70.  escape        := chr(27);
  71.  cursorhome := chr(30);
  72.  cursorup   := chr(11);;   
  73.  cursordown := chr(10);
  74.  cursorleft := chr(8);
  75.  cursorright := chr(12);  
  76.  clearscreen := chr(26);    { ASCII control-Z }
  77. end{of terminit};
  78.  
  79. Procedure CLEAR;
  80. begin
  81.   Write(clearscreen);
  82. end;
  83.  
  84. Procedure clearline( row: integer );
  85. begin
  86.   gotoxy( s_begcol, row);
  87.   WRITE( ' ':(s_endcol-s_begcol+1) );
  88.   gotoxy( s_begcol, row);
  89. end;
  90.  
  91. Function  randroom : room; { 1..20 }
  92. begin
  93.   randroom := trunc(random(20)) + 1
  94. end  { randroom };
  95.  
  96. Function  randtunnel : tunnel; { 1..3 }
  97. begin
  98.  randtunnel := trunc(random(3)) + 1
  99. end  { randtunnel };
  100.  
  101. Function  wumpmove : integer; 
  102. var    i : integer;
  103. begin
  104.   i := trunc(random(4)) + 1;
  105.   If i > 3 then
  106.     wumpmove := -1
  107.   Else
  108.     wumpmove := i;
  109. end  { wumpmove };
  110.  
  111. Function QUIRY(sign: Dstring): boolean;
  112. var    ch: char;
  113. begin
  114.   writeln;
  115.   Repeat
  116.     write(sign);
  117.     KEYIN(ch);writeln(ch);
  118.     writeln;
  119.   Until ch IN ['Y', 'y', 'N', 'n'];
  120.   QUIRY := ch in ['n', 'N'];
  121. end;
  122.  
  123. Procedure Instruct;
  124. {*
  125.  *   Attempts to read in an external file to instruct the player
  126.  *   as to how to play the game.
  127.  *   Instruct will pause for console input whenever it finds the
  128.  *   string "$pause" in the first position of a line in the line.
  129.  *}
  130. var    line : Dstring;  
  131.     Ifile : text;
  132.     ch : char;
  133.  
  134.     Procedure ShowInstructions;
  135.     begin
  136.       CLEAR;
  137.       Readln(Ifile,line);
  138.       while  not eof(Ifile) do
  139.         begin
  140.           If (line = '$pause') or (line = '$PAUSE') then
  141.         begin
  142.         Clearline(s_endlin);
  143.         write('Press <sp> to continue.');KEYIN(ch);
  144.         CLEAR;
  145.         end
  146.           Else
  147.         writeln(line);
  148.           readln(Ifile,line);
  149.        end;{ While }
  150.     End{ShowInstructions};
  151.  
  152. begin  { instruct }  
  153.   CLEAR;
  154.   write('Do you want instructions on how to play? ');
  155.   KEYIN(ch);Writeln(ch);
  156.   writeln;
  157.   If (ch='y') or (ch='Y') then
  158.     begin
  159.       RESET('WUMPUS.DOC',Ifile);
  160.       If not EOF(Ifile) then
  161.     ShowInstructions
  162.       Else
  163.     begin
  164.     writeln;
  165.     writeln('Sorry,  instructions not availiable yet.');
  166.     end;
  167.     end
  168. End{of instruct};
  169.    
  170. Procedure  getacave;
  171. LABEL    9;{ABORT}
  172. var
  173.   i : room;    { 1..20 }
  174.   j : tunnel;    { 1..3 }
  175.   k : integer;
  176.   CAVENAME : STRING 5;
  177.   LINE : Dstring;
  178.   cavein : text;
  179.   ch : char;
  180. begin 
  181.  cavename := 'CAVE ';
  182.  Repeat
  183.    Writeln;
  184.    write(bell, 'Enter cave #(0-5) ');
  185.    KEYIN(ch);Writeln(ch);
  186.  Until  ch in ['0'..'5'];
  187.  cavename[5] := ch;
  188.  (* OPEN file "cavename" for Read assign cavein *)
  189.  RESET(cavename,cavein);
  190.  fatal_error := EOF(cavein);
  191.  If fatal_error then {ABORT}
  192.    begin
  193.      writeln;
  194.      writeln('Fatal error - file not found');
  195.      {ABORT}goto 9;
  196.    end;
  197.  writeln('reading ',cavename); 
  198.  readln(cavein, line);
  199.  for  i := 1 to 20 do
  200.    for j := 1 to 3 do read(cavein,cave[i,j]);
  201.   writeln;
  202.   writeln('You are in ',line);
  203.   writeln;
  204. 9:{ABORT}
  205. End{ of getacave }{ CLOSE(cavein) };
  206.  
  207. Procedure  initsetup; 
  208. var    locatesunique : boolean;
  209.     i, j : integer;  
  210. begin
  211.  Repeat
  212.    for  i := 1 to 6 do initlocate[i] := randroom;  
  213.    locatesunique := true;
  214.    i := 1;
  215.    while  locatesunique and (i <= 6) do
  216.      begin
  217.      j := 1;
  218.      while  locatesunique and (j <= 6) do
  219.        begin
  220.        If (initlocate[i] = initlocate[j]) and (j <> i) then
  221.      locatesunique := false
  222.        Else
  223.      j := j + 1;
  224.        end;
  225.      i := i + 1
  226.      end
  227.  Until  locatesunique
  228. End  { initsetup };
  229.  
  230. Procedure  HuntTheWumpus;
  231. CONST    Title = 'Hunt the Wumpus'; 
  232. TYPE    long = real;
  233. VAR    i    : integer;
  234.     game    : (inprogress, youlost, youwon);
  235.     locate    : array[1..6] of room;
  236.  
  237.     Procedure  warnings;  
  238.     var    location, i, j: integer;
  239.     begin
  240.       writeln;
  241.       location := locate[1];   
  242.       for  i := 2 to 6 do
  243.         begin
  244.         for  j := 1 to 3 do
  245.           begin
  246.           If cave[location,j] = locate[i] then
  247.          case  i  of
  248.               2:  writeln('I smell a Wumpus!');
  249.            3, 4:  writeln('I feel a draft!');
  250.            5, 6:  writeln('Bats nearby!');
  251.          End{case};
  252.           end{ for j };
  253.         end{ for i };
  254.       writeln('You are in Room ',location:2);
  255.       write('Tunnels lead to ');
  256.       for  i := 1 to 3 do write(cave[location,i]:3); 
  257.       writeln;
  258.     End  { warnings };
  259.  
  260.     Function  WantToShoot : boolean;   
  261.     LABEL 4;{EXIT}
  262.     var    ch : char;      
  263.     begin
  264.       Repeat
  265.         writeln;
  266.         write('Shoot or move (s-m) <esc>');     
  267.         KEYIN(ch);writeln;
  268.         If ch = escape then
  269.           begin   
  270.           game := youlost;
  271.           { EXIT(HuntTheWumpus) } goto 4;
  272.           end;
  273.         If ch = 'l' then
  274.           begin  
  275.           write('you = ',locate[1]:3, ' ':8);
  276.           write(' wumpus = ',locate[2]:3);
  277.           writeln(' pits = ',locate[3]:3,',',locate[4]:3);
  278.           writeln(' bats = ',locate[5]:3,',',locate[6]:3);
  279.           writeln
  280.           end;
  281.       Until  ch in ['m', 'M', 's', 'S'];   
  282.       WantToShoot := ch in ['S', 's'];
  283.     4:{EXIT}
  284.     End  { WantToShoot }; 
  285.                     
  286.     Procedure  movewumpus; 
  287.     var    i : integer;
  288.     begin
  289.       i := wumpmove;
  290.       If i > 0 then  locate[2] := cave[locate[2],i];
  291.       If locate[1] = locate[2] then
  292.         begin      
  293.         writeln('Tsk Tsk Tsk - Wumpus got you!');
  294.         game := youlost
  295.         end;
  296.     End  { movewumpus };
  297.  
  298.     Function  lint(    s : alfa;
  299.                var l : long) : integer;  
  300.     LABEL 3;{EXIT}
  301.     var
  302.       i, j : integer;
  303.       negitive : boolean;
  304.       ch : char;
  305.     begin 
  306.       j := 0;
  307.       l := 0;
  308.       lint := -1;
  309.       negitive := false;
  310.       for  i := 1 to length(s) do
  311.         begin 
  312.         ch := s[i];
  313.         If ch in ['0'..'9'] then
  314.           begin
  315.           j := j + 1;
  316.           If j > 36 then
  317.             begin lint := -2; {EXIT(lint)}goto 3 end;
  318.           l := l * 10 + (ord(ch) - ord('0'))
  319.           end 
  320.         Else
  321.           If ch = '-' then
  322.         begin If negitive then {EXIT(lint)}goto 3 end
  323.           Else  {EXIT(lint)}goto 3;
  324.         end;{ FOR }
  325.       If l > maxint then
  326.         lint := j
  327.       Else
  328.         lint := 0;
  329.       If negitive then  l := -l;
  330.       3:{EXIT}
  331.     end{lint};
  332.  
  333. Procedure doshot;
  334. var
  335.   path : array[1..5] of integer;
  336.   rooms, i, j, arrow : integer;
  337.   roomok, targethit : boolean;
  338.   l : long;
  339.   ans : alfa;
  340. begin
  341.  { program the arrow }
  342.   Repeat
  343.     write('No. of rooms (1-5) ');
  344.     readln(ans);   
  345.     i := lint(ans, l);
  346.     rooms := trunc(l);
  347.   Until  (i = 0) and (rooms >= 1) and (rooms <= 5);              
  348.   for  i := 1 to rooms do
  349.     begin
  350.     Repeat
  351.       roomok := true;
  352.       write('Room # ');
  353.       readln(ans);  
  354.       j := lint(ans, l);
  355.       roomok := (j = 0) and (l > 0) and (l < 21);
  356.       path[i] := trunc(l);
  357.       If i > 2 then
  358.     If path[i] = path[i-2] then
  359.       begin
  360.       writeln('Arrows aren''t that crooked - try another room');
  361.       roomok := false;
  362.       end;
  363.       If not roomok then  write(bell);  
  364.     Until  roomok;
  365.     end;
  366.     { shoot the arrow }
  367.   arrowcount := arrowcount - 1;
  368.   I := 1;
  369.   arrow := locate[1];
  370.   Repeat 
  371.     roomok := false; 
  372.     for  j := 1 to 3 do
  373.       If cave[arrow,j] = path[i] then  roomok := true;
  374.     If roomok then
  375.       arrow := path[i]
  376.     Else
  377.       arrow := randroom;
  378.     If arrow = locate[1] then
  379.     begin    
  380.     writeln('OUCH! Arrow got YOU!');
  381.     game := youlost
  382.     end 
  383.     Else
  384.       If arrow = locate[2] then
  385.     begin
  386.     writeln('Aha! You got the Wumpus!');
  387.     game := youwon
  388.     end;
  389.     i := i + 1;
  390.   Until  (i > rooms) or (game <> inprogress);
  391.   Case game of
  392.     inprogress:    begin
  393.         If arrowcount=0 then
  394.           begin
  395.           writeln('Out of arrows!!');
  396.           game := youlost;
  397.           end
  398.         Else
  399.           writeln('missed');
  400.         MoveWumpus;
  401.         end;
  402.    youwon:    {dummy};
  403.    youlost:    MoveWumpus
  404.    end{of Case};
  405. end  { doshot };
  406.  
  407. Procedure domove; 
  408. var
  409.   room, i, location : integer;
  410.   roomok, movefinished : boolean;
  411.   l : long;
  412.   ans : alfa;
  413. begin
  414.   location := locate[1];
  415.   Repeat
  416.     write('Where to? '); 
  417.     readln(ans); 
  418.     roomok := false;
  419.     i := lint(ans, l);
  420.     room := trunc(l);
  421.     If i = 0 then
  422.       begin
  423.       for  i := 1 to 3 do
  424.     If room = cave[location,i] then  roomok := true;
  425.       If room = location then  roomok := true;
  426.       end;{ If i=0 }
  427.     If not roomok then  writeln('Not possible');
  428.   Until  roomok;
  429.   location := room;
  430.   Repeat  
  431.     locate[1] := location;
  432.     movefinished := true; 
  433.     If location = locate[2] then
  434.       begin
  435.       writeln('... OOPS!  Bumped a Wumpus');
  436.       movewumpus
  437.       end;
  438.     If game = inprogress then
  439.       If (location = locate[3]) or (location = locate[4]) then
  440.     begin
  441.     writeln('YYYIIEEEE . . . Fell in a pit!');
  442.     game := youlost
  443.     end
  444.       Else
  445.     If (location = locate[5]) or (location = locate[6]) then
  446.       begin
  447.       writeln('ZAP -- Super bat snatch! Elsewhereville for you!'); 
  448.       movefinished := false;
  449.       location := randroom
  450.       end;
  451.   Until  movefinished;
  452. end  { do move }; 
  453.  
  454. begin { HuntTheWumpus } 
  455.   arrowcount := 5; 
  456.   for  i := 1 to 6 do locate[i] := initlocate[i];       
  457.   game := inprogress;
  458.   writeln;
  459.   writeln(Title);
  460.   writeln;
  461. {}  REPEAT
  462.       warnings;
  463.       Case WantToShoot of
  464.     TRUE:    If game<>youlost then Doshot;
  465.     FALSE:    If game<>youlost then DoMove
  466.       End{of case};
  467. {}  Until game<>inprogress;
  468.   If game = youwon then
  469.     writeln('Hee Hee Hee - The Wumpus''ll getcha next time.')
  470.   Else
  471.     writeln('Ha Ha Ha - You lose!');
  472. end{ huntthewumpus };
  473.  
  474. Function newsetup: boolean;
  475. begin
  476.   newsetup := QUIRY('Same setup (y-n) ');
  477. end;
  478.  
  479. Function newcave: boolean;
  480. begin
  481.   newcave := QUIRY('Same cave (y-n) ');
  482. end;
  483.  
  484. Function  alldone : boolean; 
  485. begin
  486.   alldone := Quiry('Play again (y-n) ');
  487. end;
  488.  
  489. begin{ Main Program Wumpus }
  490.   terminit; 
  491.   Instruct;
  492.   Repeat
  493.      getacave;
  494.      If fatal_error then{ABORT}goto 99;
  495.      Repeat 
  496.        initsetup;
  497.        Repeat
  498.      HuntTheWumpus;
  499.        Until  newsetup;
  500.      Until  newcave
  501.   Until  alldone;
  502. 99:{ABORT}
  503. End{of Wumpus}.
  504.