10 REM WORM V1.02 STYLE - MICROBEE MICROWORLD BASIC
20 REM STEP MOVE FIX27 - FOOD VISIBILITY WATCHDOG
30 REM NUMBERED FOOD - AVOID WALL AND OWN BODY
40 DIM X(150),Y(150),Z(493)
50 STRS(300)
60 GOTO 100
100 CLS
110 PRINT
120 PRINT "              W O R M"
130 PRINT
140 PRINT "       MICROBEE MICROWORLD BASIC"
150 PRINT
160 PRINT "       EAT THE NUMBERS TO SCORE"
170 PRINT "       DO NOT HIT WALL OR BODY"
180 PRINT
190 PRINT "       A=UP       Z=DOWN"
200 PRINT "       , <=LEFT   . >=RIGHT"
210 PRINT "       ARROWS AND JOYSTICK"
220 PRINT
230 PRINT "       P=PAUSE     Q=QUIT"
240 PRINT
250 PRINT "       PRESS ANY KEY TO START"
260 A0$=KEY
270 IF A0$="" THEN GOTO 260
280 GOTO 1000
300 REM NEW NUMBERED FOOD - USE OCCUPANCY MAP
310 F=INT(RND*9)+1
320 P=INT(RND*38)+1
330 Q=INT(RND*13)+1
340 K=(Q-1)*38+P-1
350 IF Z(K)=1 THEN GOTO 320
370 RETURN
400 REM DRAW PLAYFIELD ONCE
410 CLS
420 PRINT "SCORE";S;" LENGTH";L;" FOOD";F
430 PRINT "+--------------------------------------+"
440 FOR R=1 TO 13
450 PRINT "|                                      |"
460 NEXT R
470 PRINT "+--------------------------------------+";
480 REM NO EXTRA PRINT - 38X13 USES ALL 16 SCREEN ROWS
490 FOR I=L TO 2 STEP -1
500 CURS X(I)+1,Y(I)+2:PRINT "O";
510 NEXT I
520 CURS X(1)+1,Y(1)+2:PRINT "@";
530 CURS P+1,Q+2:PRINT CHR$(48+F);
540 RETURN
600 REM GAME OVER
610 R=0:C=0:B0$="GAME OVER - SCORE":GOSUB 9000
620 PRINT S;" LENGTH";L;"  PRESS ANY KEY";
630 A0$=KEY
640 IF A0$="" THEN GOTO 630
650 GOTO 100
700 REM WAIT FOR KEYBOARD OR JOYSTICK DIRECTION
710 A0$=KEY
712 IF A0$="" THEN GOTO 800
720 IF A0$="Q" OR A0$="q" THEN GOTO 10000
730 IF A0$="P" OR A0$="p" THEN GOSUB 850:GOTO 710
740 IF A0$="A" OR A0$="a" THEN LET D=0:LET E=-1:RETURN
742 IF A0$="Z" OR A0$="z" THEN LET D=0:LET E=1:RETURN
744 IF A0$="<" OR A0$="," THEN LET D=-1:LET E=0:RETURN
745 IF A0$=CHR$(60) THEN LET D=-1:LET E=0:RETURN
746 IF A0$=">" OR A0$="." THEN LET D=1:LET E=0:RETURN
747 IF A0$=CHR$(62) THEN LET D=1:LET E=0:RETURN
750 REM PREMIUM ARROWS = CTRL-E X S D
752 IF A0$=CHR$(5) THEN LET D=0:LET E=-1:RETURN
754 IF A0$=CHR$(24) THEN LET D=0:LET E=1:RETURN
756 IF A0$=CHR$(19) THEN LET D=-1:LET E=0:RETURN
758 IF A0$=CHR$(4) THEN LET D=1:LET E=0:RETURN
760 REM ALSO ACCEPT OLD CONTROL CURSOR CODES
762 IF A0$=CHR$(11) THEN LET D=0:LET E=-1:RETURN
764 IF A0$=CHR$(10) THEN LET D=0:LET E=1:RETURN
766 IF A0$=CHR$(8) THEN LET D=-1:LET E=0:RETURN
768 IF A0$=CHR$(9) THEN LET D=1:LET E=0:RETURN
770 GOTO 710
800 REM MICROBEE JOYSTICK - SAME VALUES AS SOKOBAN FIX2
802 A=IN(0)
804 IF A<128 THEN LET A=A+128
806 IF A=254 OR A=250 OR A=246 THEN LET D=0:LET E=-1:GOSUB 920:RETURN
808 IF A=253 OR A=249 OR A=245 THEN LET D=0:LET E=1:GOSUB 920:RETURN
810 IF A=251 OR A=250 OR A=249 THEN LET D=-1:LET E=0:GOSUB 920:RETURN
812 IF A=247 OR A=246 OR A=245 THEN LET D=1:LET E=0:GOSUB 920:RETURN
814 GOTO 710
850 REM PAUSE
860 R=0:C=0:B0$="PAUSED - PRESS A KEY              ":GOSUB 9000
870 A0$=KEY
880 IF A0$="" THEN GOTO 870
890 R=0:C=0:B0$="SCORE":GOSUB 9000:PRINT S;" LENGTH";L;" FOOD";F;"      "
900 RETURN
920 REM WAIT FOR JOYSTICK RELEASE
930 A=IN(0)
940 IF A=255 OR A=127 THEN RETURN
950 GOTO 930
1000 REM NEW GAME - CIRCULAR BODY BUFFER
1010 W=38:H=13:L=3:S=0:D=1:E=0:B=0
1020 C=3:T=1
1030 X(1)=17:Y(1)=6
1040 X(2)=18:Y(2)=6
1050 X(3)=19:Y(3)=6
1052 FOR I=0 TO 493:Z(I)=0:NEXT I
1054 FOR I=1 TO 3:Z((Y(I)-1)*38+X(I)-1)=1:NEXT I
1060 OUT 1,255
1070 GOSUB 300
1080 CLS
1090 PRINT "SCORE";S;" LENGTH";L;" FOOD";F
1092 PRINT "+--------------------------------------+"
1094 FOR R=1 TO 13
1096 PRINT "|                                      |"
1098 NEXT R
1100 PRINT "+--------------------------------------+";
1102 CURS X(1)+1,Y(1)+2:PRINT "O";
1104 CURS X(2)+1,Y(2)+2:PRINT "O";
1106 CURS X(3)+1,Y(3)+2:PRINT "@";
1108 CURS P+1,Q+2:PRINT CHR$(48+F);
1110 REM MAIN LOOP - ONE MOVE PER INPUT
1112 K=(Q-1)*38+P-1
1114 IF Z(K)=0 THEN GOTO 1120
1116 GOSUB 300
1118 CURS P+1,Q+2:PRINT CHR$(48+F);
1120 GOSUB 700
1130 N=X(C)+D:M=Y(C)+E
1140 IF N<1 OR N>W OR M<1 OR M>H THEN GOTO 600
1150 G=0
1160 IF N=P AND M=Q THEN LET G=1
1170 REM FAST SELF COLLISION USING OCCUPANCY ARRAY
1180 K=(M-1)*38+N-1
1190 IF Z(K)=0 THEN GOTO 1280
1200 REM CURRENT TAIL CELL IS SAFE ONLY IF TAIL WILL MOVE
1210 IF N=X(T) AND M=Y(T) THEN GOTO 1230
1220 GOTO 600
1230 IF B>0 OR G=1 THEN GOTO 600
1280 REM ERASE/MOVE TAIL UNLESS GROWING
1290 V=0
1300 IF G=1 THEN LET B=B+F
1310 IF B>0 AND L<150 THEN LET V=1
1320 IF V=1 THEN LET B=B-1:LET L=L+1:GOTO 1360
1330 IF X(T)=P AND Y(T)=Q THEN GOTO 1334
1331 CURS X(T)+1,Y(T)+2:PRINT " ";
1332 Z((Y(T)-1)*38+X(T)-1)=0
1333 GOTO 1340
1334 Z((Y(T)-1)*38+X(T)-1)=0
1335 CURS P+1,Q+2:PRINT CHR$(48+F);
1340 T=T+1
1350 IF T>150 THEN LET T=1
1360 REM OLD HEAD BECOMES BODY
1370 CURS X(C)+1,Y(C)+2:PRINT "O";
1380 C=C+1
1390 IF C>150 THEN LET C=1
1400 X(C)=N:Y(C)=M
1402 Z(K)=1
1410 CURS N+1,M+2:PRINT "@";
1420 IF G=0 THEN GOTO 1480
1430 S=S+F
1440 GOSUB 300
1450 CURS P+1,Q+2:PRINT CHR$(48+F);
1460 CURS 1,1:PRINT "SCORE";S;" LENGTH";L;" FOOD";F;"      ";
1480 GOTO 1110
9000 REM MICROWORLD BASIC CURSOR POSITION
9010 CURS C+1,R+1:PRINT B0$;
9020 RETURN
10000 CLS
10010 END
