SUBROUTINE GAME(ICODE,NUM) C C THIS SUBROUTINE READS IN THE GAME MAP AND INITIALIZES THE MAP ARRAYS C IT ALSO SAVES AND RESTORES THE GAME FROM THE SAVE FILE C ICODE: FUNCTION, -1=RESTORE, 0=INIT, 1=SAVE C INCLUDE 'EMPIRE.INC/NOLIST' COMMON/CITIES/CITIES(128) C C DATA IFILE/'G','A','M','E','S',':','E','M','R','A',0/ DATA IFILE/'[','7',',','1','3',']','E','M','A','0',0/ BYTE J C IF (ICODE) 1800,100,1500 !-1/0/+1 = RESTORE/INIT/SAVE C C HERE TO INITIALIZE THE GAME C 100 DO 200 I=1,70 !CLEAR ARRAYS X(I)=0 FOUND(I)=0 OWNER(I)=0 PHASE(I)=0 TARGET(I)=0 FIPATH(I)=0 200 CONTINUE DO 300 I=1,1500 CALL MAP(6) CODEFU(I)=0 CODELA(I)=0 CALL MAP(7) MYCODE(I)=0 300 CONTINUE DO 400 I=1,200 CALL MAP(8) RANGE(I)=0 CALL MAP(7) RANG(I)=0 400 CONTINUE CALL MAP(8) DO 500 I=1,500 500 AR2S(I)=0 CALL MAP(4) DO 600 I=1,3000 RLMAP(I)=0 600 CONTINUE DO 700 I=1,6000 CALL MAP(1) EMAP(I)=' ' CALL MAP(5) PMAP(I)=' ' 700 CONTINUE C MODE=1 ISEC=-1 CALL TIME(PAMELA) CALL DATE(REEED) VERSION=6 !VERSION OF DATA WITHIN EMSAVE.DAT FILE IB=1 C-----MAP SELECTION------- C PICK ONE OF THE MAPS RANDOMLY. MAPS ARE IN FILES A-F C 900 TRY=1 IFILE(9)=IFILE(9)+RND(26) !There is space for up to 260 stored IFILE(10)=IFILE(10)+RND(10) !Maps. If one of these is not used. OPEN(UNIT=1,NAME=IFILE,ACCESS='SEQUENTIAL',FORM='UNFORMATTED', 1 TYPE='OLD',READONLY,ERR=950) CALL LIBPGE(1,1) CALL MAP(7) READ(1) (D(I),I=1,223) READ(1) (D(I),I=224,446) READ(1) (D(I),I=447,667) CLOSE(UNIT=1) GOTO 1100 950 CALL LIBPGE(1,1) TYPE 999 999 FORMAT(' Generating new map ...',/,' This takes about ten minutes', 1 /,' Please take a coffee break') CLOSE(UNIT=1) TRY=0 CALL GEN OPEN(UNIT=1,NAME=IFILE,ACCESS='SEQUENTIAL',FORM='UNFORMATTED', 1 TYPE='NEW') CALL MAP(7) WRITE(1) (D(I),I=1,223) WRITE(1) (D(I),I=224,446) WRITE(1) (D(I),I=447,667) CLOSE(UNIT=1) C C-----CITY AND A-MAP INITIALIZATION-------- C 1100 CALL INITIA(TRY) ! TRANSFER MAP FROM D() INTO MAPBUF 1200 C=RND(70)+1 !** PICK OUR CITY ID=RND(70)+1 ! PICK ENEMY CITY IF (X(C).EQ.0.OR.X(ID).EQ.0) GOTO 1200 IF (X(C).EQ.X(ID)) GOTO 1200 IF ((EDGER(X(C)).EQ.8).OR.(EDGER(X(ID)).EQ.8)) GOTO 1200 IF (TRY.NE.0) GOTO 1300 1250 CALL MAP(2) PCON=CITIES(RMAP(X(ID))) ECON=CITIES(RMAP(X(C))) IF (PCON.LE.100) GOTO 1200 ! NOTE RMAP IS REALLY OWNER IF (ECON.LE.100) GOTO 1200 ! FROM MAP GENERATOR PTOT=PCON/100+MOD(PCON,100) ETOT=ECON/100+MOD(ECON,100) IF (PTOT.LE.ETOT) GOTO 1275 I=C C=ID ID=I GOTO 1250 1275 DIFF=MIN(11,((ETOT*2*100+45)/PTOT)/100)-1 IF (PCON.EQ.ECON) DIFF=3 TYPE 994,DIFF 994 FORMAT(' Difficulty estimate:',I3, 1 ' where 1 is easy and 10 is most challenging') 1300 Z6=X(ID) TYPE 998,X(ID) ! TELL US WHERE IT IS 998 FORMAT(' Your city is at ',I4) DO 1400 I=1,6000 CALL MAP(3) J=OMAP(I) CALL MAP(2) 1400 RMAP(I)=J RMAP(Z6)='O' ! MARK IT ON MAP RMAP(X(C))='X' CALL SONAR(X(C)) ! DO SENSOR SCANS CALL SENSOR(Z6) MODE=0 CALL LTR(Z6,0) ! SHOW THE CITY MODE=1 CALL STROUT('What do you demand that this city produce?',13) OWNER(ID)=1 MDATE=0 CALL PHASIN(ID,E) TYPE 993,E 993 FORMAT('+',A1,$) OWNER(C)=2 PHASE(C)=1 FOUND(C)=5 Z6=X(ID) RETURN ! RETURN TO ORDERS MODE C C HERE TO SAVE A GAME C 1500 IF (MODE.EQ.0) TYPE 997 997 FORMAT(' A few moments please ...'/) 1600 CONTINUE CALL TIME(PAMELA) CALL DATE(REEED) OPEN(UNIT=1,NAME='EMSAVE',ACCESS='SEQUENTIAL',FORM='UNFORMATTED', 1 STATUS='UNKNOWN') WRITE(1) LIMIT,MDATE,VERSION,PAMELA,REEED CALL MAP(1) WRITE(1) EMAP CALL MAP(2) WRITE(1) RMAP CALL MAP(5) WRITE(1) PMAP CALL MAP(3) WRITE(1) OMAP C WRITE(1) EMAP,RMAP,PMAP,OMAP CALL MAP(4) WRITE(1) RLMAP WRITE(1) TROOPT WRITE(1) NUMBER WRITE(1) X,TARGET,FOUND WRITE(1) OWNER,PHASE DO 1700 I=1,16 1700 CALL WRITE(IOTAB(I),LIMIT(I),I) CALL MAP(8) WRITE(1) J1TS WRITE(1) NUM WRITE(1) LOCI WRITE(1) NSHIFT,FIPATH CLOSE(UNIT=1) RETURN C C HERE TO RESTORE A GAME C 1800 TYPE 997 OPEN(UNIT=1,NAME='EMSAVE',ACCESS='SEQUENTIAL',FORM='UNFORMATTED', 1 STATUS='OLD',ERR=2200) READ(1) LIMIT,MDATE,VERSION,PAMELA,REEED CALL MAP(1) READ(1) EMAP CALL MAP(2) READ(1) RMAP CALL MAP(5) READ(1) PMAP CALL MAP(3) READ(1) OMAP C READ(1) EMAP,RMAP,PMAP,OMAP IF(VERSION.GE.6) GOTO 1850 VERSION=6 !TRANSLATE TO NEW VERSION DO 1850 I=1,6000 CALL MAP(1) IF((EMAP(I).GE.'1').AND.(EMAP(I).LE.'8')) CALL TRAN(EMAP(I)) CALL MAP(2) IF((RMAP(I).GE.'1').AND.(RMAP(I).LE.'8')) CALL TRAN(RMAP(I)) CALL MAP(5) IF((PMAP(I).GE.'1').AND.(PMAP(I).LE.'8')) CALL TRAN(PMAP(I)) 1850 CONTINUE CALL MAP(4) READ(1) RLMAP READ(1) TROOPT READ(1) NUMBER READ(1) X,TARGET,FOUND READ(1) OWNER,PHASE DO 1900 I=1,16 1900 CALL READ(IOTAB(I),LIMIT(I),I) CALL MAP(8) IF (VERSION.LE.4) READ(1) (J1TS(I),I=1,1500) IF (VERSION.GE.5) READ(1) J1TS READ(1) NUM READ(1) LOCI READ(1) NSHIFT,FIPATH 2000 CLOSE(UNIT=1) I=RND(10) !KICK THE GENERATOR TO START IT. TYPE 996,PAMELA,REEED 996 FORMAT(' Ready to resume game terminated at ',8A1,' on ', 1 9A1,/) MODE=1 ISEC=-1 RETURN 2200 TYPE 995 995 FORMAT (' Unable to open save file, EMSAVE.DAT, Starting new game.') GOTO 100 END C SUBROUTINE READ(BEG,LIM,NUM) C INCLUDE 'EMPIRE.INC/NOLIST' C DO 100 J=BEG+1,BEG+LIM READ(1) K CALL MAP(4) RLMAP(J)=K CALL MAP(7) IF (NUM.LT.9) READ(1) MYCODE(J) IF (NUM.EQ.10) READ(1) RANG(J-2000) CALL MAP(6) IF (NUM.GT.8) READ(1) CODEFU(J-1500),CODELA(J-1500) CALL MAP(8) IF (NUM.EQ.9) READ(1) AR2S(J-1500) IF (NUM.EQ.2) READ(1) RANGE(J-500) 100 CONTINUE RETURN END C SUBROUTINE WRITE(BEG,LIM,NUM) C INCLUDE 'EMPIRE.INC/NOLIST' C DO 100 J=BEG+1,BEG+LIM CALL MAP(4) K=RLMAP(J) WRITE(1) K CALL MAP(7) IF (NUM.LT.9) WRITE(1) MYCODE(J) IF (NUM.EQ.10) WRITE(1) RANG(J-2000) CALL MAP(6) IF (NUM.GT.8) WRITE(1) CODEFU(J-1500),CODELA(J-1500) CALL MAP(8) IF (NUM.EQ.9) WRITE(1) AR2S(J-1500) IF (NUM.EQ.2) WRITE(1) RANGE(J-500) 100 CONTINUE RETURN END C SUBROUTINE INITIA(FLAG) C INCLUDE 'EMPIRE.INC/NOLIST' BYTE DECODE EXTERNAL DECODE BYTE CHR C IF (FLAG .EQ. 0) GOTO 50 COUNT=0 DO 30 I=1,6000 C IF (FLAG.NE.0) OMAP(I)=DECODE(I) CHR = DECODE(I) CALL MAP(2) RMAP(I) = 0 IF (CHR .EQ. '*') THEN RMAP(I) = 1 CHR = '.' ENDIF IF (CHR .EQ. '.') COUNT=COUNT+1 CALL MAP(3) OMAP(I) = CHR 30 CONTINUE CALL CITDEF(COUNT,1) 50 CALL MAP(3) DO 300 I=1,6000 IF (OMAP(I).NE.'*') GOTO 300 N1=RND(70)+1 !** DO 100 N3=N1,N1+70 N=N3 IF (N.GT.70) N=N-70 100 IF (X(N).EQ.0) GOTO 200 200 X(N)=I 300 CONTINUE RETURN END SUBROUTINE TRAN(AB) C C TRANSLATE OLD ENEMY UNITS TO NEW CHARACTERS C INCLUDE 'EMPIRE.INC/NOLIST' BYTE OLDE(8),NEWE(8) DATA OLDE/'1','2','3','4','5','6','7','8'/ DATA NEWE/'a','f','d','s','t','r','c','b'/ DO 10 I=1,8 10 IF(AB.EQ.OLDE(I)) AB=NEWE(I) RETURN END SUBROUTINE ENCODE(SEA) INCLUDE 'EMPIRE.INC/NOLIST' INTEGER MSKTAB(9) DATA MSKTAB/1,3,9,27,81,243,729,2187,6561/ C CALL MAP(7) D(1) = 0 DPTR = 1 MPTR = 1 DO 100 I=1,6000 CALL MAP(3) AB = OMAP(I) CALL MAP(7) IF (AB .NE. '.') THEN D(DPTR) = D(DPTR) + MSKTAB(MPTR) ELSE CALL MAP(2) IF (RMAP(I).EQ.SEA) THEN CALL MAP(7) D(DPTR) = D(DPTR) + 2*MSKTAB(MPTR) ENDIF ENDIF MPTR = MPTR + 1 IF (MPTR .EQ. 10) THEN MPTR = 1 DPTR = DPTR + 1 CALL MAP(7) D(DPTR) = 0 ENDIF 100 CONTINUE RETURN END BYTE FUNCTION DECODE(Z6) C C UNPACK MAP DEFINITION FILE C D() = MAP DEFINITION FROM MAP FILE C Z6 = LOCATION C DECODE = CHARACTER AT Z6 C C MAPS ARE ENCODED USING MOD 3 ARITHMETIC TO FIT 9 CHARACTERS INTO ONE 16-BIT C WORD. C INCLUDE 'EMPIRE.INC/NOLIST' INTEGER MSKTAB(9) BYTE ASCII(3) DATA ASCII/'.','+','*'/ DATA MSKTAB/1,3,9,27,81,243,729,2187,6561/ C IX=((Z6-1)/9)+1 IY=MOD(Z6-1,9)+1 CALL MAP(7) DECODE=ASCII(MOD(D(IX)/MSKTAB(IY),3)+1) RETURN END C C RANDOM MAP GENERATION SUBROUTINES C SUBROUTINE GEN IMPLICIT INTEGER(A-Z) PARAMETER WIDTH=100,HEIGHT=60 BYTE MAP1(WIDTH,HEIGHT) BYTE SUBMAP(39,39) BYTE OWNER(WIDTH,HEIGHT) INTEGER SIZES(128) COMMON/CITIES/CITIES(128) COMMON/SMAP/SUBMAP C BYTE EMAP(6000),RMAP(6000),PMAP(6000),OMAP(6000) INTEGER RLMAP(3000) C COMMON/MAPBLK/EMAP,RMAP,PMAP,RLMAP C COMMON/OMAP/OMAP COMMON /MAPPED/ RLMAP EQUIVALENCE (MAP1(1,1),RLMAP(1)),(OWNER(1,1),RLMAP(1)) 100 CALL MAP(3) DO 200 I=1,WIDTH DO 200 J=1,HEIGHT 200 MAP1(I,J)='.' HSECTS=3+RND(4) VSECTS=3+RND(3) HSPACE=WIDTH/HSECTS VSPACE=HEIGHT/VSECTS DO 400 I=1,HSECTS DO 400 J=1,VSECTS DO 400 K=1,RND(2)+RND(3) CALL MAKELAND YPOS=(J-1)*VSPACE+RND(VSPACE) XPOS=(I-1)*HSPACE+RND(HSPACE) DO 300 L=1,39 DO 300 M=1,39 IF (SUBMAP(L,M).EQ.' ') GOTO 300 IF (((XPOS+L-20).LE.0).OR.((XPOS+L-20).GT.100)) GOTO 300 IF (((YPOS+M-20).LE.0).OR.((YPOS+M-20).GT.60)) GOTO 300 MAP1(XPOS+L-20,YPOS+M-20)=SUBMAP(L,M) 300 CONTINUE 400 CONTINUE COUNT=0 DO 500 I=1,100 DO 500 J=1,60 IF (MAP1(I,J).EQ.'.') COUNT=COUNT+1 500 CONTINUE IF (COUNT.LT.4000.AND.COUNT.GT.2500) GOTO 600 C TYPE 999,COUNT C WRITE (1,999) COUNT C999 FORMAT(' FAILED SEA CHECK, COUNT=',I5) GOTO 100 C600 TYPE 998,COUNT C WRITE (1,998) COUNT C998 FORMAT(' COUNT=',I5) 600 CONTINUE CALL MAP(2) DO 800 I=1,100 DO 800 J=1,60 OWNER(I,J)=0 800 CONTINUE LAREA=1 WAREA=33 OPEN (UNIT=2,FILE='STACK.TMP',TYPE='SCRATCH', ACCESS='DIRECT', 1 RECORDSIZE=2) DO 1000 I=2,99 DO 1000 J=2,59 CALL MAP(2) IF (OWNER(I,J).NE.0) GOTO 1000 CALL MAP(3) IF (MAP1(I,J).NE.'.') GOTO 830 IF (SET(I,J,WAREA,'.',12000).EQ.0) GOTO 850 WAREA=WAREA+1 GOTO 1000 830 IF (SET(I,J,LAREA,'+',1200).EQ.1) GOTO 900 C TYPE 997 C WRITE (1,997) C997 FORMAT(' FAILED SINGLE LAND MASS TEST') 850 CLOSE (UNIT=2) GOTO 100 900 LAREA=LAREA+1 1000 CONTINUE CLOSE (UNIT=2) IF (LAREA.GE.10.AND.LAREA.LE.30) GOTO 1100 C TYPE 996, LAREA C WRITE(1,996) LAREA C996 FORMAT(' FAILED SEPARATION TEST',I10) GOTO 100 C1100 CALL MAP(2) C TYPE 995,(('@'+OWNER(I,J),I=1,100),J=1,60) C WRITE(1,995) (('@'+OWNER(I,J),I=1,100),J=1,60) C995 FORMAT(1X,100A1) 1100 CONTINUE DO 1300 I=1,128 1300 SIZES(I)=0 CALL MAP(2) DO 1400 I=2,99 DO 1400 J=2,59 SIZES(OWNER(I,J))=SIZES(OWNER(I,J))+1 1400 CONTINUE SCOUNT=COUNT*40/50 DO 1500 SEA=33,WAREA 1500 IF (SIZES(SEA).GE.SCOUNT) GOTO 1600 C TYPE 994 C WRITE (1,994) C994 FORMAT(' FAILURE- OCEANS ARE SEPARATED') GOTO 100 1600 CALL CITDEF(COUNT,SEA) CALL ENCODE(SEA) RETURN END SUBROUTINE CITDEF(COUNT,SEA) IMPLICIT INTEGER(A-Z) PARAMETER WIDTH=100,HEIGHT=60 BYTE MAP1(WIDTH,HEIGHT) BYTE OWNER(WIDTH,HEIGHT) COMMON/CITIES/CITIES(128) C BYTE EMAP(6000),RMAP(6000),PMAP(6000),OMAP(6000) INTEGER RLMAP(3000) C COMMON/MAPBLK/EMAP,RMAP,PMAP,RLMAP C COMMON/OMAP/OMAP COMMON /MAPPED/ RLMAP EQUIVALENCE (MAP1(1,1),RLMAP(1)),(OWNER(1,1),RLMAP(1)) 1600 CITS=(6000-COUNT)/50+1 CITS=MAX(52,CITS) CITS=MIN(70,CITS) SEACITS=CITS*60/100+RND(12) LANDCITS=CITS-SEACITS DO 2100 K=1,SEACITS 1700 I=RND(98)+2 J=RND(58)+2 CALL MAP(3) IF (MAP1(I,J).NE.'+') GOTO 1700 CALL MAP(2) DO 1800 L=MAX(2,I-1),MIN(99,I+1) DO 1800 M=MAX(2,J-1),MIN(59,J+1) IF (OWNER(L,M).EQ.SEA) GOTO 1900 1800 CONTINUE GOTO 1700 1900 DO 2000 L=MAX(2,I-3),MIN(99,I+3) DO 2000 M=MAX(2,J-3),MIN(59,J+3) CALL MAP(2) IF (OWNER(L,M).NE.OWNER(I,J)) GOTO 2000 CALL MAP(3) IF (MAP1(L,M).EQ.'*') GOTO 1700 2000 CONTINUE CALL MAP(3) MAP1(I,J)='*' CALL MAP(2) CITIES(OWNER(I,J))=CITIES(OWNER(I,J))+100 2100 CONTINUE DO 2500 K=1,LANDCITS 2200 I=RND(98)+2 J=RND(58)+2 CALL MAP(3) IF (MAP1(I,J).NE.'+') GOTO 2200 DO 2300 L=MAX(2,I-1),MIN(99,I+1) DO 2300 M=MAX(2,J-1),MIN(59,J+1) IF (MAP1(L,M).EQ.'.') GOTO 2200 2300 CONTINUE DO 2400 L=MAX(2,I-2),MIN(99,I+2) DO 2400 M=MAX(2,J-2),MIN(59,J+2) CALL MAP(2) IF (OWNER(L,M).NE.OWNER(I,J)) GOTO 2400 CALL MAP(3) IF (MAP1(L,M).EQ.'*') GOTO 2200 2400 CONTINUE CALL MAP(3) MAP1(I,J)='*' CALL MAP(2) CITIES(OWNER(I,J))=CITIES(OWNER(I,J))+1 2500 CONTINUE C CALL MAP(3) C TYPE 993,((MAP1(I,J),I=1,100),J=1,60) C WRITE(1,993) ((MAP1(I,J),I=1,100),J=1,60) 993 FORMAT(1X,100A1) END SUBROUTINE MAKELAND IMPLICIT INTEGER(A-Z) BYTE SUBMAP(39,39) REAL DIVER,RAD,COSANG,SINANG COMMON/SMAP/SUBMAP DO 100 I=1,39 DO 100 J=1,39 SUBMAP(I,J)=' ' 100 CONTINUE SUBMAP(20,20)='+' VARY=2+RND(3) RADIUS=RND(4)+RND(3) START=90-RND(180) DO 400 ROT=START,START+360,3 IF (RADIUS.LE.0) GOTO 300 COSANG=COS(FLOAT(ROT)/3.14159) SINANG=SIN(FLOAT(ROT)/3.14159) RAD=0 DIVER=.5/(ABS(COSANG)+ABS(SINANG)) 200 IF (RAD.GT.RADIUS) GOTO 300 RAD=RAD+DIVER SUBMAP(20+RAD*COSANG,20+RAD*SINANG)='+' GOTO 200 300 IF (MOD(ROT,10).NE.0) GOTO 400 RADIUS=RADIUS+RND(VARY)-(VARY/2) IF ((VARY.AND.1).EQ.0) RADIUS=RADIUS+RND(2) IF (RADIUS.GE.12) RADIUS=11 400 CONTINUE RETURN END FUNCTION SET(XPOS,YPOS,AREA,LS,LIMIT) IMPLICIT INTEGER(A-Z) PARAMETER WIDTH=100,HEIGHT=60 BYTE MAP1(WIDTH,HEIGHT) BYTE OWNER(WIDTH,HEIGHT) C BYTE XSTACK(12000) C BYTE YSTACK(12000) C BYTE CSTACK(12000) BYTE LS INTEGER XADDS(8),YADDS(8) DATA XADDS/-1,0,1,-1,1,-1,0,1/ DATA YADDS/-1,-1,-1,0,0,1,1,1/ C BYTE EMAP(6000),RMAP(6000),PMAP(6000),OMAP(6000) INTEGER RLMAP(3000) C COMMON/MAPBLK/EMAP,RMAP,PMAP,RLMAP C COMMON/OMAP/OMAP COMMON/MAPPED/RLMAP EQUIVALENCE (MAP1(1,1),RLMAP(1)),(OWNER(1,1),RLMAP(1)) CALL MAP(2) OWNER(XPOS,YPOS)=AREA LEVEL=1 X=XPOS Y=YPOS 100 K=1 200 IF ((X+XADDS(K).LT.2).OR.(X+XADDS(K).GT.99)) GOTO 300 IF ((Y+YADDS(K).LT.2).OR.(Y+YADDS(K).GT.59)) GOTO 300 CALL MAP(3) IF (MAP1(X+XADDS(K),Y+YADDS(K)).NE.LS) GOTO 300 CALL MAP(2) IF (OWNER(X+XADDS(K),Y+YADDS(K)).NE.0) GOTO 300 OWNER(X+XADDS(K),Y+YADDS(K))=AREA C XSTACK(LEVEL)=X C YSTACK(LEVEL)=Y C CSTACK(LEVEL)=K WRITE (2'LEVEL) X,Y,K LEVEL=LEVEL+1 IF (LEVEL.GT.LIMIT) THEN SET=0 RETURN ENDIF X=X+XADDS(K) Y=Y+YADDS(K) GOTO 100 300 K=K+1 IF (K.LE.8) GOTO 200 LEVEL=LEVEL-1 IF (LEVEL.EQ.0) THEN SET=1 RETURN ENDIF C X=XSTACK(LEVEL) C Y=YSTACK(LEVEL) C K=CSTACK(LEVEL) READ (2'LEVEL) X,Y,K GOTO 300 END