DEFINE(DIG0,48) # ASCII "0" PROGRAM PLAYEM # # AUTHOR: DON LEDFORD OCTOBER 1979 # MAY 1980 BILL CAEL AND BILL WOOD RECODED IN RATFOR # AUG 1980 BILL CAEL AND BILL WOOD IMPROVED ROBOT STRATEGIES # INCLUDE COMMON.RAT LOGICAL*1 DONE,OK INTEGER SCON(8) # # # NS=0 WRITE(5,1) 1 FORMAT('0ENTER THE NUMBERS FOR THE SHIPS TO BE RUN') DONE=.FALSE. REPEAT [ WRITE(5,11) 11 FORMAT('0THE FOLLOWING VESSELS ARE AVAILABLE FOR USE') DO I=1, 8 [ IF (! XSHIP(I)) [ WRITE(5,21) I 21 FORMAT(' SHIP ',I1) ] ] WRITE(5,31) 31 FORMAT('$SHIP NUMBER? ') CALL GETINT(IW,OK,1,8) IF (OK ) [ NS=NS+1 SCON(NS)=IW XSHIP(IW)=.TRUE. ] ] UNTIL (! OK | (NS > 7)) IF (NS == 0) CALL EXIT WRITE(5,41) 41 FORMAT('$ENTER MAX SPEED OF ROBOT SHIPS (INTEGER 1-8): ') CALL GETINT(IR,OK,1,8) IF (OK) [ WP=IR ] ELSE [ WP=8. ] WRITE(5,51) 51 FORMAT('$ENTER REACTION TIME OF ROBOTS (1-5, 1 IS FASTEST): ') CALL GETINT(IR,OK,1,5) IF (OK) [ IR=(IR*2*UPRATE)/3 ] ELSE [ IR=UPRATE ] WRITE(5,61) 61 FORMAT('$ENTER AMOUNT OF PHASER FIRE FROM ROBOTS (1-5): ') CALL GETINT(IP,OK,1,5) IF (OK) [ IP=IP+1 ] ELSE [ IP=6 ] WRITE(5,71) 71 FORMAT('$ENTER AVERAGE DEGREE OF INACCURACY (0-90): ') CALL GETINT(MIS,OK,0,90) IF (! OK) [ MIS=0 ] REPEAT [ DO IIT=1, 6 [ DO I=1, NS [ CALL PLAY(SCON,I,IIT,WP,IP,MIS) ] CALL WAIT(IR,0,M) ] ] UNTIL (DONE) CALL EXIT END SUBROUTINE INTERS(TDIR,DIRT,WT,WP,ANG) # # COMPUTE INTERSECTION # A1=TDIR/57.29577951 A2=DIRT/57.29577951 ANG=ASIN(SIN(A2-A1)*WT/WP)*57.29577951 + TDIR RETURN END SUBROUTINE SCANER(SCON,IW,ENUM,EDIS,PDIS,BDIS,HDIS, EDIR,PDIR,BDIR,HDIR) INCLUDE COMMON.RAT INTEGER ENUM,WHO,SCON(8) BYTE ALPHA REAL D1(4) # # # # BDIS=1.6E37 EDIS=1.6E37 PDIS=1.6E37 HDIS=1.6E37 WHO=SCON(IW) ID=SCAN(WHO) X=XCORD(WHO) Y=YCORD(WHO) # DO IX= -ID, + ID [ IX1=X + IX DO IY= -ID, ID [ IY1=Y + IY IF ((IX1 >= 1) & (IX1 <= 100) & (IY1 >= 1) & (IY1 <= 100)) [ ALPHA= UNIV(IX1,IY1) IF (ALPHA != EMPTY & ALPHA != '*') [ D=( (X-IX1)**2 + (Y-IY1)**2)**.5 RY=IY1 RX=IX1 DUR=DIRNRM(ATAN3((RY+.5-Y),(RX+.5-X))*57.29577951,360.) IF (ALPHA == 'B') [ IF (D < BDIS) [ BDIS=D BDIR=DUR ] # ] ELSE IF (ALPHA == BHOLE) [ HDIS=D HDIR=DUR # ] ELSE IF (ALPHA == '@') [ IF (D < PDIS) [ PDIS=D PDIR=DUR ] # ] # ] ] ] ] # # * FIND CLOSEST ENEMY # DO I=1, 8 [ IF (XSHIP(I)) [ DO K=1, 8 [ IF (SCON(K) == I) [ GOTO 101 ] ] X1=XCORD(I) IF (X1 < 50.) [ X2=X1+100. ] ELSE [ X2=X1-100. ] Y1=YCORD(I) IF (Y1 < 50.) [ Y2=Y1+100. ] ELSE [ Y2=Y1-100. ] D1(1)=((X-X1)**2 + (Y-Y1)**2)**.5 D1(2)=((X-X1)**2 + (Y-Y2)**2)**.5 D1(3)=((X-X2)**2 + (Y-Y1)**2)**.5 D1(4)=((X-X2)**2 + (Y-Y2)**2)**.5 IIT=1 DO J=2, 4 [ IF (D1(J) < D1(IIT)) [ IIT=J ] ] D=D1(IIT) IF (IIT == 1) [ YD=Y1 XD=X1 ] ELSE IF (IIT == 2) [ YD=Y2 XD=X1 ] ELSE IF (IIT == 3) [ YD=Y1 XD=X2 ] ELSE [ YD=Y2 XD=X2 ] IF (D < EDIS) [ EDIS=D ENUM=I EDIR=DIRNRM(ATAN3((YD-Y),(XD-X))*57.29577951,360.) ] 101 CONTINUE ] ] RETURN END REAL FUNCTION DIRNRM(DIR,POSLIM) IF (DIR > POSLIM) DIRNRM = DIR-360. ELSE IF (DIR < POSLIM-360.) DIRNRM = DIR+360. ELSE DIRNRM = DIR RETURN END SUBROUTINE PLAY(SCON,IW,IIT,WP,IP,MIS) INCLUDE COMMON.RAT INTEGER WHO INTEGER ENUM INTEGER SCON(8) BYTE ALPHA LOGICAL*1 OK # WHO=SCON(IW) R=RAN(I1I,I2I) CALL SCANER(SCON,IW,ENUM,EDIS,PDIS,BDIS,HDIS, EDIR,PDIR,BDIR,HDIR) CALL INTERS(EDIR,DIR(ENUM),WARP(ENUM),10.,ANG) #$ IF (EDIS >= 5.) #$ NET(WHO) = .FALSE. IF (PDIS < 5. & (TORPS(WHO) > 0) & IIT == 5) [ IF (LAUNCH(WHO) < 0.) [ TORPS(WHO)=TORPS(WHO)-1 LAUNCH(WHO)=PDIR ] # ] ELSE IF (EDIS < 10.) [ IF (R < .4) [ IF (PHA(WHO) < 0. & IP > IIT & ENERGY(WHO) > 500.) [ PHA(WHO)=EDIR ENERGY(WHO)=ENERGY(WHO)-50. ] # ] ELSE [ IF (LAUNCH(WHO) < 0. & TORPS(WHO) > 0 & (IIT == 1 | IIT == 4 )) [ ANG=DIRNRM(ANG + MIS-2*MIS*RAN(I1I,I2I),360.) LAUNCH(WHO)=ANG TORPS(WHO)=TORPS(WHO)-1 ] ELSE IF (NHOM(WHO) > 0 & IIT == 1) [ NHOM(WHO) = NHOM(WHO) - 1 WHOM(WHO, NHOM(WHO)) = -ENUM ] ] ] ELSE IF (EDIS < 20. & (IIT == 1) & NHOM(WHO) > 2) [ NHOM(WHO) = NHOM(WHO) - 1 WHOM(WHO, NHOM(WHO)) = -ENUM ] IF (ENERGY(WHO) < 2500.) [ IF (BDIS < 11.) [ DUR=BDIR ] ELSE [ DUR=180.-EDIR IF (EDIS < 20. & NHOM(WHO) > 0. & (IIT == 2 | IIT == 4)) [ NHOM(WHO)=NHOM(WHO)-1 WHOM(WHO,NHOM(WHO))=-ENUM ] ] ] ELSE IF (EDIS > 10. & BDIS < 11. & (NHOM(WHO) <= 1 | TORPS(WHO) <= 6 | ENERGY(WHO) < 4000.)) [ DUR = BDIR ] ELSE IF (EDIS > 10.) [ DUR=ANG-10. ] ELSE IF (EDIS < 5.) [ DUR = ANG + 80. #$ NET(WHO) = .TRUE. ] ELSE IF (EDIS < 10.) [ #$ DUR=ANG + 90. - 180.*RAN(I1I,I2I) DUR = ANG + 20. ] IF (HDIS < 10.) [ IF (HDIS < 5.) DUR = 180.-HDIR ELSE IF (ABS(DIRNRM(HDIR-DUR,180.)) < 90.) [ IF (DIRNRM(HDIR-DUR,180.) < 0.) DUR = HDIR+90. ELSE DUR = HDIR-90. ] ] # OK =.FALSE. REPEAT [ IX=XCORD(WHO) + COS(DUR/57.29577951)*.8 IY=YCORD(WHO) + SIN(DUR/57.29577951)*.8 IF (IX > 100) [ IX=1 ] IF (IX < 1) [ IX=100 ] IF (IY > 100) [ IY=1 ] IF (IY < 1) [ IY=100 ] ALPHA=UNIV(IX,IY) IF ((ALPHA == -WHO) | (ALPHA == EMPTY) | ((ALPHA == 'B') & (ENERGY(WHO) < 8000. | NHOM(WHO) <= 1 | TORPS(WHO) <= 6)) | (ALPHA == WHO+DIG0)) [ OK=.TRUE. ] ELSE [ IF (R > .5) [ DUR=DUR + 45. ] ELSE [ DUR=DUR - 45. ] ] ] UNTIL (OK) DIR(WHO)=DIRNRM(DUR,360.) WARP(WHO)=WP IF (SHIELD(WHO) < 1200. & ENERGY(WHO) > 1500.) [ ENERGY(WHO)=ENERGY(WHO)+SHIELD(WHO)-1200. SHIELD(WHO)=1200. ] ELSE IF (ENERGY(WHO) < 500.) [ ENERGY(WHO) = ENERGY(WHO) + SHIELD(WHO)/2. SHIELD(WHO) = SHIELD(WHO)/2. ] XSHIP(WHO)=.TRUE. RETURN END SUBROUTINE GETINT(NUM,FLAG,LOW,HIGH) INTEGER NUM,LOW,HIGH LOGICAL*1 OK,FLAG OK=.FALSE. REPEAT [ READ(5,12,END=805,ERR=205) NCHRS,NUM 12 FORMAT(Q,I5) GOTO 806 805 CLOSE(UNIT=5) 806 CONTINUE IF (NCHRS == 0) [ FLAG=.FALSE. OK=.TRUE. ] ELSE [ IF ((NUM >= LOW) & (NUM <= HIGH)) [ OK=.TRUE. FLAG=.TRUE. ] ELSE [ WRITE(5,81) LOW,HIGH 81 FORMAT('0** NUMBER MUST BE BETWEEN ',I5,' AND ',I5) WRITE(5,91) 91 FORMAT(1H$,' TRY AGAIN :') ] GOTO 305 205 WRITE(5,101) 101 FORMAT(1H$,' ** INVALID NUMERIC, TRY AGAIN :') 305 CONTINUE ] ] UNTIL (OK) RETURN END