%  Battleship in TeX
%
%  Andrew Marc Greene
%  MIT Project Athena
%  and
%  Student Information Processing Board
%  Version 1.0 April 1989
%
%  Battleship is a registered trademark of the Milton Bradley Corp.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Array-handling code (modified to handle two-dimensional arrays)
%
%  \put    takes four arguments:
%            the variant on \def
%            the array name
%            the two index values
%
\def\put#1#2#3#4{\expandafter #1%    \def -- but first find the AINAME
\csname #2%                          begin the \csname and use the arrayname
.\if\relax #3\the\fi #3.%            first index
\if\relax #4\the\fi #4\endcsname }%  second index and end the \csname
%
%
%  \get    takes three arguments:
%            the array name
%            the two index values
%
\def\get#1#2#3{\csname #1%           same as above....
.\if\relax #2\the\fi #2%
.\if\relax #3\the\fi #3%
\endcsname}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \say is a useful shorthand for ``output to screen''
%
\def\say#1{\immediate\write16{#1}}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Initialize the array to all ``Z''
%
\newcount\idx\newcount\idy
\idx=0\idy=0
\loop
\edef\Idx{\ifcase\idx A\or B\or C\or D\or E\or F\or G\or H\or I\or J\fi}
\put{\def}{MyGrid}{\Idx}{\idy}{Z}%
\advance\idx by 1
\ifnum\idx=10
\advance\idy by 1
\idx=0
\fi
\ifnum\idy<10
\repeat
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Display welcome message
%
\say{Welcome to Battleship.}
\say{(Battleship is a trademark of Milton Bradley)}
\say{}
\say{This version uses fixed-position ships.}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Position the ships.  Future versions will use a random-number
%  generator to provide a different game each time.
%
\put{\def}{MyGrid}{D}{4}{C}%        Carrier has 5 spaces
\put{\def}{MyGrid}{E}{4}{C}
\put{\def}{MyGrid}{F}{4}{C}
\put{\def}{MyGrid}{G}{4}{C}
\put{\def}{MyGrid}{H}{4}{C}
\put{\def}{MyGrid}{B}{1}{B}%        Battleship has 4
\put{\def}{MyGrid}{B}{2}{B}
\put{\def}{MyGrid}{B}{3}{B}
\put{\def}{MyGrid}{B}{4}{B}
\put{\def}{MyGrid}{G}{7}{D}%        Destroyer has 3
\put{\def}{MyGrid}{G}{8}{D}
\put{\def}{MyGrid}{G}{9}{D}
\put{\def}{MyGrid}{J}{6}{S}%        Submarine has 2
\put{\def}{MyGrid}{J}{7}{S}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Initialize some counters
%
\newcount\turns\turns=0%             Number of turns it takes to win
\newcount\hits\hits=14%%             Number of hits it takes to win
\newcount\carrier\carrier=5%         Number of hits to sink each ship
\newcount\battleship\battleship=4
\newcount\destroyer\destroyer=3
\newcount\submarine\submarine=2
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Routines to handle damage to a ship
%
%  \gobble (as defined in the TeXbook, page 308)
%
\def\gobble#1{}%                     Remove one token
%
%  \damage takes the name of a counter and damages that ship:
%
\def\damage#1{\advance#1 by -1 %     Lose one `hit point'
\ifnum #1=0 %                        If there are no more,
%                                    Print a `sank' message:
\say{You sank my \expandafter\gobble\string #1!}
\else%                               Otherwise, a `hit' message:
\say{You have hit my \expandafter\gobble\string #1.}
\fi}
%
%  Note that the above messages used \expandafter\gobble\string #1
%  to get the name of the counter and strip the \escapechar off the
%  front of it.  The resulting string (because of the way we named
%  our counters) is the name of the appropriate ship.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Give the player a chance to specify a coordinate.
%  If it's already been used, or is out-of-bounds, \say an error.
%  Otherwise increment \turns and print an appropriate message;
%    If it is a hit, decrement \hits;
%    Whether it is a hit or not, blat the space.
%  If \hits is non-zero, keep going.....
%
%
\def\defab#1#2#3^^C{\def\a{#1}\def\b{#2}}
\loop
\message{Your turn: }
\read-1 to \usrinp
\expandafter\defab\usrinp^^C
\edef\c{\get{MyGrid}{\a}{\b}}
\if\c\relax
\say{Sorry, that's not a valid coordinate.}
\else
\if\c X\say{Sorry, you already shot there.}
\else\advance\turns by 1
\if\c Z\say{You missed.}
%
%  Drat!  The user hit one of our ships!  Record damage to the correct one.
%
\else\if\c C\damage{\carrier}
\else\if\c B\damage{\battleship}
\else\if\c D\damage{\destroyer}
\else\if\c S\damage{\submarine}
\fi% submarine
\fi% destroyer
\fi% battleship
\fi% carrier
%
%  And record that there was a hit someplace:
%
\advance\hits by -1
\fi%                                 End of the hit-or-miss section
%
%  Record that this space has been shot:
%
\put{\def}{MyGrid}{\a}{\b}{X}
\fi%                                 End of the `shoot here' section
%
\fi%                                 End of the {in}valid spot section
%
%  We've finished a cycle.  If there is any part of the fleet left,
%  we go around again:
%
\ifnum\hits>0\repeat
%
%  Otherwise, we display the player's score and exit.
%
\say{You have destroyed my fleet.  It took you \the\turns\gobble1 turns.}
\bye
