REM SUB INPUT: X,Y,DIR,X1,Y1,DIR1,CODE REM DIR is 1=UP, 2=RIGHT, 3=DOWN, 4=LEFT REM RETURN_T CODE 1=FORWARD, 2=TURN RIGHT, 3=TURN LEFT and 4=FIRE REM Do not remain stationary more than 3 TURNs REM Firing range 8 units, 45 degree each side FOV, 90 degree movement REM Code by Tursi - 2/17/2023 REM CHECK IF WE TELEPORTED, THAT WOULD MEAN A RESTART IF ABS(OLDX-X)<=1 AND ABS(OLDY-Y)<=1 THEN GOTO NOTP_T OLDX1=0::OLDY1=0::SRCHDIR=0 NOTP_T: REM CHOOSE SEARCH DIRECTION SO WE DON'T WASTE TIME GETTING INTO POSITION REM 1=CW, 2=CCW IF SRCHDIR<>0 THEN GOTO GOTDIR_T IF Y>12 THEN SRCHDIR=1 ELSE SRCHDIR=2 GOTDIR_T: REM SAVE LOCATION TO DETECT TELEPORT OLDX=X::OLDY=Y REM GET 'QUADRANT' AND REPORT IT Q=INT(X/8)+INT(Y/8)*4+1 REM FIGURE OUT WHAT TO DO IF X1=0 then GOTO HUNT_T OLDX1=X1 OLDY1=Y1 OLDDIR=DIR1 RANGE=SQR((X1-X)^2+(Y1-Y)^2) IF RANGE>8 THEN GOTO PURSUE_T IF INT(X)<>INT(X1) AND INT(Y)<>INT(Y1) THEN GOTO PURSUE_T REM ENEMY IN SIGHT AND RANGE, DESTROY IF NO WALL IN THE WAY OK=1 XB=X::YB=Y IF DIR=1 THEN XD=0::YD=-1 IF DIR=2 THEN XD=1::YD=0 IF DIR=3 THEN XD=0::YD=1 IF DIR=4 THEN XD=-1::YD=0 FOR I=1 TO RANGE XB=XB+XD::YB=YB+YD IF XB<2 OR XB>31 OR YB<2 OR YB>23 THEN GOTO SKIP1_T CALL GCHAR(YB,XB,C) IF C=101 THEN OK=0 SKIP1_T: NEXT I IF OK=0 THEN GOTO PURSUE_T REM IF WE FIRED LAST TURN_T, SOMETHING IS IN THE WAY, SO MOVE_T (ALSO SAVES FROM SELF DESTRUCT) IF LAST=4 THEN GOTO PURSUE_T REM WE'RE GOOD - BLOW HIM UP! GOTO SHOOT_T REAQUIRE_T: REM GET CLOSER TO THE LAST PLACE WE SAW THEM REM UPDATE PREDICTED LOCATION IF OLDDIR=1 THEN OLDY1=OLDY1-1::IF OLDY1<2 THEN OLDY1=2 IF OLDDIR=2 THEN OLDX1=OLDX1+1::IF OLDX1>31 THEN OLDX1=31 IF OLDDIR=3 THEN OLDY1=OLDY1+1::IF OLDY1>23 THEN OLDY1=23 IF OLDDIR=4 THEN OLDX1=OLDX1-1::IF OLDX1<2 THEN OLDX1=2 REM START WORKING IT MX1=OLDX1::MY1=OLDY1 REM IF WE ARE WITHIN 2 UNITS, THAT'S CLOSE ENOUGH REM SAVES US FROM SEEKING IF WE CAN'T GET ALL THE WAY THERE IF SQR((OLDX1-X)^2+(OLDY1-Y)^2)>2 THEN GOTO PURSUE2_T OLDX1=0::OLDY1=0 GOTO PURSUE2_T PURSUE_T: MX1=X1 MY1=Y1 PURSUE2_T: REM DETERMINE WHICH WAY TO GO XRANGE=MX1-X YRANGE=MY1-Y IF ABS(XRANGE)>ABS(YRANGE) THEN GOTO HORIZ_T IF MY1>Y THEN GOTO DOWN_T REM MOVE UP, THEN DES=1 GOTO MOVE_T DOWN_T: DES=3 GOTO MOVE_T HORIZ_T: IF MX1>X THEN GOTO RIGHT_T DES=4 GOTO MOVE_T RIGHT_T: DES=2 GOTO MOVE_T MOVE_T: IF DIR<>DES THEN GOTO TESTTURN_T REM ALREADY FACING THE RIGHT WAY, SO MOVE FORWARD GOTO FWD_T TESTTURN_T: REM IN EVENT WE ARE EVADING AN OBSTACLE - WE'LL JUST USE A SHORTER RANGE TEST REM IF THE DESIRED MOVE ISN'T CLEAR, THEN DO OBSTACLE AVOIDANCE INSTEAD OK=1 XB=X::YB=Y IF DES=1 THEN XD=0::YD=-1 IF DES=2 THEN XD=1::YD=0 IF DES=3 THEN XD=0::YD=1 IF DES=4 THEN XD=-1::YD=0 FOR I=1 TO 1 XB=XB+XD::YB=YB+YD IF XB<2 OR XB>31 OR YB<2 OR YB>23 THEN GOTO SKIP2_T CALL GCHAR(YB,XB,C) IF C=101 THEN OK=0 SKIP2_T: NEXT I IF OK=0 THEN GOTO AVOID_T GOTO TURN_T TURN_T: REM ONE OF THESE SHOULD HIT IF DES=1 AND (DIR=2 OR DIR=3) THEN CODE=3 IF DES=1 AND DIR=4 THEN CODE=2 IF DES=2 AND (DIR=3 OR DIR=4) THEN CODE=3 IF DES=2 AND DIR=1 THEN CODE=2 IF DES=3 AND (DIR=4 OR DIR=1) THEN CODE=3 IF DES=3 AND DIR=2 THEN CODE=2 IF DES=4 AND (DIR=1 OR DIR=2) THEN CODE=3 IF DES=4 AND DIR=3 THEN CODE=2 REM WE DON'T REALLY NEED TO CHECK THIS AGAINST WALLS GOTO DONE_T HUNT_T: IF INT(X1)=INT(OLDX) AND INT(Y1)=INT(OLDY) THEN OLDX=0::OLDY=0 IF OLDX1<>0 THEN GOTO REAQUIRE_T IF SRCHDIR=2 THEN GOTO SRCHCCW_T REM CLOCKWISE SEARCH IF Q=1 THEN IF Y<5 THEN GOTO MOVERIGHT_T ELSE GOTO MOVEUP_T IF Q=2 THEN GOTO MODE2_T IF Q=3 THEN GOTO MODE3_T IF Q=4 THEN IF X<30 THEN GOTO MOVERIGHT_T ELSE GOTO MOVEDOWN_T IF Q=5 THEN GOTO MODE5_T IF Q=6 THEN GOTO MODE5_T IF Q=7 THEN GOTO MODE7_T IF Q=8 THEN GOTO MODE7_T IF Q=9 THEN IF X>3 THEN GOTO MOVELEFT_T ELSE GOTO MOVEUP_T IF Q=10 THEN GOTO MODE10_T IF Q=11 THEN GOTO MODE11_T IF Q=12 THEN IF Y>19 THEN GOTO MOVELEFT_T ELSE GOTO MOVEDOWN_T SRCHCCW_T: REM COUNTER-CLOCKWISE SEARCH IF Q=1 THEN IF X>3 THEN GOTO MOVELEFT_T ELSE GOTO MOVEDOWN_T IF Q=2 THEN GOTO MODE2_T IF Q=3 THEN GOTO MODE3_T IF Q=4 THEN IF Y<5 THEN GOTO MOVELEFT_T ELSE GOTO MOVEUP_T IF Q=5 THEN GOTO MODE5_T IF Q=6 THEN GOTO MODE5_T IF Q=7 THEN GOTO MODE7_T IF Q=8 THEN GOTO MODE7_T IF Q=9 THEN IF Y>19 THEN GOTO MOVERIGHT_T ELSE GOTO MOVEDOWN_T IF Q=10 THEN GOTO MODE10_T IF Q=11 THEN GOTO MODE11_T IF Q=12 THEN IF X<30 THEN GOTO MOVERIGHT_T ELSE GOTO MOVEUP_T REM MOVE COMMANDS MOVERIGHT_T: IF DIR=2 THEN GOTO FWD_T GOTO FACER_T TURNRIGHT_T: IF DIR=2 THEN GOTO SHOOT_T GOTO FACER_T FACER_T: DES=2 GOTO TESTTURN_T MOVELEFT_T: IF DIR=4 THEN GOTO FWD_T GOTO FACEL_T TURNLEFT_T: IF DIR=4 THEN GOTO SHOOT_T GOTO FACEL_T FACEL_T: DES=4 GOTO TESTTURN_T MOVEDOWN_T: IF DIR=3 THEN GOTO FWD_T GOTO FACED_T TURNDOWN_T: IF DIR=3 THEN GOTO SHOOT_T GOTO FACED_T FACED_T: DES=3 GOTO TESTTURN_T MOVEUP_T: IF DIR=1 THEN GOTO FWD_T GOTO FACEU_T TURNUP_T: IF DIR=1 THEN GOTO SHOOT_T GOTO FACEU_T FACEU_T: DES=1 GOTO TESTTURN_T FWD_T: CODE=1 GOTO TESTWALL_T SHOOT_T: CODE=4 GOTO DONE_T REM STATE HANDLERS, IF NOT DIRECT MODE2_T: IF LAST2=1 THEN GOTO MODE2_TR IF LAST2=2 THEN LAST2=0::GOTO FWD_T GOTO MODE2_TD MODE2_TD: IF DIR=3 THEN LAST2=1::GOTO MODE2_TR GOTO TURNDOWN_T MODE2_TR: IF SRCHDIR=2 THEN GOTO MODE2_TL IF DIR=2 THEN LAST2=2 GOTO MOVERIGHT_T MODE2_TL: IF DIR=4 THEN LAST2=2 GOTO MOVELEFT_T MODE3_T: IF LAST2=1 THEN GOTO MODE3_TR IF LAST2=2 THEN LAST2=0::GOTO FWD_T GOTO MODE3_TD MODE3_TD: IF DIR=3 THEN LAST2=1::GOTO MODE3_TR GOTO TURNDOWN_T MODE3_TR: IF SRCHDIR=2 THEN GOTO MODE3_TL IF DIR=2 THEN LAST2=2 GOTO MOVERIGHT_T MODE3_TL: IF DIR=4 THEN LAST2=2 GOTO MOVELEFT_T MODE5_T: IF LAST2=1 THEN GOTO MODE5_TUD GOTO MODE5_TR MODE5_TUD: IF SRCHDIR=2 THEN GOTO MOVEDOWN_T GOTO MOVEUP_T MODE5_TR: IF DIR=2 THEN LAST2=1::GOTO MODE5_TUD GOTO TURNRIGHT_T MODE7_T: IF LAST2=1 THEN GOTO MODE7_TUD GOTO MODE7_TL MODE7_TUD: IF SRCHDIR=2 THEN MOVEUP_T GOTO MOVEDOWN_T MODE7_TL: IF DIR=4 THEN LAST2=1::GOTO MODE7_TUD GOTO TURNLEFT_T MODE10_T: IF LAST2=1 THEN GOTO MODE10_TL IF LAST2=2 THEN LAST2=0::GOTO FWD_T GOTO MODE10_TU MODE10_TU: IF DIR=1 THEN LAST2=1::GOTO MODE10_TL GOTO TURNUP_T MODE10_TL: IF SRCHDIR=2 THEN MODE10_TR IF DIR=4 THEN LAST2=2 GOTO MOVELEFT_T MODE10_TR: IF DIR=2 THEN LAST2=2 GOTO MOVERIGHT_T MODE11_T: IF LAST2=1 THEN GOTO MODE11_TL IF LAST2=2 THEN LAST2=0::GOTO FWD_T GOTO MODE11_TU MODE11_TU: IF DIR=1 THEN LAST2=1::GOTO MODE11_TL GOTO TURNUP_T MODE11_TL: IF SRCHDIR=2 THEN MODE11_TR IF DIR=4 THEN LAST2=2 GOTO MOVELEFT_T MODE11_TR: IF DIR=2 THEN LAST2=2 GOTO MOVERIGHT_T TESTWALL_T: REM EITHER MOVING OR FIRING, SO CHECK IF ITS SANE. ONLY CHECK ONE POSITION HERE THOUGH OK=1 XB=X::YB=Y IF DIR=1 THEN XD=0::YD=-1 IF DIR=2 THEN XD=1::YD=0 IF DIR=3 THEN XD=0::YD=1 IF DIR=4 THEN XD=-1::YD=0 XB=XB+XD::YB=YB+YD IF XB<2 OR XB>31 OR YB<2 OR YB>23 THEN OK=0::GOTO SKIP3_T CALL GCHAR(YB,XB,C) IF C=101 THEN OK=0 SKIP3_T: IF OK=0 THEN GOTO AVOID_T GOTO DONE_T AVOID_T: REM OBSTACLE AVOIDANCE - FIRST CHECK IF WE ALREADY TURNED, AND JUST MOVE IF SO OK=1 XB=X::YB=Y IF DIR=1 THEN XD=0::YD=-1 IF DIR=2 THEN XD=1::YD=0 IF DIR=3 THEN XD=0::YD=1 IF DIR=4 THEN XD=-1::YD=0 XB=XB+XD::YB=YB+YD IF XB<2 OR XB>31 OR YB<2 OR YB>23 THEN OK=0::GOTO SKIP4_T CALL GCHAR(YB,XB,C) IF C=101 THEN OK=0 SKIP4_T: IF OK=0 THEN GOTO AVTURN_T CODE=1 GOTO DONE_T AVTURN_T: REM PREDEFINED TURN_T BASED ON LOCATION IF Y>12 THEN GOTO AVT2_T QUAD=INT(X/8) IF QUAD=0 THEN CODE=2 ELSE IF QUAD=1 THEN CODE=3 ELSE IF QUAD=2 THEN CODE=3 ELSE CODE=2 GOTO AVTOK_T AVT2_T: QUAD=INT(X/8) IF QUAD=0 THEN CODE=3 ELSE IF QUAD=1 THEN CODE=2 ELSE IF QUAD=2 THEN CODE=2 ELSE CODE=3 GOTO AVTOK_T AVTOK_T: GOTO DONE_T DONE_T: REM SAVE STATE AND EXIT LAST=CODE SUBEND