'Battle Ship 64 Cobalt
'Started 11/23/2018(30mins)
'Cobalt David
'V0.0a inital build(11/23/2018)(45mins)
'inital types and diminsions in place
'V0.0b build(11/24/2018)(30mins)
'added Title screen
'loaded sprite sheet
'V0.1a First Run Build(11/27/2018)(300mins)
'Added\Finished ship deployment
'added auto deployment for computer opponent
'added yellow selection color for ship placement and shot selection
'started shot taking routine
'added Who goes first test
'(made audio files for posible add-in later)
'(ripped video files for posible add-in later)
'V0.1b Build(11/28/2018)(240mins)
'Added Hit and Miss images
'added player shot routines
'added ship sunk routines
'added Gameover state
'added Computer shooting routine
'V0.1C Build(11/29/2018)(150mins)
'fixed Computer Shooting routine, computer can now hit players ships.
'fixed message timing, so its a hit shows befor ship sunk message
'set randomize to TIMER
'game level Easy, Computer AI: STUPID(always random shots)
'added graphics loading rountine
'public release
'V0.1D Build(11/29/2018)(10mins)
'fixed oversight found by Bplus were autoplace doesn't clear board first
'   adding extra 'ghost' ships to the layout.
'Added Title bar info.
'V0.2A Build(11/30/2018)(540mins)
'Added Menu and options
'Added ChangeColor routine
'added fonts
'added instruction page 1
'fixed bug if player pressed Reset with ship selected ship stayed selected
'     as a phantom ship.
'Updated GFX file
'Began networking routines
'first successful log in of clients
'V0.5A Build(12/1/2018)(300mins)
'Ripped Functions\Subs for network retooling.
'Added Networking types\variables\arrays\consts
'added\fixed host startup and client startup
'added communication decodeing
'added Opponent shot for multiplayer games
'V0.7A build(12/2/2018)(210mins)
'fixed networking protocol
'fixed minor bugs related to network game communication
'added IP address entry to join network screen
'reconsistuted routines into main BAS file
'First successful LAN game at 19:55 EST

'fonts:Vecteezy.com/free-fonts.com/Geronimo Font Studios[dafont.com]


TYPE Pos_Hits
 Xpos AS _BYTE
 Ypos AS _BYTE
 Orent AS _BYTE
 Hits AS _BYTE
 sunk AS _BYTE
 placed AS _BYTE
END TYPE

TYPE ships
 Carrier AS Pos_Hits
 Battle AS Pos_Hits
 Destroyer AS Pos_Hits
 Submarine AS Pos_Hits
 Patrol AS Pos_Hits
END TYPE

TYPE Ship_Board_Offsets
 Board_VX AS _BYTE
 Board_VY AS _BYTE
 Board_HX AS _BYTE
 Board_HY AS _BYTE
 RedBoard_VX AS INTEGER
 RedBoard_VY AS INTEGER
 RedBoard_HX AS INTEGER
 RedBoard_HY AS INTEGER
 ShipYard_X AS INTEGER
 ShipYard_Y AS INTEGER
END TYPE

TYPE Networking
 Host AS LONG 'host ID
 Client AS LONG 'Client ID
 Users AS _BYTE 'Clients Connected, 2 max
 Ready AS _BYTE 'Opponent has placed ships
 X AS _BYTE 'Opponents shot X location
 Y AS _BYTE 'Opponents shot Y location
END TYPE

TYPE Client
 PingTime AS LONG
 Id AS LONG
END TYPE

TYPE Game_Data
 PlayerDead AS _BYTE
 OpponentDead AS _BYTE
 GameOver AS _BYTE
 WhoIsUp AS _BYTE
 NetWork AS Networking
 Mode AS _BYTE
 Debug AS _BYTE
END TYPE

DIM SHARED Board(10, 10, 2) AS _BYTE '1-player layout\OPPONENT shots 2-player shots
DIM SHARED Fleet(2) AS ships, Offs(5) AS Ship_Board_Offsets, G AS Game_Data
DIM SHARED Ship(10) AS Pos_Hits '1-5 player 6-10 OPPONENT
DIM SHARED ShipName$(5) 'names of ship types
DIM SHARED Layer(10) AS _UNSIGNED LONG, Starts AS _BYTE, FFX(12) AS _UNSIGNED LONG
DIM SHARED User(2) AS Client, Message$, Listen&, Cancel%%

CONST CARRIER = 1, BATTLESHIP = 2, DESTROYER = 3, SUBMARINE = 4, PTBOAT = 5
CONST TRUE = -1, FALSE = NOT TRUE, HORZ = 11, VERT = 12
CONST MIX = 1, TITLE = 2, SHEET = 3, SHIPS = 4, SHOTS = 5, BOARD = 6, PEGS = 7, MENU = 8, LAN = 9
CONST PLAYER = 1, OPPONENT = 2, LANCLIENT = 3
CONST BlueBoard~& = _RGBA32(7, 15, 212, 48)
CONST RedBoard~& = _RGBA32(212, 15, 7, 48)
CONST YellowSelect~& = _RGBA32(212, 192, 7, 80)
CONST HIT = -1, MISS = -2, BAD = 4


'ship yard horzontal offsets
ShipYardOffsets:
DATA 68,316,68,343,68,367,68,393,66,416
ShipBoardOffsets:
DATA 57,55,58,57,55,58,56,60,55,58
DATA 54,58,56,57,57,55,59,57,58,55
ShipBoardOffsetsRed:
DATA 347,55,347,57,343,58,345,60,343,58
DATA 343,58,344,57,345,55,347,57,346,55
ShipNames:
DATA "Carrier","Battle Ship","Destroyer","Submarine","PT Boat"

Listen& = _FREETIMER
ON TIMER(Listen&, .1) MessageCheck 'timer for Host status.

SCREEN _NEWIMAGE(640, 480, 32)
INIT 'load screens, load data, set randomizer


'Title Screen----------------------
_PUTIMAGE , Layer(TITLE), LayerD&
_DELAY 5.5
'----------------------------------
G.Debug = FALSE

SetUpGameBoard
MainMenu
END



