'// HEATMAP-TO-FLOWFIELD TEST \\' '// J. KOHER \\' '// JANUARY 2023 \\' '*DESCRIPTION*' '// CREATES A GOAL-BASED HEAT MAP 20 WIDE BY 16 HIGH WITH A CELL SIZE OF 8X8 PIXELS GAMEPAD 1 GLOBAL M_WIDTH,M_HEIGHT,PERIMETER,C_SIZE,H_CHAR,TAR_COUNT GLOBAL SEED_X,SEED_Y,TAR_C,OBST_C,OBST_COUNT,S_C GLOBAL VEC_X,VEC_Y,V_CLOCK GLOBAL FIN_COUNT,BOTTOM_POINT,TOP_POINT,CURRENT_MIN,MAX_SUM,CURRENT_SUM_X,CURRENT_SUM_Y M_WIDTH=20 M_HEIGHT=16 C_SIZE=16 TAR_C=16 OBST_C=17 PERIMETER=2*(M_WIDTH+M_HEIGHT) '// HEAT FIELD MAP ARRAY DIM GLOBAL H_MAP((M_WIDTH-1),(M_HEIGHT-1)) '// (A,)= WIDTH INDEX '// (,B)= HEIGHT INDEX '// ARRAY FOR HANDLING THE PSUEDO-CLASS OF FLOOD-SEED POSITIONS TO BE HEAT-CHECKED '// *NOTE THAT SETTING THE FIRST INDEX SIZE TO 'PERIMETER' IS JUST TO GET A LOOSE OVER-APPROXIMATION FOR THE ACTUAL CELL PERIMETER '// AND MOREOVER, FOR AN APPROXIMATION OF THE MAXIMUM POSITIONS THAT IT WILL TRY TO TEST AT A TIME IN MOST CASES '// IF THERE ARE A LOT OF INDIVIDUAL TARGETS SPACED OUT ACROSS THE MAP, THEN GO WITH THE AREA OF THE MAP IN CELLS - # OF TARGET CELLS TO BE SURE '// BUT THE FORMER WORKS FINE WITH JUST ONE TARGET OR A SMALL, SIMPLE CLUMP OF TARGETS. JUST KNOW THE PROGRAM WOULD NEED FURTHER REFINEMENT TO DO OTHERWISE DIM GLOBAL FLOOD_CLASS((PERIMETER),1) '// (A,)= INDICATES STACK INDEX POSITION '// (,B)= INDICATES X-POSITION (,0) , AND Y-POSITION (,1) '// ARRAY FOR HANDLING THE PSUEDO-CLASS OF VECTORS BASED ON THE MIN. HEAT VALUE(S) SURROUNDING A TEST SEED DIM GLOBAL V_MIN_CLASS(7,1) '// VECTOR FIELD MAP ARRAY DIM GLOBAL V_FIELD(M_WIDTH-1,M_HEIGHT-1) '// (A,)= WIDTH INDEX '// (,B)= HEIGHT INDEX BG 1 BG COPY 0,0,20,16 TO 0,0 '// RUN LOOPS TO CHECK X & Y (I,J) CELL POSITIONS FOR TARGET(S) AND OBSTRUCTION(S) WITHIN THE SPECIFIED BG MAP '// IF A TARGET IS FOUND, THEN SET ITS EQUIVELANT H_MAP(I,J) ELEMENT TO '0' AND SET THE SEED POS. '// IF NO TARGET IS FOUND AT A POSITION, THEN SET THE EQUIVELANT H_MAP(I,J) ELEMENT TO '-1' FOR I=0 TO (M_WIDTH-1) FOR J=0 TO (M_HEIGHT-1) CURRENT_C=MCELL.C(I,J) IF CURRENT_C=TAR_C THEN H_MAP(I,J)=0 FLOOD_CLASS(TOP_POINT,0)=I FLOOD_CLASS(TOP_POINT,1)=J INC TOP_POINT ELSE IF CURRENT_C=OBST_C THEN H_MAP(I,J)=254 INC OBST_COUNT ELSE H_MAP(I,J)=-1 END IF NEXT J NEXT I '// SET UP THE INITIAL SEED POSITION VALUES SEED_X=FLOOD_CLASS(BOTTOM_POINT,0) SEED_Y=FLOOD_CLASS(BOTTOM_POINT,1) '// RUN SEED-HEATING LOOP UNTIL THE BOTTOM_POINTER CATCHES UP WITH THE TOP_POINTER, IN WHICH CASE THE ELEMENTS WILL BE -1 WHILE SEED_X>-1 AND SEED_Y>-1 '// UPDATE HEAT VALUES CALL HEAT_THE_SEED(SEED_X,SEED_Y) '// UPDATE SEED VALUES AS PER THE BOTTOM POINTER OF THE FLOOD_CLASS SEED_X=FLOOD_CLASS(BOTTOM_POINT,0) SEED_Y=FLOOD_CLASS(BOTTOM_POINT,1) WEND '// SET THE CURRENT MIN. TO THE HIGHEST VALUE (254 IN THIS CASE) AND RUN LOOPS TO FIND THE TRUE MIN'(S) AND THEN SETUP VECTOR VALUES FROM THEM: '// I AND J LOOPS WALK VECTOR SEED THROUGH EACH CELL IJ_PASS=0 RERUN_IJ: FOR I=0 TO (M_WIDTH-1) FOR J=0 TO (M_HEIGHT-1) '// ON IJ_PASS 0, SKIP TARGET CELLS AND SET INITIAL VARIABLES IF IJ_PASS<1 THEN IF H_MAP(I,J)=0 OR H_MAP(I,J)=254 THEN GOTO SKIP_J CURRENT_MIN=254 BOT_P=0 AB_PASS=0 ELSE '// ON IJ_PASS 1, SKIP ANY V_FIELD() ELEMENTS WITH SET VALUES (>-1) IF H_MAP(I,J)=0 OR H_MAP(I,J)=254 OR V_FIELD(I,J)>-1 THEN GOTO SKIP_J ELSE BG 0 PAL 7 IF V_FIELD(I,J-1)=0 THEN V_FIELD(I,J)=0 CELL I,J,5 ELSE IF V_FIELD(I+1,J-1)=1 THEN V_FIELD(I,J)=1 CELL I,J,6 ELSE IF V_FIELD(I+1,J)=2 THEN V_FIELD(I,J)=2 CELL I,J,4 ELSE IF V_FIELD(I+1,J+1)=3 THEN V_FIELD(I,J)=3 CELL I,J,22 END IF BG 1 END IF GOTO SKIP_J END IF '// RETURN LABEL FOR MULTIPLE PASSES OF THE A/B LOOPS: FIRST PASS (PASS=0) FINDS THE TRUE CURRENT_MIN, AND THE SECOND SETS UP THE MIN_CLASS VECTOR ARRAY RERUN_AB: FOR A=-1 TO 1 FOR B=-1 TO 1 IF A=0 AND B=0 THEN GOTO SKIP_B IF I+A>-1 AND I+A-1 AND J+B0 AND B<>0 AND H_MAP(I,(J+B))=254 AND H_MAP((I+A),J)=254) THEN GOTO SKIP_B IF AB_PASS<1 THEN IF H_MAP(I+A,J+B)<=CURRENT_MIN THEN CURRENT_MIN=H_MAP(I+A,J+B) ELSE IF H_MAP(I+A,J+B)=CURRENT_MIN THEN V_MIN_CLASS(BOT_P,0)=A V_MIN_CLASS(BOT_P,1)=B INC BOT_P END IF END IF END IF SKIP_B: NEXT B NEXT A '// POST-LOOP PROCESS EITHER RETURNS TO LOOPS A/B (PASS '0') OR CALCULATES THE WEIGHTED-AVERAGE OF ALL THE MIN. CELL VECTOR-EQUIVELANTS IF AB_PASS<1 THEN INC AB_PASS GOTO RERUN_AB ELSE '// ADD THE VECTORS AND FIND THE MAXIMUM VALUE TO WEIGHT THE AVERAGE AND ROUND TO BRING THEM BACK TO SCALE IN A DECIDED DIRECTION (ANY OF EIGHT) CURRENT_SUM_X=0 CURRENT_SUM_Y=0 FOR V=0 TO 7 CURRENT_SUM_X=CURRENT_SUM_X+V_MIN_CLASS(V,0) CURRENT_SUM_Y=CURRENT_SUM_Y+V_MIN_CLASS(V,1) V_MIN_CLASS(V,0)=0 V_MIN_CLASS(V,1)=0 NEXT V IF ABS(CURRENT_SUM_X)>=ABS(CURRENT_SUM_Y) THEN MAX_SUM=ABS(CURRENT_SUM_X) ELSE MAX_SUM=ABS(CURRENT_SUM_Y) IF MAX_SUM<>0 THEN VEC_X=CURRENT_SUM_X/MAX_SUM VEC_Y=CURRENT_SUM_Y/MAX_SUM ELSE VEC_X=0 VEC_Y=0 END IF '// THE ROUNDING FAVORS 0'S TO HELP BALANCE THE BIAS IN THE HEATMAP TOWARDS THE DIAGONALS IN THIS DISTANCE-COUNTING REGIME IF VEC_X>=0 THEN IF VEC_X-INT(VEC_X)<=0.5 THEN VEC_X=INT(VEC_X) ELSE VEC_X=1 ELSE IF INT(VEC_X)<>VEC_X AND INT(VEC_X)-VEC_X>=-0.5 THEN VEC_X=INT(VEC_X)+1 ELSE VEC_X=-1 END IF IF VEC_Y>=0 THEN IF VEC_Y-INT(VEC_Y)<=0.5 THEN VEC_Y=INT(VEC_Y) ELSE VEC_Y=1 ELSE IF INT(VEC_Y)<>VEC_Y AND INT(VEC_Y)-VEC_Y>=-0.5 THEN VEC_Y=INT(VEC_Y)+1 ELSE VEC_Y=-1 END IF '// ENCODE THE RESULTS AS ONE OF EIGHT 'CLOCK VALUES' WITH '0' AT THE TOP (12 O'CLOCK) INCREASING CLOCKWISE BG 0 PAL 7 IF VEC_X=0 AND VEC_Y<0 THEN V_CLOCK=0 CELL I,J,5 ELSE IF VEC_X>0 AND VEC_Y<0 THEN V_CLOCK=1 CELL I,J,6 ELSE IF VEC_X>0 AND VEC_Y=0 THEN V_CLOCK=2 CELL I,J,4 ELSE IF VEC_X>0 AND VEC_Y>0 THEN V_CLOCK=3 CELL I,J,22 ELSE IF VEC_X=0 AND VEC_Y>0 THEN V_CLOCK=4 CELL I,J,21 ELSE IF VEC_X<0 AND VEC_Y>0 THEN V_CLOCK=5 CELL I,J,23 ELSE IF VEC_X<0 AND VEC_Y=0 THEN V_CLOCK=6 CELL I,J,20 ELSE IF VEC_X<0 AND VEC_Y<0 THEN V_CLOCK=7 CELL I,J,7 ELSE V_CLOCK=-1 END IF BG 1 '// SET THE VECTOR FIELD ARRAY VALUES V_FIELD(I,J)=V_CLOCK END IF SKIP_J: NEXT J NEXT I IF IJ_PASS<1 THEN INC IJ_PASS GOTO RERUN_IJ END IF '// CYCLES THROUGH THE CELLS SURROUNDING THE CURRENT SEED AND UPDATES THEIR HEAT VALUES WHEN APPROPRIATE SUB HEAT_THE_SEED(X,Y) S_C=H_MAP(X,Y) CALL SEED_HEAT_PO '// LOOP FOR PRE-SEEDING VALUES FOR A=-1 TO 1 FOR B=-1 TO 1 '// IF AT SEED CELL, THEN SKIP UPDATING THE HEAT VALUES IF A=0 AND B=0 THEN GOTO NEXT_B '// CHECK TO SEE THAT THE CELL TO BE UPDATED IS ON THE MAP ELSE IF X+A>M_WIDTH-1 OR X+A<0 OR Y+B>M_HEIGHT-1 OR Y+B<0 THEN GOTO NEXT_B '// CHECK TO MAKE SURE DIAGONALS AREN'T BLOCKED IN BY THEIR PERPENDICULAR NEIGHBORS (SPECIFIED BY GAME MECHANICS) ELSE IF A<>0 AND B<>0 AND H_MAP(X,(Y+B))=254 AND H_MAP((X+A),Y)=254 THEN GOTO NEXT_B ELSE N_X=X+A N_Y=Y+B N_C=H_MAP(N_X,N_Y) IF N_C<0 OR (S_C+10 THEN H_PAL=INT(S_C/3) IF H_PAL>7 THEN H_PAL=7 H_CHAR=(S_C MOD 3)+1 BG 1 PAL H_PAL CELL SEED_X,SEED_Y,H_CHAR END IF BG 0 IF S_C>0 AND S_C<10 THEN NUMBER SEED_X,SEED_Y,S_C,1 BG 1 END SUB #1:MAIN PALETTES 003E3D3C00383430003B373300323120 002F1F0F000B0703000E0D0C000C0804 #2:MAIN CHARACTERS 00000000000000000000000000000000 FFFFFFFFFFFFFFFF0000000000000000 0000000000000000FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 0008047E7E0408000000000000000000 00183C5A181818000000000000000000 001E060A122040000000000000000000 00786050480402000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 FFBDA5FF424242A50000000000000000 FFBDE7DBDBE7BDFF817E5A66665A7E81 00000000000000000000000000000000 00000000000000000000000000000000 0010207E7E2010000000000000000000 001818185A3C18000000000000000000 004020120A061E000000000000000000 00020448506078000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 C3810000000081C30000000000000000 #3:MAIN BG 00001410000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00001107000000000000000000001107 00000000000000000000000000000000 00000000000000000000000011071107 11071107110700000000000000000000 00000000000000000000110700000000 00000000000000000000000000000000 00000000110700000000000000000000 00000000110700000000000000000000 00000000000000000000110700000000 00000000000000000000000011070000 00000000000000001007000000000000 00001107000000000000000000000000 00000000110700000000000000001007 10071007000000000000110700000000 00000000000000000000000011070000 00000000000000001007000000000000 00001107000000000000000000000000 00000000110700000000000000000000 00000000000000000000110700000000 00000000000000000000110700000000 00000000110711071107110711070000 00000000110700000000000000000000 00000000000000000000110700000000 00000000000011070000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000