home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / mbug / mbug086.arc / GAMES.LBR / CONVOY1.IZ / CONVOY1.I
Text File  |  1979-12-31  |  10KB  |  344 lines

  1. procedure Board;
  2.  
  3. const
  4.   tab = ^I;
  5.  
  6. var
  7.   k :integer;
  8.  
  9. begin
  10. writeln;
  11. writeln(tab,'The board (sub indicated by "<"):');
  12. writeln;
  13. write(tab);
  14. for k := 1 to sqr(grid_size) do
  15.   begin
  16.   if k = sub.location
  17.     then write(k:3,'<')
  18.     else write(k:3,' ');
  19.   if k mod grid_size = 0
  20.     then begin
  21.          writeln;
  22.          write(tab);
  23.          end;
  24.   end;
  25. writeln;
  26. end; (* Board *)
  27.  
  28.  
  29. procedure Instruct;
  30.  
  31. const
  32.   tab = ^I;
  33.  
  34. var
  35.   ch :char;
  36.  
  37. begin
  38. writeln('This is a naval war game played on a ',grid_size,'x',grid_size,' matrix.');
  39. writeln('You are the sub; the computer is a cargo ship with an escort and a destroyer.');
  40. writeln('The ship starts in square ',sqr(grid_size),' and randomly moves towards its port (square 1)');
  41. writeln('moving 1,2, or 3 squares at a time. The escort always stays within one');
  42. writeln('square of the ship. The destroyer starts in a square near the ship and moves');
  43. writeln('randomly 0,1,2, or 3 squares at a time searching for the sub.');
  44. writeln('The sub starts near the port and can move up, down, left, or right one square');
  45. writeln('at a time, two moves per turn, and it has torpedoes which it can fire one at a');
  46. writeln('time in any straight line. After each sub move, the periscope will search each');
  47. writeln('adjacent square for the ship. Also, random reconnaissance reports will be');
  48. writeln('made. The sequence of play is:');
  49. writeln;
  50. writeln(tab,'1 ship and destroyers move,');
  51. writeln(tab,'2 your move,');
  52. writeln(tab,'3 you may fire a torpedo,');
  53. writeln(tab,'4 periscope search,');
  54. writeln(tab,'5 your move again,');
  55. writeln(tab,'and back to 1.');
  56. writeln;
  57. write('Press RETURN... ');
  58. readln(ch);
  59. writeln;
  60. writeln('The sub wins if it manages to destroy the cargo ship without moving to a');
  61. writeln('square occupied by a destroyer.');
  62. writeln('Firing commands are: NO, L, R, U, D, LU, LD, RU, RD.');
  63. writeln('If you enter 0 as your move, then the board will be printed out.');
  64. board;
  65. write('Press RETURN... ');
  66. readln(ch);
  67. writeln; writeln;
  68. end; (* Instruct *)
  69.  
  70.  
  71. procedure Depth_Charge;
  72. begin
  73. who_won := computer; ended := true;
  74. writeln('VAROOM!! Sub depth charged!');
  75. end; (* Depth_Charge *)
  76.  
  77.  
  78. procedure Move_Ship;
  79.  
  80. var
  81.   move, k, dir, num_moves :integer;
  82.   valid, reported :boolean;
  83.  
  84.   procedure Move_Escort;
  85.  
  86.   var
  87.     move :integer;
  88.     valid :boolean;
  89.  
  90.   begin
  91.   repeat
  92.     valid := true;
  93.     move := ship.location + (1 - random(2) * 2) * (random(2) * 9 + 1);
  94.     if (move < 2) or (move > sqr(grid_size)) then valid := false;
  95.   until valid;
  96.   escort.location := move;
  97.   if escort.location = sub.location
  98.     then begin
  99.          writeln('Escort directly overhead!');
  100.          depth_charge;
  101.          end;
  102.   end; (* Move_escort *)
  103.  
  104. begin (* Move_Ship *)
  105. reported := false; randomize;
  106. k := 1;
  107. num_moves := random(3) + 1;
  108. while (k <= num_moves) and (not ended) do with ship do
  109.   begin
  110.   if random < 0.75
  111.     then dir := -1
  112.     else dir := 1;
  113.   valid := false;
  114.   repeat
  115.     move := dir * (random(2) * 9 + 1);
  116.     if move = 1
  117.       then begin
  118.            if location mod grid_size = 0
  119.              then dir := -dir
  120.              else if -move = last_move
  121.                     then dir := -dir
  122.                     else valid := true;
  123.            end
  124.       else if move = -1
  125.              then begin
  126.                   if location mod grid_size = 1
  127.                     then dir := -dir
  128.                     else if -move = last_move
  129.                            then dir := -dir
  130.                            else valid := true;
  131.                   end
  132.              else if (-move = last_move) or
  133.                      (location+move < 1) or (location+move > sqr(grid_size)) or
  134.                      (location = destroyer.location)
  135.                     then dir := -dir
  136.                     else valid := true;
  137.   until valid;
  138.   if not reported
  139.     then begin
  140.          writeln('Ship moved.');
  141.          reported := true;
  142.          end;
  143.   if location in [1..3,11,12,21]
  144.     then begin
  145.          who_won := computer; ended := true;
  146.          writeln('Ship''s in port.');
  147.          end
  148.     else begin
  149.          if location = sub.location
  150.            then writeln('Ship now overhead.');
  151.          last_move := move;
  152.          location := location + move;
  153.          if not escort.dead then move_escort;
  154.          k := succ(k);
  155.          end;
  156.   end; (* while *)
  157. end; (* Move_Ship *)
  158.  
  159.  
  160. procedure Move_Destroyer;
  161.  
  162. var
  163.   move, k, dir, num_moves :integer;
  164.   valid, reported :boolean;
  165.  
  166. begin
  167. reported := false; randomize;
  168. k := 1;
  169. if random > 0.8
  170.   then num_moves := 0
  171.   else num_moves := random(3) + 1;
  172. while (k <= num_moves) and (not ended) do with destroyer do
  173.   begin
  174.   if random < 0.65
  175.     then dir := -1
  176.     else dir := 1;
  177.   valid := false;
  178.   repeat
  179.     move := dir * (random(2) * 9 + 1);
  180.     if move = 1
  181.       then begin
  182.            if location mod grid_size = 0
  183.              then dir := -dir
  184.              else if -move = last_move
  185.                     then dir := -dir
  186.                     else valid := true;
  187.            end
  188.       else if move = -1
  189.              then begin
  190.                   if location mod grid_size = 1
  191.                     then dir := -dir
  192.                     else if -move = last_move
  193.                            then dir := -dir
  194.                            else valid := true;
  195.                   end
  196.              else if (-move = last_move) or
  197.                      (location+move < 2) or (location+move > sqr(grid_size)) or
  198.                      (location = ship.location)
  199.                     then dir := -dir
  200.                     else valid := true;
  201.   until valid;
  202.   if not reported
  203.     then begin
  204.          writeln('Destroyer has moved.');
  205.          reported := true;
  206.          end;
  207.   if location = sub.location
  208.     then depth_charge
  209.     else begin
  210.          last_move := move;
  211.          location := location + move;
  212.          k := succ(k);
  213.          end;
  214.   end; (* while *)
  215. end; (* Move_Destroyer *)
  216.  
  217.  
  218. function Nearby (centre, intruder :integer) :boolean;
  219. (* Returns true if "intruder" is in the immediate vicinity of "centre". *)
  220.  
  221. begin
  222. nearby := (intruder = centre) or
  223.           (intruder = centre-1) or (intruder = centre+1) or
  224.           (intruder = centre-grid_size) or (intruder = centre+grid_size) or
  225.           (intruder = centre-(grid_size-1)) or (intruder = centre+(grid_size-1)) or
  226.           (intruder = centre-(grid_size+1)) or (intruder = centre+(grid_size+1));
  227. end; (* Nearby *)
  228.  
  229.  
  230. procedure Scan;
  231.  
  232. begin
  233. randomize;
  234. if (destroyer.location = sub.location) and (not destroyer.dead)
  235.   then begin
  236.        writeln('Destroyer directly overhead.');
  237.        if random < 0.8
  238.          then depth_charge
  239.          else writeln('Depth charge just missed!');
  240.        end
  241.   else if (escort.location = sub.location) and (not escort.dead)
  242.          then begin
  243.               writeln('Escort directly overhead.');
  244.               depth_charge;
  245.               end
  246.          else if nearby(sub.location,destroyer.location) and
  247.                  (not destroyer.dead)
  248.                 then begin
  249.                      writeln('Destroyer closing in at ',destroyer.location,'.');
  250.                      destroyer.last_seen := destroyer.location;
  251.                      end
  252.                 else if nearby(sub.location,escort.location) and
  253.                         (not escort.dead)
  254.                        then begin
  255.                             writeln('Escort very near!');
  256.                             escort.last_seen := escort.location;
  257.                             end
  258.                        else if (random > 0.6) and (not destroyer.dead)
  259.                               then begin
  260.                                    writeln('Recon. plane spots tincan at ',destroyer.location,'!');
  261.                                    destroyer.last_seen := destroyer.location;
  262.                                    end;
  263. end; (* Scan *)
  264.  
  265.  
  266. procedure Periscope_Search;
  267.  
  268. begin
  269. randomize;
  270. write('Up periscope: ');
  271. if nearby(sub.location,ship.location)
  272.   then begin
  273.        writeln('ship at ',ship.location,'.');
  274.        ship.last_seen := ship.location;
  275.        end
  276.   else begin
  277.        writeln('ship not in sight.');
  278.        if random > 0.4
  279.          then begin
  280.               writeln('Recon. shows ship at ',ship.location,'.');
  281.               ship.last_seen := ship.location;
  282.               end;
  283.        end;
  284. scan;
  285. end; (* Periscope_Search *)
  286.  
  287.  
  288. procedure Move_Sub;
  289.  
  290. var
  291.   new_loc :integer;
  292.   valid :boolean;
  293.  
  294. begin
  295. writeln;
  296. writeln('Sub is now at ',sub.location,'.');
  297. write('Ship last seen at ',ship.last_seen);
  298. if destroyer.dead
  299.   then writeln('.')
  300.   else writeln(', destroyer last sighted at ',destroyer.last_seen,'.');
  301. repeat
  302.   valid := true;
  303. {$I-}
  304.   repeat
  305.     write('Sub''s move: ');
  306.     readln(new_loc);
  307.   until ioresult = 0;
  308. {$I+}
  309.   if (new_loc < 2) or (new_loc > sqr(grid_size))
  310.     then begin
  311.          valid := false;
  312.          if new_loc = 0
  313.            then board
  314.            else writeln('What? Try again.');
  315.          end;
  316.   if valid
  317.     then if new_loc = sub.location + 1
  318.            then begin
  319.                 if sub.location mod grid_size = 0
  320.                   then begin
  321.                        valid := false;
  322.                        writeln('Can''t move there. Try again.');
  323.                        end;
  324.                 end
  325.            else if new_loc = sub.location - 1
  326.                   then begin
  327.                        if new_loc mod grid_size = 0
  328.                          then begin
  329.                               valid := false;
  330.                               writeln('Can''t move there. Try again.');
  331.                               end;
  332.                        end
  333.                   else if not ((new_loc = sub.location+grid_size) or
  334.                                (new_loc = sub.location-grid_size) or
  335.                                (new_loc = sub.location))
  336.                          then begin
  337.                               valid := false;
  338.                               writeln('Can''t move there. Try again.');
  339.                               end;
  340. until valid;
  341. sub.location := new_loc;
  342. periscope_search;
  343. end; (* Move_Sub *)
  344.