SUB MainMenu
 'Game Menu-------------------------
 _FONT FFX(2), Layer(MIX)
 ExitFlag%% = FALSE

 DO
  _PUTIMAGE , Layer(MENU), Layer(MIX)
  IF G.Mode = LAN THEN
   ChangeColor _RGB32(248, 48, 64), Layer(MIX)
   _PRINTSTRING (0, 450), "CONNECTED", Layer(MIX)
  END IF
  ChangeColor _RGB32(48, 48, 64), Layer(MIX) 'BASE COLOR
  _PRINTSTRING (280, 150), "PLAY GAME", Layer(MIX)
  IF G.Mode <> LAN THEN
   _PRINTSTRING (280, 180), "START NETWORK GAME", Layer(MIX)
  ELSE
   _PRINTSTRING (280, 180), "STOP NETWORK GAME", Layer(MIX)
  END IF
  _PRINTSTRING (280, 210), "JOIN NETWORK GAME", Layer(MIX)
  _PRINTSTRING (280, 240), "INSTRUCTION!", Layer(MIX)
  _PRINTSTRING (280, 270), "QUIT GAME", Layer(MIX)

  IF over%% THEN 'hi-lite option mouse is over
   ChangeColor _RGB32(248, 248, 48), Layer(MIX) 'Hover color
   SELECT CASE over%%
    CASE 1
     _PRINTSTRING (280, 150), "PLAY GAME", Layer(MIX)
    CASE 2
     IF G.Mode <> LAN THEN
      _PRINTSTRING (280, 180), "START NETWORK GAME", Layer(MIX)
     ELSE
      _PRINTSTRING (280, 180), "STOP NETWORK GAME", Layer(MIX)
     END IF
    CASE 3
     _PRINTSTRING (280, 210), "JOIN NETWORK GAME", Layer(MIX)
    CASE 4
     _PRINTSTRING (280, 240), "INSTRUCTION!", Layer(MIX)
    CASE 5
     _PRINTSTRING (280, 270), "QUIT GAME", Layer(MIX)
   END SELECT
  END IF

  IF _MOUSEBUTTON(1) THEN 'player clicked on option
   SELECT CASE over%%
    CASE 1 'play the game
     DeployFleet
     AutoPlaceShips OPPONENT
     ClearArea
     GamePlay
     _FONT FFX(2), Layer(MIX)
    CASE 2 'start host for network game
     IF G.Mode = LAN THEN
      'close down host and host's client reset game to normal mode
      'turn off network listening timer
      CLOSE #6
      TIMER(Listen&) OFF
      CLOSE #G.NetWork.Client
      CLOSE #G.NetWork.Host
      G.Mode = FALSE
     ELSE
      '      IF G.Debug THEN OPEN "Debughost.txt" FOR OUTPUT AS #6
      CreateNetworkGame
     END IF
     UpDate%% = TRUE
    CASE 3 'find network game on server list and join
     '     IF G.Debug THEN OPEN "debugclient.txt" FOR OUTPUT AS #6
     JoinNetworkGame
     IF NOT Cancel%% THEN
      'game is now in network mode
      '-------------------------------------------
      'start game directly
      DeployFleet
      ClearArea
      GamePlay
     ELSE
      Cancel%% = FALSE 'player hit ESC
     END IF
     TIMER(Listen&) OFF
     CLOSE #G.NetWork.Client
     _FONT FFX(2), Layer(MIX)
    CASE 4 'instructions! heck its point and click ppl!
     Instruction
    CASE 5 'quit game
     ExitFlag%% = TRUE
   END SELECT
   'trap mouse button down
   DO: null = _MOUSEINPUT: _DELAY .025: LOOP WHILE _MOUSEBUTTON(1)
  END IF

  _PUTIMAGE , Layer(MIX), Layer(0)

  DO
   _DELAY .025
   IF INKEY$ = CHR$(27) THEN ExitFlag%% = TRUE
  LOOP UNTIL _MOUSEINPUT OR ExitFlag%% OR UpDate%%

  UpDate%% = FALSE
  x% = _MOUSEX: y% = _MOUSEY
  IF x% > 280 AND x% < 630 THEN 'if mouse is in correct X region
   IF y% > 150 AND y% < 300 THEN 'if mouse is in correct Y region
    over%% = (y% - 150) \ 30 + 1
   END IF
  ELSE 'off menu region
   over%% = 0
  END IF
  DO: LOOP WHILE _MOUSEINPUT
 LOOP UNTIL ExitFlag%%

 ExitFlag%% = FALSE 'reset flag
 ChangeColor &HFFFFFFFF, Layer(MIX)
 _FONT 16
 '----------------------------------
END SUB

FUNCTION StartHost (port%)
 IF port% = 0 THEN default% = 1979 ELSE default% = port%
 ID$ = "TCP/IP:" + LTRIM$(STR$(default%))
 HostID& = _OPENHOST(ID$) 'begin new host
 Result = HostID&
 StartHost = Result
END FUNCTION

SUB MessageCheck
 'catch user connection----------------
 'only if HOST
 IF G.Mode = LAN THEN
  newclient = _OPENCONNECTION(G.NetWork.Host) ' receive any new connection
  IF newclient THEN
   G.NetWork.Users = G.NetWork.Users + 1
   User(G.NetWork.Users).Id = newclient
   IF G.Debug THEN PRINT #6, "add:" + STR$(newclient)
  END IF
 END IF
 '--------------------------------------
 'Listen for communication from Players-
 IF G.Mode = LAN THEN 'host game only listens for player 2
  IF G.NetWork.Users = 2 THEN 'only listen once hosts has both users
   GET #User(2).Id, , Message$
   IF G.Debug AND Message$ <> "" THEN PRINT #6, "REC:" + STR$(User(I%%).Id) + ":" + Message$
  END IF
 ELSE 'while player two just listens
  GET #G.NetWork.Client, , Message$
  IF G.Debug AND Message$ <> "" THEN PRINT #6, "REC:" + STR$(User(I%%).Id) + ":" + Message$
 END IF
 '--------------------------------------
 IF Message$ <> "" THEN ProcessMessage
END SUB

SUB ProcessMessage
 SELECT CASE LEFT$(Message$, 5)
  CASE "[SHP]" 'ship xy and orentation data
   txt$ = MID$(Message$, 6, 30)
   FOR i%% = 6 TO 10
    x%% = VAL(MID$(txt$, 1, 2))
    y%% = VAL(MID$(txt$, 3, 2))
    o%% = VAL(MID$(txt$, 5, 2))
    txt$ = MID$(txt$, 7)
    Ship(i%%).Xpos = x%%
    Ship(i%%).Ypos = y%%
    Ship(i%%).Orent = o%%
    PlaceShipOnBoard i%%
   NEXT i%%
   G.NetWork.Ready = TRUE
  CASE "[SHT]" 'players Shot xy data
   txt$ = MID$(Message$, 6, 4)
   x%% = VAL(MID$(txt$, 1, 2))
   y%% = VAL(MID$(txt$, 3, 2))
   G.NetWork.X = x%%
   G.NetWork.Y = y%%
  CASE "[FST]" 'who goes first number chance
   'go ahead and use x value for this.
   G.NetWork.X = VAL(MID$(Message$, 6, 2))
  CASE "[PKN]" 'who goes first number
   G.NetWork.Y = VAL(MID$(Message$, 6, 2))
 END SELECT
END SUB

FUNCTION ConnectClient (port%, IPA$)
 IF port% = 0 THEN default% = 1979 ELSE default% = port%
 IF IPA$ = "0" THEN IP$ = ":localhost" ELSE IP$ = ":" + IPA$
 ID$ = "TCP/IP:" + LTRIM$(STR$(default%)) + IP$
 connection& = _OPENCLIENT(ID$) ' Attempt to connect to local host as a client
 Result = connection&
 IF G.Debug THEN PRINT #6, ID$ + " " + STR$(Result)
 ConnectClient = Result
END FUNCTION

SUB SendMessage
 IF G.Debug THEN PRINT #6, "SND:" + STR$(User(2).Id) + ":" + STR$(G.Mode)
 IF G.Mode = LAN THEN
  IF G.Debug THEN PRINT #6, "SND:" + STR$(User(2).Id) + ":" + Message$
  PUT #User(2).Id, , Message$
 ELSE
  IF G.Debug THEN PRINT #6, "SND:" + STR$(G.NetWork.Client) + ":" + Message$
  PUT #G.NetWork.Client, , Message$
 END IF
 Message$ = ""
END SUB

SUB AutoPlaceShips (Who%%)
 IF Who%% = PLAYER THEN A%% = 0 ELSE A%% = 5
 FOR i%% = 1 + A%% TO 5 + A%% 'take each ship starting with Carrier
  limit! = TIMER
  DO: Good%% = FALSE
   x%% = INT(RND * 10) + 1 'pick a spot and orentation
   y%% = INT(RND * 10) + 1
   IF INT(RND * 100) + 1 > 50 THEN o%% = HORZ ELSE o%% = VERT
   IF CheckShipPos(x%%, y%%, o%%, i%%) THEN Good%% = TRUE 'check that it fits and doesn't overlap
   IF TIMER > limit! + .5 THEN PRINT "AUTO PLACE ERROR, TIME EXCEEDED!": END
  LOOP UNTIL Good%%
  Ship(i%%).Xpos = x%%
  Ship(i%%).Ypos = y%%
  Ship(i%%).Orent = o%%
  PlaceShipOnBoard (i%%)
 NEXT i%%
END SUB

SUB ChangeColor (value~&, id~&)
 'change text color(value~&) on specified layer(id~&)
 old~& = _DEST
 _DEST id~&
 COLOR value~&
 _DEST old~&
END SUB

