!***************************************************************************!
!                                                                           !
!                                BATTL2.BAS                                 !
!                      Battleship for the Alpha Micro                       !
!                                                                           !
!***************************************************************************!
!Copyright (C) 1986 by UltraSoft.  All Rights Reserved.
!FreeWare from UltraSoft.  May be distributed free of charge.
!
!Written by: David Pallmann
!
!Edit History:
!1.0 29-Mar-86 created. /DFP
!2.0 01-May-86 Two-user version of BATTLE.BAS /RPW (CENTAURI) (512) 631-9141

       PROGRAM BATTL2,2.0

       MAP1 PROMPT,S,20
       MAP1 ENTRY,S,30
       MAP1 HCHAR,S,1,"*"      !Hit marker.
       MAP1 MCHAR,S,1,"+"      !Missed marker.
       MAP1 CCHAR,S,1,"."      !Coordinate marker.
       MAP1 DELAY,F,6,2000     !Delay loop for error mess.
       MAP1 CNAM,S,6           !Opponent's job name.
       MAP1 PNAM,S,6           !This player's job name.
       MAP1 CBRD(10,10),B,1    !COMPUTER BOARD
       MAP1 PBRD(10,10),B,1    !PLAYER BOARD
       MAP1 PIMG(10,10),B,1    !PLAYER IMAGE OF COMPUTER BOARD
       MAP1 CSHIP(5),F         !SHIP COUNTS
       MAP1 PSHIP(5),F         !SHIP COUNTS
       MAP1 NAME(5),S,20       !SHIP NAMES
       MAP1 LENGTH(5),F        !SHIP LENGTHS
       MAP1 CDOWN,F            !COMPUTER SHIPS SANK
       MAP1 PDOWN,F            !PLAYER SHIPS SANK
       MAP1 HR,F               !HIT ROW
       MAP1 HC,F               !HIT COLUMN
       MAP1 SR,F               !SAVED HIT ROW
       MAP1 SC,F               !SAVED HIT COLUMN
       MAP1 HFLAG,F            !HIT FLAG
       MAP1 I,F                !LOOP INDEX
       MAP1 J,F                !LOOP INDEX
       MAP1 K,F                !LOOP INDEX
       MAP1 R,F                !ROW
       MAP1 C,F                !COLUMN
       MAP1 R1,F               !ROW
       MAP1 C1,F               !COLUMN
       MAP1 D,F                !DIRECTION
       MAP1 VD,F               !VERTICAL DIRECTION
       MAP1 HD,F               !HORIZONTAL DIRECTION
       MAP1 L,F                !LENGTH OF CURRENT SHIP
       MAP1 TEXT,S,10          !INPUT STRING
       MAP1 HITS,F             !PLAYER HITS
       MAP1 CHITS,F            !COMPUTER HITS
       MAP1 FLAG,F             !FLAG
       MAP1 USR'BUF            !Borrowed from A.B. USRBUF.CPY
               MAP2 UB'RCN,B,2
               MAP2 UB'UID,S,6
               MAP2 UB'NAME,S,30
               MAP2 UB'FIL,X,62
       MAP1 CNAME,S,30
       MAP1 ANSWER,S,1

       ?TAB(-1,0);"           *+*+*+*+BATTLESHIP*+*+*+*+*+"
       ?TAB(10,1);"1.  PLAY AGAINST THE COMPUTER."
       ?TAB(11,1);"2.  PLAY AGAINST ANOTHER USER."
WHICH:
       ?TAB(15,1);"_ <-- Enter your choice.";TAB(15,1);
       INPUT "",WHICH
       IF WHICH=1 CHAIN "BATTLE"
       IF WHICH<>2 GOTO WHICH
       ?TAB(20,1);"______ <-- Enter name of job to play against.";TAB(20,1);
       INPUT "",CNAM
       XCALL STRIP,CNAM
       IF LEN(CNAM)<1 GOTO WHICH
SND'MSG:
       ?TAB(21,1);"_ <-- Send message to "+CNAM+"? (Y/N)";TAB(21,1);
       INPUT "",ANSWER
       IF UCS(ANSWER)<>"Y" GOTO INIT1
       ?TAB(22,1);
       XCALL SYSTEM,"SEND "+CNAM+" <HOW ABOUT A GAME OF BATTLESHIP?>"
       GOTO SND'MSG
INIT1:
       LOOKUP "MEM:GINDTA.SV",ABF
       IF ABF THEN &
               XCALL DB,14,USR'BUF : &
               PNAM=UB'UID
       IF ABF=0 THEN XCALL JOBNAM,PNAM
       XCALL STRIP,PNAM

INIT:   RANDOMIZE
       FOR I=1 TO 5
           READ NAME(I),LENGTH(I)
           CSHIP(I)=LENGTH(I)
           PSHIP(I)=LENGTH(I)
           NEXT
       DATA BATTLESHIP,5
       DATA DESTROYER,4
       DATA CRUISER,3
       DATA SUBMARINE,3
       DATA PT BOAT,2

