Back in 1982 (or possibly 1983) while I was at University I wrote the following program which is the oldest program to which I have any form of recording. It was written for the BBC Micro and was also provided to Simon (one of my lecturers who went by the singular name) and included in the book Quality Programs for the BBC Micro1. Given the nature of the book the program is now released under CC0 1.0 Universal (CC0 1.0) Public Domain Dedication.
If you get the chance it's worth reading both the specific chapter on this program and indeed the complete book. Simon's very mild criticism of my programming style is fun to read all these years after the event (and I can tell my programming lineage via the Commodore Pet still shows through!). I also note that some of the formatting and styling of the program not what I would do today - whether that formatting is more to do with the layout required for the book or more to do with my style of coding back in the day is something I can't answer!2
100 REM Snazzy Snake, by David Vines 110 ON ERROR GOTO 240 120 MODE7 130 VDU23;8202;0;0;0;: *FX4,1 140 PROCINIT 150 REPEAT 160 PROCSETUP: PROCSCREEN 170 REPEAT: PROCSNAKE: PROCNUMBER 180 UNTIL TIME>6000 190 PROCENDGAME 200 UNTIL FNEND 210 PROCCLEANUP: MODE 7 220 END 229 230 REM ERROR HANDLING 240 PROCCLEANUP 250 REPORT: IF ERL>0 THEN PRINT" at line ";ERL 260 END 269 270 DEF PROCINIT 280 HIGHSCORE=0: *FX11,0 290 max=500: DIM xpos(max),ypos(max),D$(4) 300 D$(1)="^": D$(2)="]": D$(3)="V"; D$(4)="[" 310 PROCINSTRUCTIONS 320 ENDPROC 329 330 DEF PROCINSTRUCTIONS 340 CLS 350 FOR I=1 TO 2 360 VDU132,157,135,141: PRINTSPC(5)"SNAZZY SNAKE"; 370 VDU140: IF I=1 THEN PRINT" By David Vines" 380 NEXT 390 PRINT''" This is a game for one player. The" 400 PRINT"game represents a snake, trapped in an" 410 PRINT"enclosed area, who has tto keep eating" 420 PRINT"in order to survive. The snake eats" 430 PRINT"his food by hitting it." 440 PRINT'" The snake is controlled by the cursor" 450 PRINT"keys. The ""["" key turns the snake to" 460 PRINT"its left, the ""]"" key turns it to" 470 PRINT"its right. The snake initially has one" 480 PRINT"minute to survive, but each piece of" 490 PRINT"food he eats means that he can live" 500 PRINT"longer. The score is the total value of" 510 PRINT"food eaten by the snake." 520 PRINT'''" ";: VDU132,157,135 530 PRINT"PRESS ANY KEY TO START ";:VDU 156,30 540 A$=GET$ 550 ENDPROC 559 560 DEF PROCSETUP 570 SCORE=0: TIME=0: NX=4: NY=4: value=0: Head=2 580 Length=2: Real_Length=2: Tail=0; DIR=1 590 xpos(Head)=19: ypos(Head)=10: xpos(Head-1)=19 600 ypos(Head-1)=11: xpos(Tail)=19: ypos(Tail)=12 610 ENDPROC 619 620 DEF PROCSCREEN 630 CLS: PROCTOPLINE: PRINT 640 FOR I=1 TO 39: VDU 255: NEXT 650 FORJ=2 TO 21: VDU31,0,J,255,31,38,J,255: NEXT 660 PRINTTAB(0,22);: FORI=1 TO 39: VDU 255: NEXT 670 PRINTTAB(19,10)"^";TAB(19,11)"*";TAB(19,12)"*" 680 ENDPROC 689 690 DEF PROCSNAKE 700 PROCTOPLINE: I$=INKEY$(0) 710 IF I$<>"" THEN PROCNEWDIR(I$) 720 IF Length=Real_Length THEN PROCPOKE(xpos(Tail),ypos(Tail)," "): Tail=Tail+1: IF Tail>max THEN Tail=0 730 IF Length>Real_Length THEN Real_Length=Real_Length+1 740 OHead=Head: Head=Head+1: IF Head>max THEN Head=0 750 IF DIR=1 THEN PROCadd(0,1) ELSE IF DIR=2 THEN PROCadd(1,0) ELSE IF DIR=3 THEN PROCadd(0,-1) ELSE PROCadd(-1,0) 760 A$=FNPeek(xpos(Head),ypos(Head)) 770 IF A$=CHR$(255) OR A$="*" THEN TIME=7000 780 PROCPOKE(xpos(OHead),ypos(OHead),"*") 790 PROCPOKE(xpos(Head),ypos(Head),D$(DIR)) 800 IF ASC(A$)<>1 AND A$<>"#" THEN ENDPROC 810 FOR I=value-1 TO 0 STEP -1 820 PROCPOKE(NX,NY,STR$(I)): Length=Length+1 830 PROCWAIT(0.05): SCORE=SCORE+1 840 TIME=TIME-57: PROCTOPLINE 850 NEXT 860 value=0 870 ENDPROC 879 880 DEF PROCNEWDIR(I$) 890 IF I$=CHR$(&89) THEN DIR=DIR+1: IF DIR=5 THEN DIR=1 900 IF I$=CHR$(&88) THEN DIR=DIR-1: IF DIR=0 THEN DIR=4 910 ENDPROC 919 920 DEF PROCadd(x,y) 930 xpos(Head)=xpos(OHead)+x: ypos(Head)=ypos(OHead)+y 940 ENDPROC 949 950 DEF PROCNUMBER 960 IF value<>0 AND RND(120)<>1 THEN ENDPROC 970 FOR I=-1 TO 1: FOR J=-1 TO 1 980 IF NX+I<>xpos(Head) OR NY+J<>ypos(Head) THEN PROCPOKE(NX+I,NY+J," ") 990 NEXT:NEXT 1000 REPEAT 1010 NX=RND(35)+1: NY+RND(16)+2: valid=TRUE 1020 FOR I=-1 TO 1: FOR J=-1 TO 1 1030 valid=valid AND (FNPEEK(NX+I,NY+J)=" ") 1040 NEXT: NEXT 1050 UNTIL valid OR TIME>6000 1060 IF TIME>6000 THEN ENDPROC 1070 value=RND(9) 1080 FOR I=-1 TO 1: FOR J=-1 TO 1 1090 PROCPOKE(NX+I,NY+J,"#") 1100 NEXT: NEXT 1110 PROCPOKE(NX,NY,STR$(value)) 1120 ENDPROC 1129 1130 DEF PROCENDGAME 1140 VDU28,4,17,36,8: CLS 1150 FOR J=3 TO 4:PRINTTAB(10,J)CHR$(141)"GAME OVER"CHR$(140): NEXT 1160 IF A$=CHR$(255) THEN PRINTTAB(0,1)" YOU'VE HIT A SIDE - OH DEAR ! " 1170 IF A$="*" THEN PRINTTAB(0,1)" YOU'VE HIT YOURSELF - A BAD MOVE " 1180 IF TIME<7000 THEN PRINTTAB(12,1)" TIME UP " 1190 PROCWAIT(1): IF SCORE>HIGHSCORE THEN HIGHSCORE+SCORE 1200 ENDPROC 1209 1210 DEF FNEND: LOCAL B$ 1220 PRINTTAB(0,6)" ANOTHER GAME? (PRESS 'Y' OR 'N') " 1230 PRINTTAB(0,8)" (PRESS 'I' FOR INSTRUCTIONS) ": VDU26 1240 REPEAT 1250 B$=GET$ 1260 IF B$="I" OR B$="i" THEN PROCINSTRUCTIONS: B$="Y" 1270 UNTIL INSTR("YyNn",B$) 1280 =B$="N" OR B$="n" 1289 1290 DEF PROCTOPLINE 1300 PRINTTAB(0,0);"SCORE+ ";SCORE;" TIME= "; 1310 @%=&20205: PRINT;60-TIME/100;: @%=10 1320 PRINT" HIGH SCORE= ";HIGHSCORE;" "; 1330 ENDPROC 1339 1340 DEF FNPEEK(X,Y) 1350 VDU31,X,Y 1360 A%=135 1370 =CHR$((USR(&FFF4) AND &FFFF) DIV &100) 1379 1380 DEF PROCPOKE(X,Y,X$) 1390 VDU 31,X,Y,ASC(X$) 1400 ENDPROC 1409 1410 DEF PROCWAIT(T): LOCAL oldtime 1420 oldtime=TIME 1430 REPEAT UNTIL TIME-oldtime>T*100 1440 ENDPROC 1449 1450 DEF PROCCLEANUP 1460 *FX12,0 1470 *FX4,0 1480 @%=10 1490 ENDPROC
Footnotes
- ISBN 0-7447-0001-9 and had the princely price of £6.50 ↩
- And yes, some more comments would have been handy - but the program had to fit on a BBC Model A (which had only 16K bytes of RAM, of which 3¾K was used by the operating system and another 1K for the screen (this program uses the BBC Micro's teletext screen mode) leaving under 12K for the program itself AND all the variables it uses (including two 500 element arrays each of holds a floating point number and hence uses about 2K just on those array. In any event there just wasn't much room for comments! ↩