FUNCTION CheckShipPos (xt%%, yt%%, ot%%, tt%%)
 'lets not change a variable by accident
 x%% = xt%%: y%% = yt%%: o%% = ot%%: t%% = tt%%

 IF t%% > 5 THEN w%% = 2: t%% = t%% - 5 ELSE w%% = 1 '>5 OPPONENT ships
 result%% = TRUE
 SELECT CASE t%% 'first check to see if ship will fit on board
  CASE CARRIER
   IF o%% = HORZ AND x%% > 6 THEN result%% = FALSE
   IF o%% = VERT AND y%% > 6 THEN result%% = FALSE
  CASE BATTLESHIP
   IF o%% = HORZ AND x%% > 7 THEN result%% = FALSE
   IF o%% = VERT AND y%% > 7 THEN result%% = FALSE
  CASE DESTROYER, SUBMARINE
   IF o%% = HORZ AND x%% > 8 THEN result%% = FALSE
   IF o%% = VERT AND y%% > 8 THEN result%% = FALSE
  CASE PTBOAT
   IF o%% = HORZ AND x%% > 9 THEN result%% = FALSE
   IF o%% = VERT AND y%% > 9 THEN result%% = FALSE
 END SELECT
 IF result%% THEN 'if fit test passed make sure no ships in way
  SELECT CASE t%%
   CASE CARRIER
    IF o%% = HORZ THEN
     FOR i%% = 0 TO 4
      IF Board(x%% + i%%, y%%, w%%) THEN result%% = FALSE: i%% = 5
     NEXT i%%
    END IF
    IF o%% = VERT THEN
     FOR i%% = 0 TO 4
      IF Board(x%%, y%% + i%%, w%%) THEN result%% = FALSE: i%% = 5
     NEXT i%%
    END IF
   CASE BATTLESHIP
    IF o%% = HORZ THEN
     FOR i%% = 0 TO 3
      IF Board(x%% + i%%, y%%, w%%) THEN result%% = FALSE: i%% = 5
     NEXT i%%
    END IF
    IF o%% = VERT THEN
     FOR i%% = 0 TO 3
      IF Board(x%%, y%% + i%%, w%%) THEN result%% = FALSE: i%% = 5
     NEXT i%%
    END IF
   CASE DESTROYER, SUBMARINE
    IF o%% = HORZ THEN
     FOR i%% = 0 TO 2
      IF Board(x%% + i%%, y%%, w%%) THEN result%% = FALSE: i%% = 5
     NEXT i%%
    END IF
    IF o%% = VERT THEN
     FOR i%% = 0 TO 2
      IF Board(x%%, y%% + i%%, w%%) THEN result%% = FALSE: i%% = 5
     NEXT i%%
    END IF
   CASE PTBOAT
    IF o%% = HORZ THEN
     FOR i%% = 0 TO 1
      IF Board(x%% + i%%, y%%, w%%) THEN result%% = FALSE: i%% = 5
     NEXT i%%
    END IF
    IF o%% = VERT THEN
     FOR i%% = 0 TO 1
      IF Board(x%%, y%% + i%%, w%%) THEN result%% = FALSE: i%% = 5
     NEXT i%%
    END IF
  END SELECT
 END IF
 CheckShipPos = result%%
END FUNCTION

SUB checkships
 STATIC Known(10) AS _BYTE
 'check for sunk ship on player
 G.PlayerDead = TRUE
 FOR i%% = 1 TO 5
  IF Ship(i%%).sunk AND (NOT Known(i%%)) THEN
   MessageHandler "Opponent Sunk players " + ShipName$(i%%) + " !"
   _DELAY .75
   Known(i%%) = TRUE
  END IF
  IF Ship(i%%).sunk = FALSE THEN G.PlayerDead = FALSE
 NEXT i%%
 'check for sunk ship on opponent
 G.OpponentDead = TRUE
 FOR i%% = 6 TO 10
  IF Ship(i%%).sunk AND (NOT Known(i%%)) THEN
   MessageHandler "Player Sunk Opponents " + ShipName$(i%% - 5) + " !"
   _DELAY .75
   Known(i%%) = TRUE
  END IF
  IF Ship(i%%).sunk = FALSE THEN G.OpponentDead = FALSE
 NEXT i%%
 IF G.PlayerDead OR G.OpponentDead THEN G.GameOver = TRUE
END SUB

SUB ClearArea
 'Clear deploy information area---------------
 _DEST Layer(BOARD)
 LINE (0, 300)-(639, 479), _RGB32(0, 0, 0), BF
 _DEST Layer(0)
 _DEST Layer(SHIPS)
 LINE (0, 300)-(639, 479), _RGB32(0, 0, 0), BF
 _DEST Layer(0)
 _PUTIMAGE , Layer(BOARD), Layer(MIX)
 _PUTIMAGE , Layer(SHIPS), Layer(MIX)
 _PUTIMAGE , Layer(MIX), Layer(0)
 '--------------------------------------------
END SUB

SUB ClearLayer (id%%)
 old& = _DEST
 _DEST Layer(id%%)
 CLS
 _DEST old&
END SUB

SUB ComputerShot
 DO: Good%% = FALSE 'run until an unfired upon area is found
  x%% = INT(RND * 10) + 1
  y%% = INT(RND * 10) + 1
  IF Board(x%%, y%%, 1) >= 0 THEN Good%% = TRUE
 LOOP UNTIL Good%%
 MessageHandler "Computer fires at " + CHR$(64 + y%%) + STR$(x%%)
 _DELAY .5
 SELECT CASE SendShot(x%%, y%%, OPPONENT)
  CASE HIT 'Computer hits players ship
   MessageHandler "Computer Hits!"
   checkships
  CASE MISS 'Computer missed players ship
   MessageHandler "Computer Misses"
  CASE BAD 'Computer already fired upon this space ERROR
   MessageHandler "Computer has been Hitting the juice again, fired an error"
 END SELECT
 _DELAY .5
END SUB

SUB DisplayShip (X%, Y%, ID%%, Orentation%%, LayerD&)
 SELECT CASE ID%%
  CASE CARRIER
   IF Orentation%% = HORZ THEN _PUTIMAGE (X%, Y%), Layer(SHEET), LayerD&, (500, 277)-(611, 299) ELSE _PUTIMAGE (X%, Y%), Layer(SHEET), LayerD&, (592, 165)-(614, 276)
  CASE BATTLESHIP
   IF Orentation%% = HORZ THEN _PUTIMAGE (X%, Y%), Layer(SHEET), LayerD&, (500, 303)-(588, 321) ELSE _PUTIMAGE (X%, Y%), Layer(SHEET), LayerD&, (570, 165)-(589, 253)
  CASE DESTROYER
   IF Orentation%% = HORZ THEN _PUTIMAGE (X%, Y%), Layer(SHEET), LayerD&, (500, 324)-(570, 341) ELSE _PUTIMAGE (X%, Y%), Layer(SHEET), LayerD&, (551, 165)-(568, 235)
  CASE SUBMARINE
   IF Orentation%% = HORZ THEN _PUTIMAGE (X%, Y%), Layer(SHEET), LayerD&, (500, 344)-(568, 357) ELSE _PUTIMAGE (X%, Y%), Layer(SHEET), LayerD&, (534, 165)-(548, 233)
  CASE PTBOAT
   IF Orentation%% = HORZ THEN _PUTIMAGE (X%, Y%), Layer(SHEET), LayerD&, (500, 360)-(546, 375) ELSE _PUTIMAGE (X%, Y%), Layer(SHEET), LayerD&, (516, 165)-(531, 211)
 END SELECT
END SUB