NEWGAM: PRINT TAB(-1,0); TAB(-1,11);
       FOR I=1 TO 10
           PRINT TAB(1,I*2+2); STR(I);
           PRINT TAB(13,I*2+2); STR(I);
           PRINT TAB(I+1,1); CHR(I+64);
           PRINT TAB(I+13,1); CHR(I+64);
           FOR J=1 TO 10
               CBRD(I,J)=0 : PBRD(I,J)=0 : PIMG(I,J)=0
               PRINT TAB(I+1,J*2+2); CCHAR;
               PRINT TAB(I+13,J*2+2); CCHAR;
               NEXT
           NEXT
       PRINT TAB(6,25); "OPPONENT'S";
       PRINT TAB(7,25); "FIELD";
       PRINT TAB(17,25);"YOUR";
       PRINT TAB(18,25);"FIELD";
       PRINT TAB(-1,12);
       IF ABF=0 PROMPT="YOUR NAME? " : CALL INPUT : UB'NAME=ENTRY
       PRINT TAB(19,25);PNAM;" (";UB'NAME;")";

       PRINT TAB(3,50); "**  BATTLESHIP  **";
       LOOKUP PNAM+".BAT",FOUND
       IF FOUND CALL LOAD'OLD'BOARD : GOTO START'PLAY

       PRINT TAB(-1,11);
       PRINT TAB(5,40); "ENTER STARTING COORDINATE, COMMA,";
       PRINT TAB(6,40); "ENDING COORDINATE (EXAMPLE: A1,A5)";
       FOR I=1 TO 5
GETPOS:     PRINT TAB(-1,11);
           PRINT TAB(I+7,40); NAME(I); " ("; STR(LENGTH(I)); ")? "; TAB(-1,9);
           PRINT TAB(-1,12);
           PROMPT=""
           CALL INPUT
           TEXT=ENTRY
           CALL COORD : IF FLAG THEN GOTO GETPOS
           CALL CHOP
           R1=R : C1=C
           CALL COORD : IF FLAG THEN GOTO GETPOS
           VD=0 : HD=0
           IF R>R1 THEN VD=1
           IF R<R1 THEN VD=-1
           IF C>C1 THEN HD=1
           IF C<C1 THEN HD=-1
           IF VD#0 AND HD#0 THEN GOTO GETPOS
           IF VD=0 AND HD=0 THEN GOTO GETPOS
           IF R1+(LENGTH(I)-1)*VD#R AND C1+(LENGTH(I)-1)*HD#C THEN GOTO GETPOS
           FLAG=0
           FOR J=1 TO LENGTH(I)
               R=R1+(VD*(J-1))
               C=C1+(HD*(J-1))
               IF R>10 OR C>10 GOTO GETPOS     !Watch for subscript out of range.
               IF PBRD(R,C)#0 THEN FLAG=-1
               NEXT J
           IF FLAG THEN GOTO GETPOS
           FOR J=1 TO LENGTH(I)
               PBRD(R1,C1)=I
               PRINT TAB(R1+13,C1*2+2); CHR(I+96);
               R1=R1+VD : C1=C1+HD
               NEXT
           NEXT
       FOR I=5 TO 12
           PRINT TAB(I,40); TAB(-1,9);
           NEXT

       CALL SAVE'BOARD
START'PLAY:
       CALL LOAD'BOARD
       LOOKUP PNAM+".MOV",FOUND
       IF FOUND KILL PNAM+".MOV"

       PRINT TAB(-1,11);
       PRINT TAB(5,40); "YOUR GUESS";
       PRINT TAB(7,40); CNAM+"'S GUESS";
       PRINT TAB(-1,12);

PLAYER: PRINT TAB(5,65); TAB(-1,9);
       PROMPT=""
       CALL INPUT
       TEXT=ENTRY
       CALL COORD : IF FLAG THEN GOTO PLAYER
       IF R<1 OR R>10 OR C<1 OR C>10 THEN GOTO PLAYER
       IF PIMG(R,C)#0 THEN GOTO PLAYER
       CALL SAVE'MOVE
       IF CBRD(R,C)=0 THEN GOTO MISS

HIT:    PIMG(R,C)=1
       PRINT TAB(R+1,C*2+2); HCHAR;
       PRINT TAB(5,70); "HIT "; CHR(7);
       HITS=HITS+1
       I=CBRD(R,C)
       CSHIP(I)=CSHIP(I)-1
       IF CSHIP(I)=0 THEN CDOWN=CDOWN+1 : &
               PRINT TAB(20,45); STR(CDOWN); " OF "+CNAM+"'S SHIPS SANK";
       IF HITS<17 THEN GOTO COMP
       PRINT TAB(22,45); "CONGRATULATIONS, YOU WIN   ";
       CALL DELAY : CALL DELAY
       CALL LOAD'MOVE
       GOTO QUIT

MISS:   PIMG(R,C)=-1
       PRINT TAB(R+1,C*2+2); MCHAR;
       PRINT TAB(5,70); "MISS";

COMP:
       CALL LOAD'MOVE
       PRINT TAB(7,65); CHR(R+64); STR(C); " ";
       IF PBRD(R,C)#0 THEN GOTO CHIT

