       ! Fortran version of Battleship -- 2002 December 6
       PROGRAM Battleship
       IMPLICIT NONE
       DIMENSION Mine(9,9), Theirs(9,9)
       INTEGER Mine, Theirs, ShowOut, Tries, iseed, IntRand, Lim19
       INTEGER mod, RandomShot, RimShot, GoodShot, BetterShot
       INTEGER ix, tx, zx, ro, co, here, thar, up, wide, tall
! StartGame
       iseed = 2233
       CALL Read3I(up)
       DO ix=1,up
         tx = IntRand(iseed,2)
         END DO
       DO ro=1,9 ! Zapit..
         DO co=1,9
           Mine(ro,co) = 0
           Theirs(ro,co) = 0
           END DO
         END DO
       DO ix=5,1,-1
         wide = ix
         IF (ix<2) wide = 2
         up = IntRand(iseed,2)
         tall = wide*up
         wide = wide*(1-up)
         DO
           here = IntRand(iseed,9-tall+up)
           thar = IntRand(iseed,10-wide-up)
           DO ro=tall+1-up,1,-1
             DO co=wide+up,1,-1
               IF (Mine(here+ro,thar+co)>0) THEN
                 here = -1
                 EXIT
                 END IF
               END DO
             IF (here<0) EXIT
             END DO
           IF (here>=0) THEN
             DO ro=tall+1-up,1,-1
               DO co=wide+up,1,-1
                 Mine(here+ro,thar+co) = ix
                 END DO
               END DO
             EXIT
             END IF
           END DO
         END DO
       ShowOut = 0
       CALL ShowArrays(Mine, Theirs, ShowOut)
       Tries = 40