SUB GamePlay
 'start game----------------------------------
 WhoIsFirst 'find who gets to shoot first!
 DO
  IF G.WhoIsUp = PLAYER THEN
   'shooting routine PLAYER----------------------
   DO: ShotFired%% = FALSE
    'mix layers and display-----------------
    _PUTIMAGE , Layer(BOARD), Layer(MIX)
    _PUTIMAGE , Layer(SHIPS), Layer(MIX)
    _PUTIMAGE , Layer(PEGS), Layer(MIX)
    _PUTIMAGE (0, 0), Layer(MIX), Layer(0), (0, 0)-(639, 300)
    '---------------------------------------

    x% = _MOUSEX: y% = _MOUSEY 'get mouse location

    IF x% > 344 AND y% > 54 AND x% < 582 AND y% < 294 THEN 'mouse over enemy board
     'highlite grid block that mouse is over(grid blocks are 22x22[24x24WL])
     hx%% = ((x% - 344) \ 24) + 1: hy%% = ((y% - 54) \ 24) + 1
     LINE (344 + ((hx%% - 1) * 24), 54 + ((hy%% - 1) * 24))-(367 + ((hx%% - 1) * 24), 77 + ((hy%% - 1) * 24)), YellowSelect~&, BF
    END IF

    'debug information ----------------------
    LOCATE 1, 1: PRINT CHR$(64 + hy%%); hx%%
    '----------------------------------------
    IF G.GameOver = FALSE THEN
     'Main input loop------------------------
     DO: _DELAY .025
      KBD$ = INKEY$
      SELECT CASE KBD$
       CASE CHR$(27)
        ExitFlag%% = TRUE
        G.GameOver = TRUE
      END SELECT
     LOOP UNTIL _MOUSEINPUT OR ExitFlag%%
     '---------------------------------------
     'Player shoots----------------------------
     IF _MOUSEBUTTON(1) THEN
      IF x% > 344 AND y% > 54 AND x% < 582 AND y% < 294 THEN 'only shoot if player is over shot board.
       MessageHandler "Player Fires at: " + CHR$(64 + hy%%) + STR$(hx%%)
       _DELAY .5
       IF G.Mode THEN
        IF hx%% < 10 THEN m$ = "0" + LTRIM$(STR$(hx%%)) ELSE m$ = LTRIM$(STR$(hx%%))
        Message$ = "[SHT]" + m$
        IF hy%% < 10 THEN m$ = "0" + LTRIM$(STR$(hy%%)) ELSE m$ = LTRIM$(STR$(hy%%))
        Message$ = Message$ + m$
        SendMessage
       END IF
       SELECT CASE SendShot(hx%%, hy%%, PLAYER)
        CASE HIT%% 'player hit enemy  ship
         MessageHandler "Player Hits!"
         ShotFired%% = TRUE
         checkships
        CASE MISS%% 'player missed enemy ship
         MessageHandler "Player Misses"
         ShotFired%% = TRUE
        CASE BAD%% 'player already fired upon this space
         MessageHandler "Space Already Fired at, pick again"
       END SELECT
      END IF
      _DELAY 1.5
     END IF
     '-----------------------------------------
    ELSE
     ExitFlag%% = TRUE
     G.GameOver = TRUE
    END IF
    DO: LOOP WHILE _MOUSEINPUT
   LOOP UNTIL ShotFired%% OR G.GameOver

  ELSEIF G.WhoIsUp = OPPONENT THEN 'opponents turn to shoot!
   'mix layers and display-----------------
   _PUTIMAGE , Layer(BOARD), Layer(MIX)
   _PUTIMAGE , Layer(SHIPS), Layer(MIX)
   _PUTIMAGE , Layer(PEGS), Layer(MIX)
   _PUTIMAGE (0, 0), Layer(MIX), Layer(0), (0, 0)-(639, 300)
   '---------------------------------------
   IF G.Mode THEN OpponentShot ELSE ComputerShot
   IF G.GameOver THEN ExitFlag%% = TRUE
  END IF
  'whos turn is it now?
  IF G.WhoIsUp = PLAYER THEN G.WhoIsUp = OPPONENT ELSE G.WhoIsUp = PLAYER
 LOOP UNTIL ExitFlag%%

 'dumpboard
 IF G.PlayerDead THEN MessageHandler "You have lost this round."
 IF G.OpponentDead THEN MessageHandler "Congratulations You are Victorious!"
 IF NOT G.PlayerDead AND NOT G.OpponentDead THEN MessageHandler "Game quit..."
 MessageHandler "Press any key to return to menu"
 DO: LOOP WHILE INKEY$ = ""
END SUB

SUB HitShip (id%%)
 'ID%%-number of the ship, 1-5 player 6-10 opponent
 Ship(id%%).Hits = Ship(id%%).Hits + 1
 SELECT CASE id%%
  CASE CARRIER, CARRIER + 5
   IF Ship(id%%).Hits = 5 THEN Ship(id%%).sunk = TRUE
  CASE BATTLESHIP, BATTLESHIP + 5
   IF Ship(id%%).Hits = 4 THEN Ship(id%%).sunk = TRUE
  CASE DESTROYER, DESTROYER + 5
   IF Ship(id%%).Hits = 3 THEN Ship(id%%).sunk = TRUE
  CASE SUBMARINE, SUBMARINE + 5
   IF Ship(id%%).Hits = 3 THEN Ship(id%%).sunk = TRUE
  CASE PTBOAT, PTBOAT + 5
   IF Ship(id%%).Hits = 2 THEN Ship(id%%).sunk = TRUE
 END SELECT
END SUB

SUB INIT
 DIM Size(64) AS LONG, FOffset&(64)

 OPEN "battleship.gfx" FOR BINARY AS #1
 GET #1, , c~%% 'number of records
 FOR w% = 1 TO c~%%
  GET #1, , FOffset&(w%)
  GET #1, , Size(w%)
  FOffset&(w%) = FOffset&(w%) + 1
 NEXT

 Layer(0) = _DISPLAY
 Layer(MIX) = _NEWIMAGE(640, 480, 32) 'composite layer
 Layer(TITLE) = LoadGFX&(FOffset&(1), Size(1))
 Layer(SHEET) = LoadGFX&(FOffset&(2), Size(2))
 Layer(SHIPS) = _NEWIMAGE(640, 480, 32)
 Layer(SHOTS) = _NEWIMAGE(640, 480, 32)
 Layer(BOARD) = _NEWIMAGE(640, 480, 32)
 Layer(PEGS) = _NEWIMAGE(640, 480, 32)
 Layer(MENU) = LoadGFX&(FOffset&(3), Size(3))
 Layer(LAN) = LoadGFX&(FOffset&(4), Size(4)) '_LOADIMAGE("Networking.bmp", 32)

 FFX(1) = LoadFFX&(FOffset&(5), Size(5), 30) '_LOADFONT("gunmetl.ttf", 30, "monospace")
 FFX(2) = LoadFFX&(FOffset&(6), Size(6), 18) '_LOADFONT("ARGEBL.ttf", 18, "monospace")
 FFX(3) = LoadFFX&(FOffset&(7), Size(7), 18) '_LOADFONT("TechnoLCD.ttf", 18, "monospace")
 FFX(4) = LoadFFX&(FOffset&(8), Size(8), 24) '_LOADFONT("TechnicznaPomocR.ttf", 24, "monospace")
 FFX(5) = LoadFFX&(FOffset&(5), Size(5), 48) '_LOADFONT("gunmetl.ttf", 30, "monospace")
 FFX(6) = LoadFFX&(FOffset&(5), Size(5), 24) '_LOADFONT("gunmetl.ttf", 30, "monospace")

 _PRINTMODE _KEEPBACKGROUND , Layer(MIX)
 _PRINTMODE _KEEPBACKGROUND , Layer(LAN)

 ClearLayer BOARD
 _CLEARCOLOR _RGB32(0, 0, 0), Layer(SHEET)
 _CLEARCOLOR _RGB32(0, 0, 0), Layer(SHIPS)
 _CLEARCOLOR _RGB32(0, 0, 0), Layer(SHOTS)
 _CLEARCOLOR _RGB32(0, 0, 0), Layer(PEGS)

 LoadData

 RANDOMIZE TIMER
 CLOSE #1
 IF _FILEEXISTS("temp.dat") THEN KILL "temp.dat" 'make sure we clean up temp files.
 _SCREENMOVE 25, 25
 _TITLE "BattleShip 64 V0.7A"
END SUB

SUB ItsAHit (x%%, y%%, Who%%)
 'who%%- which player board to add hit 1-PLAYER, 2-OPPONENT
 'put red peg in board and tally hits to ships
 HitShip Board(x%%, y%%, Who%%) + ((Who%% - 1) * 5)
 Board(x%%, y%%, Who%%) = HIT
END SUB

SUB ItsAMiss (x%%, y%%, Who%%)
 'who%%- which player board to add hit 1-PLAYER, 2-OPPONENT
 'put white peg in board
 Board(x%%, y%%, Who%%) = MISS
END SUB

SUB LoadData
 RESTORE ShipYardOffsets
 FOR i%% = 1 TO 5
  READ Offs(i%%).ShipYard_X
  READ Offs(i%%).ShipYard_Y
 NEXT i%%
 RESTORE ShipBoardOffsets
 FOR i%% = 1 TO 5
  READ Offs(i%%).Board_HX
  READ Offs(i%%).Board_HY
 NEXT i%%
 FOR i%% = 1 TO 5
  READ Offs(i%%).Board_VX
  READ Offs(i%%).Board_VY
 NEXT i%%
 RESTORE ShipBoardOffsetsRed
 FOR i%% = 1 TO 5
  READ Offs(i%%).RedBoard_HX
  READ Offs(i%%).RedBoard_HY
 NEXT i%%
 FOR i%% = 1 TO 5
  READ Offs(i%%).RedBoard_VX
  READ Offs(i%%).RedBoard_VY
 NEXT i%%
 RESTORE ShipNames
 FOR i%% = 1 TO 5
  READ ShipName$(i%%)
 NEXT i%%