CMISS:
       PRINT TAB(R+13,C*2+2); MCHAR;
       PRINT TAB(7,70); "MISS";
       GOTO PLAYER

CHIT:
       PRINT TAB(R+13,C*2+2); HCHAR;
       PRINT TAB(7,70); "HIT "; CHR(7);
       CHITS=CHITS+1
       I=PBRD(R,C)
       PSHIP(I)=PSHIP(I)-1
       IF PSHIP(I)=0 THEN PDOWN=PDOWN+1 : &
               PRINT TAB(18,45); STR(PDOWN); " OF YOUR SHIPS SANK";
       IF CHITS<17 THEN GOTO PLAYER
       PRINT TAB(22,45); "SORRY, YOU HAVE LOST. ";
QUIT:
       IF HITS<17 PRINT TAB(22,68); "WIMP!";
       PRINT TAB(23,45); "EFFICIENCY RATING = ";(HITS/TRIES)*100 USING "###";"%";
       FOR I=1 TO 10
           FOR J=1 TO 10
               IF CBRD(I,J)#0 AND PIMG(I,J)=0 THEN PRINT TAB(I+1,J*2+2); CHR(96+CBRD(I,J));
               NEXT
           NEXT
       PRINT TAB(22,75);
       CALL DELAY : CALL DELAY
       END

COORD:  FLAG=0
       R=ASC(LEFT(TEXT,1))-64
       CALL CHOP
       C=LEFT(TEXT,1)
       CALL CHOP
       IF LEFT(TEXT,1)="0" THEN C=10 : CALL CHOP
       IF R<1 OR R>10 THEN FLAG=-1
       IF C<1 OR C>10 THEN FLAG=-1
       RETURN

CHOP:   TEXT=RIGHT(TEXT,LEN(TEXT)-1)
       RETURN

LOAD'MOVE:
       LOOKUP CNAM+".MOV",FOUND
       IF FOUND=0 ?TAB(23,40);TAB(-1,9); : CALL DELAY : &
               ?"Waiting for "+CNAM+" to move..."; :&
               CALL DELAY : CALL DELAY : GOTO LOAD'MOVE
       ?TAB(23,40);TAB(-1,9);
       OPEN #1,CNAM+".MOV",INPUT
       INPUT #1,R,C
       CLOSE #1
       KILL CNAM+".MOV"
       RETURN

SAVE'MOVE:
       LOOKUP PNAM+".MOV",FOUND
       IF FOUND ?TAB(23,40);TAB(-1,9); : CALL DELAY : &
               ?"Waiting for "+CNAM+" to get your move..."; :&
               CALL DELAY : CALL DELAY : GOTO SAVE'MOVE
       ?TAB(23,40);TAB(-1,9);
       OPEN #1,PNAM+".MOV",OUTPUT
       PRINT #1,STR(R);",";STR(C)
       CLOSE #1
       TRIES=TRIES+1
       RETURN

LOAD'BOARD:
       IF ABF PROMPT="OPPONENT'S ID " : CALL INPUT : CNAM=ENTRY
       LOOKUP CNAM+".BAT",FOUND
       IF FOUND=0 ?TAB(23,40);TAB(-1,9); : CALL DELAY : &
               ?"Waiting for "+CNAM+" to set up board..."; :&
               CALL DELAY : CALL DELAY : GOTO LOAD'BOARD
       ?TAB(23,40);TAB(-1,9);
       OPEN #1,CNAM+".BAT",INPUT
       INPUT LINE #1,CNAME
       FOR X = 1 TO 10
               FOR Y = 1 TO 10
                       INPUT #1,CBRD(X,Y)
               NEXT
       NEXT
       CLOSE #1
       KILL CNAM+".BAT"
       PRINT TAB(5,40);TAB(-1,9);
       PRINT TAB(8,25);CNAM;" (";CNAME;")";
       RETURN
SAVE'BOARD:
       OPEN #1,PNAM+".BAT",OUTPUT
       PRINT #1,UB'NAME
       FOR X = 1 TO 10
               FOR Y = 1 TO 10
                       PRINT #1,STR(PBRD(X,Y))
               NEXT
       NEXT
       CLOSE #1
       RETURN
LOAD'OLD'BOARD:
       OPEN #1,PNAM+".BAT",INPUT
       INPUT LINE #1,TEXT
       TEXT=""
       FOR X = 1 TO 10
               FOR Y = 1 TO 10
                       INPUT #1,PBRD(X,Y)
                       IF PBRD(X,Y)<>0 &
                               PRINT TAB(X+13,Y*2+2); CHR(PBRD(X,Y)+96);
               NEXT
       NEXT
       CLOSE #1
       RETURN

INPUT:
       IF LEN(PROMPT)>0 &
               PRINT TAB(-1,11);TAB(5,40);TAB(-1,9);PROMPT;TAB(-1,12);
       INPUT LINE ENTRY
       XCALL STRIP,ENTRY
       ENTRY=UCS(ENTRY)
       IF ENTRY[1,1]="Q" OR ENTRY="END" OR ENTRY="BYE" GOTO QUIT
       RETURN

DELAY:  FOR X = 1 TO DELAY : NEXT : RETURN