Tag name:programming

One of my early programs

26th February 2022

I recently rediscovered one of my early programs dating back (at time of writing) almost forty years! I've copied onto this website at Snazzy Snake.

Snazzy Snake

26th February 2022

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

  1. ISBN 0-7447-0001-9 and had the princely price of £6.50
  2. 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!

Maplin's Touch LCD Shield for Arduino

2nd September 2016

I've been playing around with Maplin's Touch LCD Shield. It's not a bad device (it does seem to be a little slow, but I suspect that's mostly down to the library being used to drive it. That said, I did take a while to get it working since there's not a lot of documentation for it and I notice that I'm not the only one who had problems. So partially as a reminder to myself (and partially to make this visible to search engines) there's what I had to do.

  1. Download the correct library from linkshield's wiki. I eventually downloaded the v2 library.
  2. Copy the example program (again from the wiki).
  3. Fix up the compile errors in that example program - I guess the library was updated AFTER the example:
    1. Remove the declaration of TS_MINX, TS_MAXX, TS_MINY, TS_MAXY (the library has these as #define's and the compiler gets quite confused.)
    2. Changed the test p.z > ts.pressureThreshold to ts.isTouching()  (The library doesn't have a pressThreshold field and the point class doesn't have a z field. On the other hand, the library does have the isTouching method!)
    3. Changed the initTouchScreenParameters method to initialise a touchscreen via TouchScreen(XP, YP, XM, YM) and deleted the setting of TS_MINX, TS_MAXX, TS_MINY, TS_MAXY (again the compiler gets quite confused).

I was then able to run the demo, although the touch output seemed to be completely reversed, so I edited my library header file to switch the values of TS_MIN* with TS_MAX*. This seemed to fix the problem.

I've, for the time being at least, used it to act as a monitor for my Thinkpad that runs my linux server (that is, I got the linux server to talk to it!)

Moving from RTC to fossil

14th December 2015

I am a fan of IBM's Rational Team Concert, but have reluctantly decided that I need to move from it to something much easier on the operations side. My specific problem is that the Ubuntu machine on which I run the RTC server needs a clean reinstall1. Having tried (on my laptop that also has Ubuntu installed) to use my backup of the repository2 to get a working clone of the RTC system has proved a LOT harder that I would like, I ended investigating alternatives.

Fossil is my selected alternative, at least for the time being. The pro's and con's (at least as compared with RTC) are:

Pro's

  • Install is easy (I'd go as far as trivial) - fossil is a single executable (with executables for Windows and Linux (also Mac, though I don't have any of those at this time))
  • Includes a problem tracking system as well as a source control system (also a wiki)
  • The repository is a single file, yet is still a SQL database (fossil uses SQLite)
  • Its mental model for development is not that dissimilar to RTC
  • Builtin web server for admin and browse capabilities (OK, so you have to run the executable to get the server running...)
  • Moving from RTC will allow me to use an up to date eclipse - not that the current version I'm using is broken!

Con's

  • No integration with eclipse - this one is a shame, but my website and plugins are small enough that I can handle running a commit command to put my changes into the repository
  • No included build support (though fossil can generate a rss feed). I did investigate getting jenkins running, but since there's just me and I already had one-step build running, I've (for the time being at least) decided I can manage to run a manual build instead
  • The lack of build support means there's no immediately obvious way to publish build results - this is next on my investigation list (I suspect using either a wiki page, or technotes might be a substitute, but I'm worried about wanting attachments in some form - I guess that's another con for the moment.

As you can probably guess I do consider this to be a shame, but I don't want to spend lots of time attempting to set up RTC on a reinstalled machine so that it's the same as before

Footnotes

  1. Somehow my kernel and the /boot are not in sync (I think the /boot partition that's being mounted is NOT the one that grub is using at boot time, and since I'm also having to manually select the upstart kernel (the standard kernel locks up in the G15 keyboard handler that I installed) AND the size of the /boot partition is tiny I need to do a reinstall to get to a clean system
  2. OK, I admit it, I didn't prove that I had a backup by attempting the restore on a different machine earlier

Spider Caves Fixed

7th November 2015

Yesterday I discovered that my spider caves plugin was broken (in fact it looks like it's been broken since at least the conversion to wordpress. All the problems I discovered have now been fixed 🙂

Menu woes

2nd August 2015

If you've recently tried to use my top navigation bar, you may have encountered problems with the sub-menus disappearing as you try to move the pointer down into the sub-menu. I'm still working on that (I know the change that caused the problem is that I'm now using a custom menu for the navigation rather than the default, but I haven't yet found a suitable fix.

Still this is a normal kind of debugging!