END SUB

FUNCTION LoadGFX& (Foff&, Size&)
 IF _FILEEXISTS("temp.dat") THEN KILL "temp.dat"
 OPEN "temp.dat" FOR BINARY AS #3
 dat$ = SPACE$(Size&)
 GET #1, Foff&, dat$
 PUT #3, , dat$
 CLOSE #3
 LoadGFX& = _LOADIMAGE("temp.dat", 32)
END FUNCTION

FUNCTION LoadFFX& (Foff&, Size&, Fize%%)
 IF _FILEEXISTS("temp.dat") THEN KILL "temp.dat"
 OPEN "temp.dat" FOR BINARY AS #3
 dat$ = SPACE$(Size&)
 GET #1, Foff&, dat$
 PUT #3, , dat$
 CLOSE #3
 LoadFFX& = _LOADFONT("temp.dat", Fize%%, "monospace")
END FUNCTION

SUB MessageHandler (txt$)
 'define message area
 VIEW PRINT 20 TO 25
 'display message
 LOCATE 25, 1: PRINT txt$
 'restore screen area
 VIEW PRINT
END SUB

SUB PlaceShipOnBoard (id%%)
 'w%%- Which board to place ship 1-player 2-Opponent
 'o%%= ships Orentation VERT or HORZ
 'idx%%- Ident of ship to place CARRIER to PTBOAT

 IF id%% <= 5 THEN 'players ships
  w%% = 1: idx%% = id%%
 ELSE 'OPPONENT ships
  w%% = 2: idx%% = id%% - 5 'correction for Enemy ships 6-10
 END IF
 o%% = Ship(id%%).Orent

 SELECT CASE idx%%
  CASE CARRIER
   IF o%% = HORZ THEN FOR i%% = 0 TO 4: Board(Ship(id%%).Xpos + i%%, Ship(id%%).Ypos, w%%) = CARRIER: NEXT i%%
   IF o%% = VERT THEN FOR i%% = 0 TO 4: Board(Ship(id%%).Xpos, Ship(id%%).Ypos + i%%, w%%) = CARRIER: NEXT i%%
  CASE BATTLESHIP
   IF o%% = HORZ THEN FOR i%% = 0 TO 3: Board(Ship(id%%).Xpos + i%%, Ship(id%%).Ypos, w%%) = BATTLESHIP: NEXT i%%
   IF o%% = VERT THEN FOR i%% = 0 TO 3: Board(Ship(id%%).Xpos, Ship(id%%).Ypos + i%%, w%%) = BATTLESHIP: NEXT i%%
  CASE DESTROYER
   IF o%% = HORZ THEN FOR i%% = 0 TO 2: Board(Ship(id%%).Xpos + i%%, Ship(id%%).Ypos, w%%) = DESTROYER: NEXT i%%
   IF o%% = VERT THEN FOR i%% = 0 TO 2: Board(Ship(id%%).Xpos, Ship(id%%).Ypos + i%%, w%%) = DESTROYER: NEXT i%%
  CASE SUBMARINE
   IF o%% = HORZ THEN FOR i%% = 0 TO 2: Board(Ship(id%%).Xpos + i%%, Ship(id%%).Ypos, w%%) = SUBMARINE: NEXT i%%
   IF o%% = VERT THEN FOR i%% = 0 TO 2: Board(Ship(id%%).Xpos, Ship(id%%).Ypos + i%%, w%%) = SUBMARINE: NEXT i%%
  CASE PTBOAT
   IF o%% = HORZ THEN FOR i%% = 0 TO 1: Board(Ship(id%%).Xpos + i%%, Ship(id%%).Ypos, w%%) = PTBOAT: NEXT i%%
   IF o%% = VERT THEN FOR i%% = 0 TO 1: Board(Ship(id%%).Xpos, Ship(id%%).Ypos + i%%, w%%) = PTBOAT: NEXT i%%
 END SELECT
END SUB

SUB ResetBoard
 FOR iz%% = 0 TO 2
  FOR ix%% = 0 TO 10
   FOR iy%% = 0 TO 10
    Board(ix%%, iy%%, iz%%) = FALSE
   NEXT iy%%
  NEXT ix%%
 NEXT iz%%
END SUB

FUNCTION SendShot (x%%, y%%, Who%%)
 IF Who%% = PLAYER THEN
  'Player shooting, check enemy board
  IF Board(x%%, y%%, OPPONENT) > 0 THEN
   ItsAHit x%%, y%%, OPPONENT
   Result%% = HIT
  ELSEIF Board(x%%, y%%, OPPONENT) < 0 THEN 'already hit or miss
   Result%% = BAD
  ELSE 'space is empty so its a miss
   ItsAMiss x%%, y%%, OPPONENT
   Result%% = MISS
  END IF
 ELSE
  'Opponent shooting, check player board
  IF Board(x%%, y%%, PLAYER) > 0 THEN
   ItsAHit x%%, y%%, PLAYER
   Result%% = HIT
  ELSEIF Board(x%%, y%%, PLAYER) < 0 THEN 'already hit or miss
   Result%% = BAD
  ELSE 'space is empty so its a miss
   ItsAMiss x%%, y%%, PLAYER
   Result%% = MISS
  END IF
 END IF
 UpdatePegLayer
 SendShot = Result%%
END SUB

SUB SetUpGameBoard
 _DEST Layer(BOARD)
 _PUTIMAGE (32, 32), Layer(SHEET), Layer(BOARD), (0, 0)-(262, 262)
 _PUTIMAGE (320, 32), Layer(SHEET), Layer(BOARD), (0, 0)-(262, 262)
 LINE (32, 32)-(294, 294), BlueBoard~&, BF
 LINE (320, 32)-(582, 294), RedBoard~&, BF
 _PUTIMAGE , Layer(BOARD), _DISPLAY

 _PRINTSTRING (64, 16), "Your fleet"
 _PRINTSTRING (352, 16), "Enemy fleet"
 _DEST Layer(0)
END SUB

SUB ShowShips (Who%%)
 IF Who%% = PLAYER THEN
  FOR i%% = 1 TO 5
   IF Ship(i%%).Orent = HORZ THEN
    DisplayShip Offs(i%%).Board_HX + (Ship(i%%).Xpos - 1) * 24, Offs(i%%).Board_HY + (Ship(i%%).Ypos - 1) * 24, i%%, Ship(i%%).Orent, Layer(SHIPS) 'display ships in Board area
   ELSE
    DisplayShip Offs(i%%).Board_VX + (Ship(i%%).Xpos - 1) * 24, Offs(i%%).Board_VY + (Ship(i%%).Ypos - 1) * 24, i%%, Ship(i%%).Orent, Layer(SHIPS) 'display ships in Board area
   END IF
  NEXT i%%
 ELSE
  FOR i%% = 6 TO 10
   IF Ship(i%%).Orent = VERT THEN
    DisplayShip Offs(i%% - 5).RedBoard_VX + (Ship(i%%).Xpos - 1) * 24, Offs(i%% - 5).RedBoard_VY + (Ship(i%%).Ypos - 1) * 24, i%% - 5, Ship(i%%).Orent, Layer(SHIPS) 'display ships in Board area
   ELSE
    DisplayShip Offs(i%% - 5).RedBoard_HX + (Ship(i%%).Xpos - 1) * 24, Offs(i%% - 5).RedBoard_HY + (Ship(i%%).Ypos - 1) * 24, i%% - 5, Ship(i%%).Orent, Layer(SHIPS) 'display ships in Board area
   END IF
  NEXT i%%
 END IF
END SUB

SUB UpdatePegLayer
 FOR z%% = 1 TO 2
  IF z%% = 1 THEN ofx% = 55: ofy% = 55 ELSE ofx% = 343: ofy% = 55
  FOR y%% = 1 TO 10
   FOR x%% = 1 TO 10
    SELECT CASE Board(x%%, y%%, z%%)
     CASE HIT
      _PUTIMAGE (ofx% + (x%% - 1) * 24, ofy% + (y%% - 1) * 24), Layer(SHEET), Layer(PEGS), (305, 144)-(327, 166)
     CASE MISS
      _PUTIMAGE (ofx% + (x%% - 1) * 24, ofy% + (y%% - 1) * 24), Layer(SHEET), Layer(PEGS), (329, 144)-(350, 166)
    END SELECT
   NEXT x%%
  NEXT y%%
 NEXT z%%