! DoTurn
       DO ! forever..
         READ *,up
         IF (up>599) EXIT
         ShowOut = mod(ShowOut,100)
         IF (up==0) THEN
           CALL Read3I(up)
           PRINT *,"You played ",up
           END IF
         IF (up<0) up = 0
         tx = up/100
         up = mod(up,100)
         ro = up/10
         co = mod(up,10)
         ! PRINT *,"??",ShowOut,tx,up,ro,co, ShowOut/10, mod(ShowOut,10)
         IF (ShowOut*tx>0) THEN
           IF (tx==1) THEN ! got something, dunno what..
             Theirs(ShowOut/10, mod(ShowOut,10)) = 9
           ELSE
             CALL SunkIt(Theirs, tx, ShowOut/10, mod(ShowOut,10))
             END IF
           END IF
         up = 0
         ShowOut = 0
         IF (ro*co>0) THEN ! process this shot against me..
           ShowOut = Mine(ro,co)
           IF (ShowOut>5) THEN
             ShowOut = 1 ! repeat shot, just report hit
           ELSE IF (ShowOut>0) THEN
             Mine(ro,co) = ShowOut+5
             DO zx=Lim19(ro-4),Lim19(ro+4)
               tx = Mine(zx,co)
               IF (tx==ShowOut) up = up+1 ! not sunk yet
               END DO
             IF (up==0) THEN 
               DO zx=Lim19(co-4),Lim19(co+4)
                 tx = Mine(ro,zx)
                 IF (tx==ShowOut) up = up+1
                 END DO
               END IF
             IF (up>0) THEN
               ShowOut = 1
             ELSE IF (ShowOut<2) THEN
               ShowOut = 2
               END IF
             END IF
           END IF
         ro = 0
         co = BetterShot(Theirs) ! try to extend a line of hits
         IF (co==0) co = GoodShot(Theirs) ! try for near a hit
         IF (co==0) co = RimShot(Theirs) ! try for a rim
         IF (co==0) co = RandomShot(Theirs, iseed, Tries) ! no directed shots, try a random shot
         IF (co>0) THEN
           Theirs(co/10,mod(co,10)) = -1
           IF (mod(ro+co,2)>0) Tries = Tries-1
         ELSE 
           ShowOut = 9 ! huh? somebody cheated
           END IF
         ShowOut = ShowOut*100+co
         CALL ShowArrays(Mine, Theirs, ShowOut)
         END DO
       END PROGRAM

       SUBROUTINE SunkIt(Theirs, whom, rx, cx)
       IMPLICIT NONE
       DIMENSION Theirs(9,9)
       INTEGER Theirs, whom, rx, cx, ix, hi, lo
       ! PRINT *,"SunkIt", whom, rx, cx
       Theirs(rx,cx) = 9
       lo = rx-1
       DO
         IF (lo<1) EXIT
         IF (Theirs(lo,cx)<6) EXIT
         lo = lo-1
         END DO
       hi = rx+1
       DO
         IF (hi>9) EXIT
         IF (Theirs(hi,cx)<6) EXIT
         hi = hi+1
         END DO
       IF (hi-lo==whom+1) THEN
         DO ix=lo+1,hi-1
           Theirs(ix,cx) = whom
           END DO
       ELSE
         lo = cx-1
         DO 
           IF (lo<1) EXIT
           IF (Theirs(rx,lo)<6) EXIT
           lo = lo-1
           END DO
         hi = cx+1
         DO
           IF (hi>9) EXIT
           IF (Theirs(rx,hi)<6) EXIT
           hi = hi+1
           END DO
         IF (hi-lo==whom+1) THEN
           DO ix=lo+1,hi-1
             Theirs(rx,ix) = whom
             END DO
         ELSE
           Theirs(rx,cx) = whom
           END IF
         END IF
       END SUBROUTINE

       FUNCTION BetterShot(Theirs)
       IMPLICIT NONE
       DIMENSION Theirs(9,9)
       INTEGER BetterShot, Theirs, ro, co
       ! PRINT *,"Better"
       BetterShot = 0
       DO ro=1,9
         DO co=1,7
           IF (Theirs(ro,co)==0) THEN
             IF (Theirs(ro,co+1)>5) THEN
               IF (Theirs(ro,co+2)>5) THEN
                 BetterShot = ro*10+co
                 END IF
               END IF
             END IF
           END DO
         DO co=9,3,-1
           IF (Theirs(ro,co)==0) THEN
             IF (Theirs(ro,co-1)>5) THEN
               IF (Theirs(ro,co-2)>5) THEN
                 BetterShot = ro*10+co
                 END IF
               END IF
             END IF
           END DO
         END DO
       DO co=1,9
         DO ro=1,7
           IF (Theirs(ro,co)==0) THEN 
             IF (Theirs(ro+1,co)>5) THEN
               IF (Theirs(ro+2,co)>5) THEN
                 BetterShot = ro*10+co
                 END IF
               END IF
             END IF
           END DO
         DO ro=9,3,-1 
           IF (Theirs(ro,co)==0) THEN
             IF (Theirs(ro-1,co)>5) THEN
               IF (Theirs(ro-2,co)>5) THEN
                 BetterShot = ro*10+co
                 END IF
               END IF
             END IF
           END DO
         END DO
       END FUNCTION

       FUNCTION GoodShot(Theirs)
       IMPLICIT NONE
       DIMENSION Theirs(9,9)
       INTEGER GoodShot, Lim19, Theirs, ro, co, ix
       ! PRINT *,"Good"
       GoodShot = 0
       DO ro=1,9
         DO co=1,9
           IF (Theirs(ro,co)>5) THEN
             ix = Lim19(ro-1);
             IF (Theirs(ix,co)==0) GoodShot = ix*10+co
             ix = Lim19(ro+1);
             IF (Theirs(ix,co)==0) GoodShot = ix*10+co
             ix = Lim19(co-1);
             IF (Theirs(ro,ix)==0) GoodShot = ro*10+ix
             ix = Lim19(co+1);
             IF (Theirs(ro,ix)==0) GoodShot = ro*10+ix
             END IF
           END DO
         END DO
       END FUNCTION

       FUNCTION RimShot(Theirs)
       IMPLICIT NONE
       DIMENSION Theirs(9,9)
       INTEGER RimShot, Theirs, ix
       ! PRINT *,"Rim"
       RimShot = 0
       DO ix=1,4
         IF (Theirs(ix*2,1)==0) RimShot = ix*20+1
         IF (Theirs(ix*2,9)==0) RimShot = ix*20+9
         IF (Theirs(1,ix*2)==0) RimShot = ix*2+10
         IF (Theirs(9,ix*2)==0) RimShot = ix*2+90
         END DO
       END FUNCTION

       FUNCTION RandomShot(Theirs, iseed, Tries)
       IMPLICIT NONE
       DIMENSION Theirs(9,9)
       INTEGER RandomShot, Lim19, IntRand, Theirs, iseed, Tries
       INTEGER ro, co, cnt, mask, res
       res = 0
       cnt = IntRand(iseed, Tries)
       DO mask=0,2
         ! PRINT *,"Random: ",mask,cnt,Tries
         DO ro=1,9
           DO co=1,9
             IF (mod(ro+co,2)+(mask/2)>0) THEN
               IF (Theirs(ro,co)==0) THEN
                 cnt = cnt-1
                 IF (cnt<0) THEN
                   res = 0
                   Theirs(ro,co) = -1 ! assume nothing there
                   IF (Theirs(Lim19(ro-1),co)<0) THEN
                     IF (Theirs(Lim19(ro+1),co)<0) THEN
                       IF (Theirs(ro,Lim19(co-1))<0) THEN
                         IF (Theirs(ro,Lim19(co+1))<0) THEN ! it can't be a ship..
                           Tries = Tries-1
                           res = -1
                           END IF
                         END IF
                       END IF
                     END IF
                   IF (res==0) THEN
                     res = ro*10+co
                     EXIT
                     END IF
                   END IF
                 END IF
               END IF
             END DO
           IF (res>0) EXIT
           END DO
         IF (res>0) EXIT
         END DO
       RandomShot = res
       END FUNCTION

       FUNCTION Lim19(theNum)
       IMPLICIT NONE
       INTEGER Lim19, theNum, res
       res = theNum
       IF (theNum<1) res = 1
       IF (theNum>9) res = 9
       Lim19 = res
       END FUNCTION

       SUBROUTINE ShowArrays(Mine, Theirs, ShowOut)
       IMPLICIT NONE
       DIMENSION Mine(9,9), Theirs(9,9), chars(19), digits(-1:10)
       INTEGER Mine, Theirs, ShowOut, r, c, ix
       CHARACTER chars, digits
       digits(-1) = "*"
       digits(0) = "."
       digits(1) = "1"
       digits(2) = "2"
       digits(3) = "3"
       digits(4) = "4"
       digits(5) = "5"
       digits(6) = "6"
       digits(7) = "7"
       digits(8) = "8"
       digits(9) = "9"
       digits(10) = "0"
       DO r=1,9
         DO c=1,9
           chars(c) = digits(Mine(r,c))
           END DO
         chars(10) = "|"
         DO c=1,9
           chars(c+10) = digits(Theirs(r,c))
           END DO
         PRINT 100,chars
         END DO
       digits(0) = "0"
       ix = ShowOut
       DO c=3,1,-1
         r = ix/10
         chars(c) = digits(ix-r*10)
         ix = r
         END DO
       PRINT 101,(chars(c),c=1,3)
 100   FORMAT(20(1X,A1))
 101   FORMAT(" My play=", 3A1, ", Yours:")
       CALL Write3I(ShowOut)
       END SUBROUTINE

       SUBROUTINE Write3I(theNum)
       IMPLICIT NONE
       INTEGER theNum
       open (unit=3, file="F:/Play.txt", status="OLD")
       write (3,111),theNum
       close (unit=3)
 111   FORMAT(I3)
       END SUBROUTINE

       SUBROUTINE Read3I(theNum)
       IMPLICIT NONE
       INTEGER theNum
       open (unit=3, file="F:/Play.txt", status="OLD")
       read (3,111),theNum
       close (unit=3)
 111   FORMAT(I3)
       END SUBROUTINE

       FUNCTION IntRand(iseed, modulus)
       IMPLICIT NONE
       INTEGER iseed, modulus, IntRand, mod
       iseed = iseed*2233
       IF (iseed<0) iseed = -iseed
       IntRand = mod(iseed/76,modulus)
       ! PRINT *,"Rnd=",iseed,modulus,IntRand
       END FUNCTION

       FUNCTION mod(num, modulus)
       INTEGER num, modulus, mod
       mod = num-(num/modulus)*modulus
       END FUNCTION

