!***************************************************************************!
!									    !
!				 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