END SUB

SUB WhoIsFirst
 ' Pick Who Goes first------------------------
 starter%% = INT(RND * 100) + 1
 LOCATE 20, 1: INPUT "Pick Number 1-100"; P%%

 IF G.Mode = FALSE THEN 'if not a network game
  computer%% = INT(RND * 100) + 1

 ELSE
  'if game is network then------------------------------------------------------------
  IF G.Mode = LAN THEN 'if this program is host game then send pick to player2
   IF starter%% < 10 THEN m$ = "0" + LTRIM$(STR$(starter%%)) ELSE m$ = LTRIM$(STR$(starter%%))
   Message$ = "[PKN]" + m$
   SendMessage
 
  ELSEIF G.Mode = LANCLIENT THEN 'if this program is player 2 then wait for number
   PRINT "Awaiting Pick Number..."
   DO
    _DELAY .005
   LOOP UNTIL G.NetWork.Y
   starter%% = G.NetWork.Y
   G.NetWork.Y = 0
  END IF
  '-----------------------------------------------------------------------------------

  'client sends number first then waits.
  'host waits first then sends number.
  IF G.Mode = LANCLIENT THEN
   IF P%% < 10 THEN m$ = "0" + LTRIM$(STR$(P%%)) ELSE m$ = LTRIM$(STR$(P%%))
   Message$ = "[FST]" + m$
   SendMessage
   _DELAY .025
  END IF
 
  LOCATE 21, 1: PRINT "Waiting for Opponents pick..."
  DO
   _DELAY .005
  LOOP UNTIL G.NetWork.X

  computer%% = G.NetWork.X 'set player 2's number
  G.NetWork.X = 0
 
  IF G.Mode = LAN THEN 'send player 1's number to player 2
   IF P%% < 10 THEN m$ = "0" + LTRIM$(STR$(P%%)) ELSE m$ = LTRIM$(STR$(P%%))
   Message$ = "[FST]" + m$
   SendMessage
  END IF
 END IF

 IF P%% < 1 OR P%% > 100 THEN 'player auto lose
  PRINT "Opponent wins because you can not follow instructions."
  computer%% = starter%%
 ELSE 'player entered correct ranged value
  PRINT "Opponent picks:"; computer%%
 END IF
 testp%% = ABS(starter%% - P%%) 'find how far off player is.
 testc%% = ABS(starter%% - computer%%) ' find how far off computer is.
 IF testp%% = testc%% THEN winner%% = PLAYER 'in a tie player wins
 IF testp%% < testc%% THEN winner%% = PLAYER 'player closer wins
 IF testp%% > testc%% THEN winner%% = OPPONENT 'computer closer wins
 _DELAY 1.25
 PRINT "Control number was:";
 _DELAY .75
 PRINT starter%%
 _DELAY .75
 IF winner%% = PLAYER THEN PRINT "You Win the chance to shoot first" ELSE PRINT "Opponent shoots first"
 G.WhoIsUp = winner%% 'store who starts for later
 _DELAY 1.5
 '---------------------------------------------
END SUB

SUB DeployFleet
 STATIC Picked(5)
 _PUTIMAGE , Layer(BOARD), Layer(0)
 _PUTIMAGE (64, 300), Layer(SHEET), Layer(BOARD), (304, 6)-(499, 142)
 _PRINTSTRING (304, 320), "Place Your fleet.", Layer(BOARD)
 _PRINTSTRING (304, 336), "Space to rotate ship.", Layer(BOARD)
 _PRINTSTRING (304, 352), "Left Click to select and place ship.", Layer(BOARD)
 _PRINTSTRING (304, 368), "Right Click to abort Placement.", Layer(BOARD)
 IF G.Mode = LAN OR G.Mode = LANCLIENT THEN _PRINTSTRING (304, 384), "Game is in Network Mode.", Layer(BOARD)
 _PUTIMAGE (304, 400), Layer(SHEET), Layer(BOARD), (24, 279)-(180, 322) 'accept button
 _PUTIMAGE (480, 400), Layer(SHEET), Layer(BOARD), (182, 279)-(338, 322) 'Reset button
 _FONT 16, Layer(MIX)
 DO
  AllPlaced%% = TRUE
  FOR i%% = 1 TO 5
   IF NOT Picked(i%%) THEN 'is ship 'in hand' or placed on board already?
    DisplayShip Offs(i%%).ShipYard_X, Offs(i%%).ShipYard_Y, i%%, HORZ, Layer(SHIPS) 'display ships in ShipYard area
    AllPlaced%% = FALSE
   ELSE
    _PUTIMAGE (64, 316 + (i%% - 1) * 24), Layer(SHEET), Layer(SHIPS), (304, 22)-(424, 46) 'Erase ships from ShipYard area
    'display ships placed on board-----------------------------------------
    IF Ship(i%%).Xpos <> 0 THEN 'if ship has valid xpos then place on board
     IF Ship(i%%).Orent = HORZ THEN
      DisplayShip Offs(i%%).Board_HX + (Ship(i%%).Xpos - 1) * 24, Offs(i%%).Board_HY + (Ship(i%%).Ypos - 1) * 24, i%%, Ship(i%%).Orent, Layer(SHIPS) 'display ships in Board area
     ELSE
      DisplayShip Offs(i%%).Board_VX + (Ship(i%%).Xpos - 1) * 24, Offs(i%%).Board_VY + (Ship(i%%).Ypos - 1) * 24, i%%, Ship(i%%).Orent, Layer(SHIPS) 'display ships in Board area
     END IF
    END IF 'otherwise ship must still be 'in-hand'
    '----------------------------------------------------------------------
   END IF
  NEXT i%%

  'move image to screen -------------------------------------------
  'avoids flicker for the most part.
  _PUTIMAGE , Layer(BOARD), Layer(MIX)
  _PUTIMAGE , Layer(SHIPS), Layer(MIX)
  IF ShipSelection%% THEN DisplayShip x% - 6, y% - 6, ShipSelection%%, ShipOrentation%%, Layer(MIX)
  
  IF G.Mode = LAN THEN
   IF G.NetWork.Ready THEN
    _PRINTSTRING (304, 454), "Opponent is ready", Layer(MIX)
   ELSE
    _PRINTSTRING (304, 454), "Awaiting Opponent ship placement", Layer(MIX)
   END IF
  END IF
  
  _PUTIMAGE , Layer(MIX), Layer(0)
  '----------------------------------------------------------------

  'debug information -------------------------------------------------------------
  LOCATE 1, 1: PRINT CHR$(64 + hy%%); hx%%
  '-------------------------------------------------------------------------------

  x% = _MOUSEX: y% = _MOUSEY 'get mouse location
  IF x% > 54 AND y% > 54 AND x% < 294 AND y% < 294 THEN 'mouse over player board
   'highlite grid block that mouse is over(grid blocks are 22x22[24x24WL])
   hx%% = ((x% - 54) \ 24) + 1: hy%% = ((y% - 54) \ 24) + 1
   LINE (54 + ((hx%% - 1) * 24), 54 + ((hy%% - 1) * 24))-(77 + ((hx%% - 1) * 24), 77 + ((hy%% - 1) * 24)), YellowSelect~&, BF

   'place ship on player board-------
   IF _MOUSEBUTTON(1) AND ShipSelection%% <> 0 THEN
    IF CheckShipPos(hx%%, hy%%, ShipOrentation%%, ShipSelection%%) THEN 'make sure ship fits
     Ship(ShipSelection%%).Xpos = hx%%
     Ship(ShipSelection%%).Ypos = hy%%
     Ship(ShipSelection%%).Orent = ShipOrentation%%
     PlaceShipOnBoard ShipSelection%%
     held%% = 0
     ShipSelection%% = 0
     _MOUSESHOW
    END IF
   END IF
   '---------------------------------

  END IF

  'Main input loop---------------------------------------------------------------
  DO: _DELAY .025
   KBD$ = INKEY$
   SELECT CASE KBD$
    CASE CHR$(13)
     IF AllPlaced%% AND (held%% = FALSE) THEN exitflag%% = TRUE
    CASE CHR$(27)
     '     exitflag%% = TRUE
    CASE CHR$(32)
     IF ShipOrentation%% = HORZ THEN ShipOrentation%% = VERT ELSE ShipOrentation%% = HORZ
     UpDateFlag%% = TRUE
    CASE CHR$(65)
     IF NOT AutoFlag%% THEN
      FOR i%% = 1 TO 5
       Picked(i%%) = TRUE 'set true before using autopick
       Ship(i%%).Xpos = 0
       Ship(i%%).Ypos = 0
       Ship(i%).Orent = 0
      NEXT i%%
      ResetBoard
      ClearLayer SHIPS
      _CLEARCOLOR _RGB32(0, 0, 0), Layer(SHIPS)
      AutoPlaceShips PLAYER
      UpDateFlag%% = TRUE
      AutoFlag%% = TRUE
     END IF
   END SELECT
  LOOP UNTIL _MOUSEINPUT OR exitflag%% OR UpDateFlag%%
  UpDateFlag%% = FALSE
  '------------------------------------------------------------------------------

  'Ship Selection to place-------------------------------------------------------
  IF x% > 64 AND y% > 316 AND x% < 245 AND y% < 432 THEN 'player over ship yard
   IF _MOUSEBUTTON(1) THEN
    IF ShipSelection%% = 0 THEN
     hy2%% = ((y% - 316) \ 24) + 1
     IF NOT Picked(hy2%%) THEN 'make sure ship is still in the yard.
      SELECT CASE hy2%%
       CASE CARRIER
        ShipSelection%% = CARRIER: ShipOrentation%% = HORZ: Picked(1) = TRUE: held%% = 1
       CASE BATTLESHIP
        ShipSelection%% = BATTLESHIP: ShipOrentation%% = HORZ: Picked(2) = TRUE: held%% = 2
       CASE DESTROYER
        ShipSelection%% = DESTROYER: ShipOrentation%% = HORZ: Picked(3) = TRUE: held%% = 3
       CASE SUBMARINE
        ShipSelection%% = SUBMARINE: ShipOrentation%% = HORZ: Picked(4) = TRUE: held%% = 4
       CASE PTBOAT
        ShipSelection%% = PTBOAT: ShipOrentation%% = HORZ: Picked(5) = TRUE: held%% = 5
      END SELECT
     END IF
     IF ShipSelection%% <> 0 THEN _MOUSEHIDE
    END IF
   END IF
  END IF
  '------------------------------------------------------------------------------
  IF x% > 304 AND y% > 400 AND x% < 460 AND y% < 443 THEN 'accept button
   IF _MOUSEBUTTON(1) AND AllPlaced%% AND (held%% = FALSE) THEN
    exitflag%% = TRUE
    _PUTIMAGE (304, 400), Layer(SHEET), Layer(0), (24, 324)-(180, 367) 'accept button down
   END IF
  END IF
  IF x% > 480 AND y% > 400 AND x% < 636 AND y% < 443 THEN 'reset button
   IF _MOUSEBUTTON(1) THEN
    _PUTIMAGE (480, 400), Layer(SHEET), Layer(0), (182, 324)-(338, 367) 'Reset button down
    FOR i%% = 1 TO 5
     Picked(i%%) = FALSE
     Ship(i%%).Xpos = 0
     Ship(i%%).Ypos = 0
     Ship(i%).Orent = 0
    NEXT i%%
    held%% = 0: ShipSelection%% = 0
    _MOUSESHOW
    ResetBoard
    IF AutoFlag%% THEN AutoFlag%% = FALSE
    ClearLayer SHIPS
    _CLEARCOLOR _RGB32(0, 0, 0), Layer(SHIPS)
   END IF
  END IF
  IF _MOUSEBUTTON(2) THEN ShipSelection%% = 0: Picked(held%%) = FALSE: held%% = 0: _MOUSESHOW 'Deselect ship for placement
  DO: LOOP WHILE _MOUSEINPUT
 LOOP UNTIL exitflag%%
 'player is done but if network game pause here until Opponent is ready

 ClearArea

 IF NOT G.NetWork.Ready THEN
  _PRINTSTRING (304, 320), "Awaiting Opponent ship placement...", Layer(0)
  _PRINTSTRING (304, 336), "You are Ready...", Layer(0)
 END IF

 IF G.Mode = LAN THEN
  DO
   _DELAY .05
  LOOP UNTIL G.NetWork.Ready
  'once client has given ship locations send hosts
  Message$ = "[SHP]"
  FOR i%% = 1 TO 5
   IF Ship(i%%).Xpos < 10 THEN m$ = "0" + LTRIM$(STR$(Ship(i%%).Xpos)) ELSE m$ = LTRIM$(STR$(Ship(i%%).Xpos))
   Message$ = Message$ + m$
   IF Ship(i%%).Ypos < 10 THEN m$ = "0" + LTRIM$(STR$(Ship(i%%).Ypos)) ELSE m$ = LTRIM$(STR$(Ship(i%%).Ypos))
   Message$ = Message$ + m$
   Message$ = Message$ + LTRIM$(STR$(Ship(i%%).Orent))
  NEXT i%%
  SendMessage
 END IF

 IF G.Mode = LANCLIENT THEN
  'send host ship placement
  Message$ = "[SHP]"
  FOR i%% = 1 TO 5
   IF Ship(i%%).Xpos < 10 THEN m$ = "0" + LTRIM$(STR$(Ship(i%%).Xpos)) ELSE m$ = LTRIM$(STR$(Ship(i%%).Xpos))
   Message$ = Message$ + m$
   IF Ship(i%%).Ypos < 10 THEN m$ = "0" + LTRIM$(STR$(Ship(i%%).Ypos)) ELSE m$ = LTRIM$(STR$(Ship(i%%).Ypos))
   Message$ = Message$ + m$
   Message$ = Message$ + LTRIM$(STR$(Ship(i%%).Orent))
  NEXT i%%
  SendMessage
  DO
   _DELAY .05
  LOOP UNTIL G.NetWork.Ready
 END IF
 IF G.Debug THEN dumpboard
END SUB

SUB OpponentShot
 DO 'wait until opponent sends shot packet
  _DELAY .01
  'if something happens to Opponent
  IF INKEY$ = CHR$(27) THEN G.NetWork.X = 1: G.NetWork.Y = 1: G.GameOver = TRUE
 LOOP UNTIL G.NetWork.X
 x%% = G.NetWork.X
 y%% = G.NetWork.Y
 G.NetWork.X = 0
 G.NetWork.Y = 0
 MessageHandler "Opponent fires at " + CHR$(64 + y%%) + STR$(x%%)
 _DELAY .5
 SELECT CASE SendShot(x%%, y%%, OPPONENT)
  CASE HIT 'Hits players ship
   MessageHandler "Opponent Hits!"
   checkships
  CASE MISS 'Missed players ship
   MessageHandler "Opponent Misses"
  CASE BAD 'Already fired upon this space ERROR
   MessageHandler "Opponent has been Hitting the juice again, fired an error"
 END SELECT
 _DELAY .5
END SUB

SUB CreateNetworkGame
 CLS
 ClearLayer MIX
 _FONT FFX(1), Layer(LAN)
 _PRINTSTRING (128, 32), "PORT ADDRESS FOR HOST", Layer(LAN)
 _FONT FFX(6), Layer(LAN)
 _PRINTSTRING (96, 64), "VALUE MUST BE GREATER THAN 1000", Layer(LAN)
 _PRINTSTRING (200, 84), "0 FOR DEFUALT PORT", Layer(LAN)
 _FONT FFX(5), Layer(MIX)
 ChangeColor _RGB32(63, 208, 63), Layer(MIX)
 port$ = "1945" 'defualt WWII port address
 DO
  Port% = VAL(port$)
  _PUTIMAGE , Layer(LAN), Layer(MIX)
  _PRINTSTRING (268, 117), LTRIM$(STR$(Port%)), Layer(MIX)
  _PUTIMAGE , Layer(MIX), Layer(0)
  x% = _FONTWIDTH(FFX(5)) * LEN(port$)
  LINE (268 + x%, 158)-(292 + x%, 162), _RGB32(255, 255, 0), BF
  DO
   KBD$ = INKEY$
   SELECT CASE KBD$
    CASE CHR$(8) 'backspace
     IF port$ <> "" THEN port$ = MID$(port$, 1, LEN(port$) - 1)
     UpDate%% = TRUE
    CASE CHR$(13)
     IF LEN(port$) = 4 THEN
      Port% = VAL(port$): ExitFlag%% = TRUE
     ELSEIF port$ = "" OR port$ = "0" THEN
      Port% = 0: ExitFlag%% = TRUE
     END IF
    CASE CHR$(27)
     ExitFlag%% = TRUE
    CASE CHR$(48) TO CHR$(57) 'numbers
     IF LEN(port$) < 4 THEN port$ = port$ + KBD$
     UpDate%% = TRUE
   END SELECT
   _DELAY .025
  LOOP UNTIL _MOUSEINPUT OR ExitFlag%% OR UpDate%%
  UpDate%% = FALSE
 LOOP UNTIL ExitFlag%%
 ExitFlag%% = FALSE
 _FONT 16, Layer(LAN)
 _PRINTSTRING (8, 464), "Starting up host...", Layer(0)
 G.NetWork.Host = StartHost(Port%)
 IF G.NetWork.Host THEN _DELAY 1.5 'give host a few secs to start up
 G.Mode = LAN
 TIMER(Listen&) ON 'turn on the timer to listen for opponent chatter
 'connect host user
 _PRINTSTRING (256, 464), "Connecting to host...", Layer(0)
 _DELAY .5
 G.NetWork.Client = ConnectClient(Port%, "0")
 'game is now in network mode
 '-------------------------------------------
 _FONT FFX(2), Layer(MIX)
END SUB

SUB JoinNetworkGame
 CLS
 ClearLayer MIX
 _FONT FFX(1), Layer(LAN)
 _PRINTSTRING (128, 32), "PORT ADDRESS CONNECT TO", Layer(LAN)
 _PRINTSTRING (144, 168), "IP ADDRESS CONNECT TO", Layer(LAN)
 _FONT FFX(6), Layer(LAN)
 _PRINTSTRING (200, 84), "0 FOR DEFUALT PORT", Layer(LAN)
 _PUTIMAGE (32, 200), Layer(SHEET), Layer(LAN), (0, 376)-(575, 430)
     
 _FONT FFX(5), Layer(MIX)
 ChangeColor _RGB32(63, 208, 63), Layer(MIX)
 port$ = "1945" 'defualt WWII port address
 IF IPA$ = "" THEN IPA$ = "LOCALHOST"
 selection%% = 2
 DO
  Port% = VAL(port$)
  _PUTIMAGE , Layer(LAN), Layer(MIX)
  _PRINTSTRING (268, 117), LTRIM$(STR$(Port%)), Layer(MIX)
      
  _PRINTSTRING (320 - ((LEN(IPA$) \ 2) * _FONTWIDTH(FFX(5))), 208), IPA$, Layer(MIX)
  _PUTIMAGE , Layer(MIX), Layer(0)
  
  x% = _MOUSEX: y% = _MOUSEY 'get mouse location
  
  IF _MOUSEBUTTON(1) THEN
   IF x% > 220 AND x% < 450 AND y% > 112 AND y% < 162 THEN selection%% = 1 'port address
   IF x% > 40 AND x% < 600 AND y% > 200 AND y% < 250 THEN selection%% = 2 'IP address
   update%% = TRUE
  END IF
      
  IF selection%% = 1 THEN
   x% = _FONTWIDTH(FFX(5)) * LEN(port$)
   LINE (268 + x%, 158)-(292 + x%, 162), _RGB32(255, 255, 0), BF
  ELSEIF selection%% = 2 THEN
   x% = 320 - ((LEN(IPA$) \ 2) * _FONTWIDTH(FFX(5))) + (LEN(IPA$) * _FONTWIDTH(FFX(5)))
   LINE (x%, 249)-(x% + 24, 253), _RGB32(255, 255, 0), BF
  END IF
  DO
   KBD$ = INKEY$
   SELECT CASE KBD$
    CASE CHR$(8) 'backspace
     IF selection%% = 1 THEN
      IF port$ <> "" THEN port$ = MID$(port$, 1, LEN(port$) - 1)
     ELSEIF selection%% = 2 THEN
      IF IPA$ <> "" THEN IPA$ = MID$(IPA$, 1, LEN(IPA$) - 1)
     END IF
     update%% = TRUE
    CASE CHR$(13)
     IF LEN(port$) = 4 THEN
      IF IPA$ = "" OR UCASE$(IPA$) = "LOCALHOST" THEN IPA$ = "0"
      Port% = VAL(port$): ExitFlag%% = TRUE
     ELSEIF port$ = "" OR port$ = "0" THEN
      Port% = 0: ExitFlag%% = TRUE
     END IF
    CASE CHR$(27)
     ExitFlag%% = TRUE: Cancel%% = TRUE
    CASE CHR$(48) TO CHR$(57), CHR$(46) 'numbers and .
     IF selection%% = 1 THEN
      IF LEN(port$) < 4 THEN port$ = port$ + KBD$
     ELSEIF selection%% = 2 THEN
      IF LEN(IPA$) < 15 THEN IPA$ = IPA$ + KBD$
     END IF
     update%% = TRUE
   END SELECT
   _DELAY .025
  LOOP UNTIL _MOUSEINPUT OR ExitFlag%% OR update%%
  update%% = FALSE
  DO: LOOP WHILE _MOUSEINPUT

 LOOP UNTIL ExitFlag%%
 ExitFlag%% = FALSE

 _FONT 16, Layer(LAN)
 'connect host user
 IF NOT Cancel%% THEN
  _PRINTSTRING (256, 464), "Connecting to host...", Layer(0)
  _DELAY .5
  G.NetWork.Client = ConnectClient(Port%, IPA$)
  IF G.NetWork.Client THEN G.Mode = LANCLIENT
  TIMER(Listen&) ON 'turn on the timer to listen for opponent chatter
 END IF
END SUB

SUB Instruction
 'Instructions------------------------------
 _FONT FFX(1), Layer(MIX)
 ChangeColor _RGB32(212, 212, 212), Layer(MIX) 'Hover color
 ClearLayer MIX
 _PRINTSTRING (200, 16), "BATTLESHIP 64", Layer(MIX)
 _PRINTSTRING (64, 48), "SHIP STATS:", Layer(MIX)
 FOR i%% = 1 TO 5
  DisplayShip 32, 64 + (32 * i%%), i%%, HORZ, Layer(MIX)
 NEXT i%%
 _PRINTSTRING (160, 96), "CARRIER TAKES 5 HITS", Layer(MIX)
 _PRINTSTRING (160, 128), "BATTLESHIP TAKES 4 HITS", Layer(MIX)
 _PRINTSTRING (160, 160), "DESTROYER TAKES 3 HITS", Layer(MIX)
 _PRINTSTRING (160, 192), "SUBMARINE TAKES 3 HITS", Layer(MIX)
 _PRINTSTRING (160, 224), "PT BOAT TAKES 2 HITS", Layer(MIX)
 _FONT FFX(4), Layer(MIX)
 _PRINTSTRING (32, 256), "Ships can be palced vertically", Layer(MIX)
 _PRINTSTRING (32, 288), "on the game board by pressing", Layer(MIX)
 _PRINTSTRING (32, 320), "the space bar while the ship", Layer(MIX)
 _PRINTSTRING (32, 352), "is selected.", Layer(MIX)

 _PUTIMAGE (32, 400), Layer(SHEET), Layer(MIX), (305, 144)-(327, 166)
 _PUTIMAGE (32, 432), Layer(SHEET), Layer(MIX), (329, 144)-(350, 166)
 _PRINTSTRING (64, 400), "-Denotes a hit.", Layer(MIX)
 _PRINTSTRING (64, 432), "-Denotes a miss.", Layer(MIX)
 _FONT 16, Layer(MIX)
 _PRINTSTRING (8, 464), "Press any key to return to menu", Layer(MIX)
 _PUTIMAGE , Layer(MIX), Layer(0)

 _FONT FFX(2), Layer(MIX)
 '------------------------------------------
 DO: LOOP WHILE INKEY$ = ""
 _KEYCLEAR
END SUB



'Routines Beyond are not Game nessesary-------------------------------

SUB dumpboard
 'debugging
 FOR z%% = 1 TO 2
  FOR y%% = 1 TO 10
   FOR x%% = 1 TO 10
    PRINT #6, Board(x%%, y%%, z%%);
   NEXT
   PRINT #6,
  NEXT
  PRINT #6,: PRINT #6,
 NEXT
END SUB
