Sneekie

Sneekie, regel voor regel

Een Nederlandstalige rondleiding door de GW-BASIC-bron uit 1988 — 38 jaar later geannoteerd.

Dit is de originele SNEEKIE.BAS met het verhaal erbij. De code staat precies zoals hij geschreven is; de amberkleurige notities onder regels en de kaarten tussen secties zijn de nieuwe uitleg. Is een routine onduidelijk, zoek dan het regelnummer hieronder — alles is gegroepeerd zoals GW-BASIC het nummerde.

Een groene BASIC-listing met amberkleurige annotaties en doolhofschetsen eromheen.

Het ene idee dat alles verklaart: het scherm is het spel

Er zijn geen sprites, geen game-objecten en eigenlijk geen aparte "slang"-datastructuur. De slang, muren, harten en pijlen zijn gewoon tekens in het tekstschermgeheugen van de PC, en het programma leest en schrijft dat geheugen rechtstreeks met PEEK en POKE.

Het tekstscherm is 80×25 cellen. Elke cel heeft twee bytes: eerst de tekencode, daarna de kleur ("attribute"). Het adres van een cel is dus

offset = (rij − 1) × 160 + (kolom − 1) × 2  — 160 omdat een rij 80 cellen × 2 bytes is.

De even byte bevat het teken; de oneven byte bevat het attribuut (7 = normaal, 15 = helder). Om te weten wat er voor de slang ligt, PEEKt de code alleen de tekenbyte van het doelvak en schakelt op dat getal. Die ene truc — beeld en toestand zijn dezelfde bytes — verklaart waarom zoveel programmawerk offset-rekenen is.

▶ Bekijk het live — stuur een slang en zie de echte bytes veranderen.

De variabelen

T()de slang — een lijst met schermoffsets, van staart T(ETEL) tot kop T(BTEL)
BTEL / ETELindex van kop / staart in T() (teller)
E / Fhuidige / vorige richting (scancodes 72 80 75 77)
HARTharten ♥ die nog verzameld moeten worden
KLAVERklavers ♣ die nog verzameld moeten worden
BONUS / BMINtijdbonus, en hoeveel hij per zet daalt
AANTALhoeveel items er van elk type worden gestrooid
Zseconden toegestaan per zet; 999 = beurt voor beurt, klein = realtime
LIVE / LEVELresterende levens / huidig level
ZCORE / ZOREscore / highscore
OPpunten die deze keer worden toegevoegd
S() B() D()popup-backup / poortposities / bewegende-pijltoestand
VIDEOhet schermgeheugensegment (&HB000 mono / &HB800 kleur)

Wat de tekens betekenen (CP437)

32 leeg vak
219slangenkop
186 205 187 188 201 200║═╗╝╔╚slangenlijf: recht en hoeken
179 196 197 …│─┼doolhof- en kadermuren
1smiley — slecht (−50)
3hart (+10)
5klaver (+25)
10steen — duwbaar
24 26 27↑→←bewegende pijlen — dodelijk
attr 7 / 15 normaal / helder

Toetsen (de scancodes in E)

72 80 75 77↑↓←→stuur de slang
27ESCopgeven als je vastzit (kost een leven)
67 / 68F9 / F10cheat: +leven & overslaan / level overslaan

Hoe een zet verloopt (regels 420–1010)

  1. Wacht tot Z seconden op een pijltjestoets, of laat de slang zijn richting houden.
  2. Trek BMIN van de bonus af.
  3. Zet de richting om in een schermstap en bepaal het vak dat de kop wil binnenkomen.
  4. PEEK dat vak en reageer: leeg vak, hart/klaver eten, steen duwen, sterven door een pijl, of geblokkeerd worden door een muur.
  5. Maak van het oude kopvak het juiste ═║╗╝╔╚-stuk en teken een nieuwe kop.
  6. Laat het lijf glimmen en beweeg de pijlen/poorten van dit level een stap.
  7. Herhaal tot elk hart en elke klaver weg is.
10 REM SNEEKIE
20 REM MS(X)DOS Computer Magazine
30 REM GW-Basic versie
40 REM door HerbySoft
70 REM
1

Opstarten & het scherm vinden

regels 80–100
Drie dingen in twee regels. DEFINT A-Y maakt variabelen A…Y integer en laat de Z*-namen floating-point; daarom heten timer en score Z, ZCORE, ZORE. SCREEN 0:WIDTH 80 kiest 80×25 tekst, en PEEK(&H449) vraagt de BIOS of dit een mono- of kleurenscherm is.
80 DEFINT A-Y: SCREEN 0: WIDTH 80: CLS: ZORE=0: RANDOMIZE TIMER: DEF SEG=&H0
DEFINT A-Y = integers; Z* blijft floating-point voor timer en score. SCREEN 0:WIDTH 80 kiest 80x25 tekst.
90 IF PEEK(&H449)=7 THEN VIDEO=&HB000 ELSE VIDEO=&HB800
PEEK(&H449) is de BIOS-videomodus. Mode 7 = mono op &HB000; anders kleur op &HB800.
100 DEF SEG=VIDEO: CLS: DIM T(15000),S(168),B(10),D(80,3)
DEF SEG=VIDEO richt PEEK/POKE op schermgeheugen. De arrays: T()=slang, S()=popup-backup, B()=poorten, D()=pijlen.
2

Het kader & scorepaneel tekenen

regels 110–220
Gewone LOCATE…PRINT tekent de vaste meubels: buitenkader, titelbalk en legenda onderaan. De laatste regel POKEt de vier icoontjes rechtstreeks op vaste schermoffsets.
110 LOCATE 1, 1: PRINT CHR$(218);STRING$(78,CHR$(196));CHR$(191);
Bovenrand van het kader: hoek + 78 lijnen + hoek.
120 LOCATE 2, 1: PRINT CHR$(179);SPC(78);CHR$(179);
130 LOCATE 2,17: PRINT "**** Sneekie **** (c) juli '88 by HerbySoft";
De titel in de bovenbalk.
140 LOCATE 22, 1: PRINT CHR$(179);SPC(78);CHR$(179);
150 LOCATE 22, 6: PRINT "10 punten -50 punten Highscore";
160 LOCATE 23, 1: PRINT CHR$(179);SPC(78);CHR$(179);
170 LOCATE 22,55: PRINT "Level Score";
180 LOCATE 23, 6: PRINT "25 punten Steen <ESC> vastgelopen";
190 LOCATE 23,55: PRINT "Lives Bonus";
200 LOCATE 24, 1: PRINT CHR$(192);STRING$(78,CHR$(196));CHR$(217);
Onderkant van het kader.
210 POKE 3396,1: POKE 3556,10: POKE 3526,5: POKE 3366,3
Zet de vier legenda-icoontjes direct in schermgeheugen: smiley(1), steen(10), klaver(5), hart(3).
220 '
3

Nieuw spel starten

regel 230
Zet de score op nul, geef drie levens en speel levels 1→32.
230 ZCORE=0: LIVE=3
Nieuw spel: score 0, drie levens.
4

De levelloop

regels 240–310
Elk level wist de binnenste 17 rijen, zet een tweecellige slang in het midden en springt via ON LEVEL GOSUB naar het recept van dat level.
240 FOR LEVEL=1 TO 32
250 FOR I=1 TO 17: LOCATE 3+I,1: PRINT CHR$(179);SPC(78);CHR$(179): NEXT
Wis de 17 binnenrijen, maar laat de zijmuren staan.
260 LOCATE 3,1: PRINT CHR$(195);STRING$(78,CHR$(196));CHR$(180)
270 LOCATE 21,1: PRINT CHR$(195);STRING$(78,CHR$(196));CHR$(180)
280 T(1)=2000: T(2)=1840: BTEL=2: ETEL=1
Startslang: staart op offset 2000, kop op 1840; hij begint omhoog. BTEL=kopslot, ETEL=staartslot.
290 POKE T(BTEL),219: POKE T(ETEL),186: POKE T(BTEL)+1,15
Teken de kop als blok (219), de staart als dubbele lijn (186), kop helder (15).
300 E=72: F=72: HART=0: KLAVER=0: BONUS=10000: OP=0: GOSUB 1190
Per-level reset: richting omhoog, nog niets verzameld, bonus 10000.
310 ON LEVEL GOSUB 2320,2330,2340,2350,2360,2370,2380,2390,2410,2420,2430,2440,2450,2460,2470,2480,2320,2330,2340,2350,2360,2370,2380,2390,2410,2420,2430,2440,2450,2460,2470,2480
ON LEVEL GOSUB kiest het levelrecept: snelheid, itemaantal, bonusstap en doolhof.
5

Statusregel & items strooien

regels 320–360
Toon bonus, levens en level, en strooi daarna AANTAL harten en AANTAL smileys op willekeurige lege vakken.
320 LOCATE 23,73: PRINT USING "######";BONUS
330 LOCATE 23,61: PRINT USING "##";LIVE: LOCATE 22,61: PRINT USING "##";LEVEL
340 FOR I=1 TO AANTAL
Strooi AANTAL smileys en AANTAL harten.
350 L=1: GOSUB 1150: L=3: GOSUB 1150: IF K1=1 THEN HART=HART+1
GOSUB 1150 zet een teken op een willekeurig leeg vak; K1=1 betekent dat het hart landde.
360 NEXT
6

De “Level n”-popup

regels 370–410
Kopieer het schermdeel onder de popup naar S(), teken de box, wacht op een toets en plak het scherm terug zodat er geen gat achterblijft.
370 FOR I=1 TO 42: FOR I3=0 TO 3: S(I+I3*42)=PEEK(1497+I+I3*160): NEXT: NEXT
Bewaar het 4x42-gebied onder de popup in S().
380 GOSUB 2280: LOCATE 11,37: PRINT "Level ";LEVEL
390 LOCATE 12,32: PRINT "Druk op een toets"
400 DEF SEG=0: POKE 1050,PEEK(1052): DEF SEG=VIDEO: A$=INPUT$(1)
Leeg de BIOS-toetsenbuffer en wacht op een toets.
410 FOR I=1 TO 42: FOR I3=0 TO 3: POKE 1497+I+I3*160,S(I+I3*42): NEXT: NEXT
Plak het bewaarde schermdeel terug en wis de popup.
7

De move-loop — een toets lezen

regels 420–460
Het hart van het spel. Per tick wacht de code maximaal Z seconden op een toets. Vroege levels wachten voor altijd; latere levels bewegen vanzelf door.
420 WHILE+ KLAVER+HART>0
Speel dit level tot alle harten en klavers weg zijn.
430 A$=INKEY$: Z2=0: Z1=TIMER
Lees een wachtende toets en start een timer.
440 WHILE+ A$="" AND Z2<Z
450 Z2=TIMER-Z1: A$=INKEY$
Blijf INKEY$ pollen tot een toets komt of Z seconden voorbij zijn.
460 WEND
8

Bonus uitgeven en toets sorteren

regels 470–650
Elke tick haalt BMIN van de bonus. Daarna bepaalt de code of de toets een pijltje, ESC of rommel is.
470 IF BONUS>0 THEN BONUS=BONUS-BMIN
Elke zet kost BMIN bonus.
480 LOCATE 23,73: PRINT USING "######";BONUS
490 IF LEN(A$)<>1 THEN GOTO 640
Een echte pijltjestoets is twee tekens; lengte <> 1 gaat naar de bewegingscode.
500 IF ASC(A$)<>27 THEN GOTO 910
Een enkel teken dat geen ESC is, is rommel en wordt als botsing behandeld.
510 FOR I=1 TO 3
ESC of een dodelijke hit: de dood/opgeven-routine.
520 SOUND 2000,3: SOUND 3000,3: SOUND 4000,3: SOUND 3000,3
530 NEXT
540 IF PLAY(0)<>0 THEN GOTO 540
Wacht tot de geluidswachtrij leeg is.
550 WHILE+ ETEL<=BTEL
Rol de slang staart-eerst af...
560 Z=TIMER
570 Z1=TIMER-Z: IF Z1<0.075 THEN GOTO 570
580 POKE T(ETEL),32: POKE T(ETEL)+1,7: SOUND 1500,0.1
...wis elk vak met een bliep...
590 ETEL=ETEL+1: OP=BMIN*-1: GOSUB 1190
...schuif de staart op en trek bonus af.
600 WEND
610 LIVE=LIVE-1: HART=0: KLAVER=0
Verlies een leven; reset hart- en klavertellers.
620 IF LIVE=0 THEN LEVEL=32 ELSE LEVEL=LEVEL-1
Geen levens? Zet LEVEL=32 zodat de FOR-loop eindigt; anders speel dit level opnieuw.
630 GOTO 1080
640 IF LEN(A$)=2 THEN E=ASC(MID$(A$,2,1))
Twee-tekentoets: haal de scancode uit byte twee. Bij timeout blijft E gelijk en beweegt de slang door.
650 A=T(BTEL)
A = waar de kop nu staat.
9

Cheats en de kop draaien

regels 660–700
F10 slaat over, F9 geeft een leven en slaat over. Anders wordt de richting vertaald naar een schermstap: ±160 voor een rij, ±2 voor een kolom.
660 IF E=68 THEN GOTO 1080
Scancode 68 = F10, level overslaan.
670 IF E=67 THEN LIVE=LIVE+1: GOTO 1080
Scancode 67 = F9, gratis leven en overslaan.
680 IF E=80 THEN A=A+160 ELSE IF E=72 THEN A=A-160
Richting naar schermstap: +/-160 voor rij, +/-2 voor kolom.
690 IF E=77 THEN A=A+2 ELSE IF E=75 THEN A=A-2
700 D=PEEK(A)
Kijk wat er al in het doelvak staat.
10

Wat staat er in het volgende vak?

regels 710–900
De grote beslissing: schakel op het teken dat vóór de kop ligt.
  • 32 leeg → schuif vooruit (staart wissen, kop erbij).
  • 5 ♣ klaver → +25 en groeien (de staart wordt niet gewist).
  • 3 ♥ hart → +10 en groeien; na level 16 broedt het ook een nieuwe klaver.
  • 10 ◙ steen → duw hem als het vak erachter leeg is, anders zit je vast.
  • 1 ☺ smiley → −50 en er overheen groeien.
  • 24/26/27 pijl → onmiddellijke dood.
Een aardige twist: een hart of klaver eten laat verse smileys verschijnen, dus het veld wordt drukker terwijl je het leegruimt.
710 IF D<>32 THEN GOTO 740
32 = leeg, dus gewoon bewegen.
720 POKE T(ETEL),32: POKE T(ETEL)+1,7: SOUND 1500,0.1: ETEL=ETEL+1
Wis de staart en schuif de staartpointer op.
730 GOTO 920
740 IF D<>5 THEN GOTO 770
5 = klaver, 25 punten.
750 L=1: GOSUB 1150: GOSUB 2260
Strooi een nieuwe smiley en speel de jingle.
760 OP=25: GOSUB 1190: KLAVER=KLAVER-1: GOTO 920
+25, een klaver minder. Geen staart wissen, dus groei.
770 IF D<>3 THEN GOTO 800
3 = hart, 10 punten.
780 IF LEVEL>16 THEN L=5: GOSUB 1150: IF K1=1 THEN KLAVER=KLAVER+1
In de harde helft kan een hart een nieuwe klaver maken.
790 L=1: GOSUB 1150: GOSUB 2260: OP=10: GOSUB 1190: HART=HART-1: GOTO 920
Strooi smiley, jingle, +10, een hart minder, groei.
800 IF D<>10 THEN GOTO 870
10 = steen; probeer hem te duwen.
810 TA=A: IF E=80 THEN TA=TA+160 ELSE IF E=72 THEN TA=TA-160
TA = het vak achter de steen.
820 IF E=77 THEN TA=TA+2 ELSE IF E=75 THEN TA=TA-2
830 D=PEEK(TA)
840 IF D<>32 THEN GOTO 910
Als dat vak niet leeg is, kan de steen niet bewegen.
850 POKE TA,10: POKE T(ETEL),32: POKE T(ETEL)+1,7
Duw de steen, wis de staart en beweeg.
860 SOUND 1500,0.1: ETEL=ETEL+1: GOTO 920
870 IF D<>1 THEN GOTO 900
1 = smiley, de slechte.
880 FOR I=50 TO 1 STEP -1: SOUND 600+75*I,0.35: NEXT
Een dalende klaagtoon van 50 noten.
890 OP=-50: GOSUB 1190: L=1: GOSUB 1150: GOTO 920
-50, strooi nog een smiley, en groei erop.
900 IF D=24 OR D=26 OR D=27 THEN GOTO 510
24/26/27 = bewegende pijl, instant dood.
11

Geblokkeerd — muren en eigen staart

regel 910
Een muur of eigen lijf doodt je niet. De slang blijft staan, houdt de oude richting, verliest wat bonus en zoemt.
910 E=F: OP=BMIN*-1: GOSUB 1190: SOUND 1000,5: GOTO 1020
Muur of eigen lijf: niet naar binnen. Oude richting houden, bonus verliezen, zoemen.
12

Lijf tekenen, kop laten groeien, animeren

regels 920–1020
Het oude kopvak wordt het juiste box-drawing-stuk, de nieuwe kop wordt toegevoegd, het lijf glimt en de vijandroutine van dit level doet een stap.
920 IF (E=77 AND F=77) OR (E=75 AND F=75) THEN POKE T(BTEL),205: GOTO 980
Horizontaal recht stuk wordt 205.
930 IF (E=80 AND F=80) OR (E=72 AND F=72) THEN POKE T(BTEL),186: GOTO 980
Verticaal recht stuk wordt 186.
940 IF (E=80 AND F=77) OR (E=75 AND F=72) THEN POKE T(BTEL),187: GOTO 980
Deze regels kiezen de hoekglyph voor een bocht uit nieuwe richting E en oude richting F.
950 IF (E=72 AND F=77) OR (E=75 AND F=80) THEN POKE T(BTEL),188: GOTO 980
960 IF (E=80 AND F=75) OR (E=77 AND F=72) THEN POKE T(BTEL),201: GOTO 980
970 IF (E=72 AND F=75) OR (E=77 AND F=80) THEN POKE T(BTEL),200: GOTO 980
980 BTEL=BTEL+1: T(BTEL)=A: F=E: POKE T(BTEL),219
Voeg de nieuwe kop toe: BTEL+1, offset bewaren, kop tekenen.
990 IF BTEL=15000 THEN GOTO 510
Trail-array vol? Dan kan de slang nergens meer groeien: dood.
1000 FOR I=BTEL TO ETEL STEP -2: POKE T(I)+1,15: POKE T(I-1)+1,7: NEXT
De glans: alternerende lijfvakken worden helder. Omdat BTEL van pariteit wisselt, lijkt het te lopen.
1010 ON LEVEL GOSUB 1170,1170,1170,1170,2130,1830,1970,2130,1170,1170,1170,1170,2130,1830,1970,2130,1170,1170,1170,1170,2130,1830,1970,2130,1170,1170,1170,1170,2130,1830,1970,2130
ON LEVEL GOSUB kiest de animatie van dit level: niets, pijlen of poorten.
1020 WEND
13

Level gehaald — bonus innen

regels 1030–1080
De resterende bonus gaat vijf punten per keer naar de score, daarna krijg je een extra leven.
1030 WHILE+ BONUS>0
Level gehaald: stort de resterende bonus in de score.
1040 OP=5: GOSUB 1190: BONUS=BONUS-5: LOCATE 23,74
1050 PRINT USING "#####";BONUS: SOUND 3000,0.1
1060 WEND
1070 LIVE=LIVE+1
Geef een extra leven voor het halen van het level.
1080 NEXT LEVEL
14

Einde / opnieuw spelen

regels 1090–1140
Na alle 32 levels of wanneer de levens op zijn, toont de code Einde, vraagt of je opnieuw wilt spelen, en start opnieuw of stopt.
1090 GOSUB 2280: LOCATE 11,33: PRINT "Einde"
Alle 32 klaar of geen levens: toon Einde.
1100 LOCATE 12,32: PRINT "Nog een keer (j/n)"
1110 DEF SEG=0: POKE 1050,PEEK(1052): DEF SEG=VIDEO
1120 A$=INPUT$(1): IF INSTR("JjNn",A$)=0 THEN GOTO 1120
1130 IF A$="J" OR A$="j" THEN GOTO 230 ELSE CLS: PRINT "Bedankt voor het spelen": END
j = ja: opnieuw starten; anders bedanken en END.
1140 '
15

Item op een willekeurig vak zetten

regels 1150–1180
Kies een willekeurige even offset in het speelveld. Even betekent: tekenbyte, niet kleurbyte. Alleen een leeg vak wordt gevuld.
1150 K1=0: K=INT(RND*2720+480): IF K MOD 2=1 THEN K=K+1
Willekeurige even offset in het speelveld; even = tekenbyte.
1160 IF PEEK(K)=32 THEN POKE K,L: K1=1
Alleen als het vak leeg is: schrijf L en zet K1=1.
1170 RETURN
1180 '
16

Score & highscore

regels 1190–1220
Tel OP bij de score op en werk de highscore bij als die wordt verbeterd.
1190 ZCORE=ZCORE+OP: LOCATE 22,73: PRINT USING "######";ZCORE
Tel OP bij de score op en teken opnieuw.
1200 IF ZCORE>ZORE THEN ZORE=ZCORE: LOCATE 22,46: PRINT USING "######";ZORE
Highscore verbeterd? Werk ZORE bij en toon hem.
1210 RETURN
1220 '
17

Layout: het labyrint

regels 1230–1390
Geneste lussen tekenen een web van enkele lijnen en kruisingen: het dichtste doolhof.
1230 FOR I=1 TO 39: LOCATE 8,1+I: PRINT CHR$(196): LOCATE 16,80-I: PRINT CHR$(196): NEXT
1240 FOR I=0 TO 8
1250 LOCATE 21-I,11: PRINT CHR$(179): LOCATE 3+I,70: PRINT CHR$(179): LOCATE 21-I,26: PRINT CHR$(179)
1260 LOCATE 3+I,55: PRINT CHR$(179): LOCATE 15,22+I: PRINT CHR$(196): LOCATE 6,51+I: PRINT CHR$(196)
1270 LOCATE 15,7+I: PRINT CHR$(196): LOCATE 6,66+I: PRINT CHR$(196): LOCATE 18,7+I: PRINT CHR$(196)
1280 LOCATE 9,66+I: PRINT CHR$(196): LOCATE 18,22+I: PRINT CHR$(196): LOCATE 9,51+I: PRINT CHR$(196)
1290 FOR I1=6 TO 10
1300 LOCATE I1,5+I*4: PRINT CHR$(179): LOCATE 8+I1,44+I*4: PRINT CHR$(179)
1310 NEXT
1320 LOCATE 8,5+I*4: PRINT CHR$(197): LOCATE 16,44+I*4: PRINT CHR$(197)
1330 NEXT
1340 LOCATE 3,70: PRINT CHR$(194): LOCATE 21,11: PRINT CHR$(193): LOCATE 3,55: PRINT CHR$(194)
1350 LOCATE 15,26: PRINT CHR$(197): LOCATE 6,55: PRINT CHR$(197): LOCATE 18,26: PRINT CHR$(197)
1360 LOCATE 9,55: PRINT CHR$(197): LOCATE 15,11: PRINT CHR$(197): LOCATE 6,70: PRINT CHR$(197)
1370 LOCATE 18,11: PRINT CHR$(197): LOCATE 9,70: PRINT CHR$(197): LOCATE 21,26: PRINT CHR$(193)
1380 RETURN
1390 '
18

Layout: verspreide stenen

regels 1400–1490
Legt ◙ stenen in zigzag. De helper op regel 1480 zet een teken op kolom X, rij Y.
1400 FOR Y=4 TO 20 STEP 2: FOR I=0 TO 1: Q=1: FOR A=1 TO 6
1410 IF Q=1 THEN Q=0: Y=Y+1 ELSE Q=1: Y=Y-1
1420 IF Y<21 THEN X=17+A+40*I: GOSUB 1480
1430 NEXT: NEXT: NEXT
1440 I1=7
1450 FOR X=2 TO 78 STEP 2: FOR I=0 TO 1
1460 Y=7+8*I: GOSUB 1480: Y=8+8*I: X=X+1: GOSUB 1480: Y=9+8*I: X=X-1: GOSUB 1480
1470 NEXT: NEXT: RETURN
1480 POKE (Y-1)*160+(X-1)*2,10: RETURN
Werkpaard: POKE een teken op kolom X, rij Y.
1490 '
19

Layout: kamers met deuropeningen

regels 1500–1660
Bouwt een raster van kamers en leest daarna DATA-coordinaten om doorgangen in de muren te slaan.
1500 FOR I=2 TO 79: FOR I1=1 TO 2: LOCATE 3+6*I1,I: PRINT CHR$(196): NEXT: NEXT
1510 FOR I=4 TO 20: FOR I1=1 TO 7
1520 LOCATE 3,10*I1: PRINT CHR$(194): LOCATE 21,10*I1: PRINT CHR$(193)
1530 LOCATE I,10*I1: PRINT CHR$(179)
1540 FOR I2=1 TO 2
1550 LOCATE 3+6*I2,10*I1: PRINT CHR$(197): LOCATE 3+6*I2,80: PRINT CHR$(180)
1560 LOCATE 3+6*I2, 1: PRINT CHR$(195)
1570 NEXT: NEXT: NEXT: RESTORE 1500
1580 FOR I=1 TO 13: READ C1,C2,C3,C4
Lees 13 coordinaatparen en maak deuropeningen in de kamermuren.
1590 LOCATE C1,C2: PRINT " ": LOCATE C1,C2-1: PRINT CHR$(180)
1600 LOCATE C1,C2+2: PRINT CHR$(195): LOCATE C1,C2+1: PRINT " "
1610 LOCATE C3+2,C4: PRINT CHR$(194): LOCATE C3+1,C4: PRINT " "
1620 LOCATE C3,C4: PRINT " ": LOCATE C3-1,C4: PRINT CHR$(193)
1630 NEXT: RETURN: DATA 15,5
DATA met deurcoordinaten.
1640 DATA 6,10,9,35,6,20,9,75,6,40,9,55,6,70,9,65,18,10,15,55,18,20,15,65,18,30
1650 DATA 15,75,18,40,9,45,12,20,9,15,12,30,9,15,18,50,9,15,6,50,9,15,18,60
1660 '
20

Layout: verticale poorten

regels 1670–1740
Kolommen met een opening van drie vakken; B(I) onthoudt per poort waar de opening zit.
1670 FOR I=1 TO 9: B(I)=6+I
B(I) is de rij van opening I; teken een kolom en maak een drie-vaks gat.
1680 LOCATE 3,8*I: PRINT CHR$(194)
1690 FOR I1=4 TO 20: LOCATE I1,8*I: PRINT CHR$(179): NEXT
1700 LOCATE 21,8*I: PRINT CHR$(193): LOCATE B(I)-1,I*8: PRINT "┴
1710 FOR I1=0 TO 2: LOCATE B(I)+I1,I*8: PRINT " ": NEXT
1720 LOCATE B(I)+3,I*8: PRINT CHR$(194)
1730 NEXT: RETURN
1740 '
21

Layout: poorten + stenen

regels 1750–1800
De poortlayout plus een strooiing stenen.
1750 GOSUB 1670
1760 FOR I1=4 TO 20 STEP 2: FOR I2=0 TO 9
1770 Y=I1: X=I2*8+3: GOSUB 1480: Y=I1: X=I2*8+5: GOSUB 1480
1780 IF Y<20 THEN Y=I1+1: X=I2*8+4: GOSUB 1480
1790 NEXT: NEXT: RETURN
1800 '
22

Gevaar: omhoogpijlen

regels 1810–1910
Elke even kolom krijgt een omhoogpijl die per tick een rij stijgt en bovenaan terugwikkelt. Een pijl op de kop is fataal.
1810 FOR I=2 TO 79 STEP 2: D(I,1)=5+INT(RND*14): D(I,2)=32: NEXT: GOSUB 1830: RETURN
1820 '
1830 FOR I=2 TO 78 STEP 2
1840 I2=(D(I,1)-1)*160+(I-1)*2
1850 IF D(I,1)=4 THEN POKE I2,D(I,2): POKE I2+1,7: D(I,1)=21: I2=I2+2720
Loopt een pijl boven uit beeld, dan wikkelt hij terug naar de andere kant.
1860 IF PEEK(I2-160)=219 THEN RETURN 510
Pijl stapt op de kop? RETURN 510 = dood.
1870 IF PEEK(I2-160)>100 THEN GOTO 1900
1880 IF D(I,1)<>21 THEN POKE I2,D(I,2): POKE I2+1,7
1890 D(I,1)=D(I,1)-1: D(I,2)=PEEK(I2-160): POKE I2-160,24: POKE I2-159,15
Herstel het verlaten vak, verplaats de pijl en onthoud wat eronder lag.
1900 NEXT: RETURN
1910 '
23

Gevaar: horizontale pijlen

regels 1920–2120
Per rij bewegen twee pijlen: een naar rechts en een naar links. Ze wikkelen aan de rand terug.
1920 FOR I=4 TO 20: FOR A=0 TO 1
1930 D(I+A*20,1)=RND*38*2+2+A: D(I+A*20,2)=32
1940 NEXT: NEXT
1950 D(12,1)=14: D(13,1)=6: D(32,1)=65: D(33,1)=55: GOSUB 1970: RETURN
1960 '
1970 FOR I=4 TO 20
Beweeg horizontale pijlen: een naar rechts en een naar links per rij.
1980 I2=(I-1)*160+(D(I,1)-1)*2
1990 IF D(I,1)=79 THEN POKE I2,D(I,2): POKE I2+1,7: D(I,1)=1: I2=I2-156
2000 D=PEEK(I2+2): IF D=219 THEN RETURN 510
Raakt hij de kop? dood.
2010 IF D=27 THEN POKE I2+2,D(I+20,2): D(I+20,2)=26
2020 IF D>100 THEN GOTO 2050
2030 IF D(I,1)<>1 THEN POKE I2,D(I,2): POKE I2+1,7
2040 D(I,1)=D(I,1)+1: D(I,2)=PEEK(I2+2): POKE I2+2,26: POKE I2+3,15
2050 L=I+20: I2=(I-1)*160+(D(L,1)-1)*2
2060 IF D(L,1)=2 THEN POKE I2,D(L,2): POKE I2+1,7: D(L,1)=80: I2=I2+156
2070 D=PEEK(I2-2): IF D=219 THEN RETURN 510
Raakt hij de kop? dood.
2080 IF D>100 OR D=26 THEN GOTO 2110
2090 IF D(L,1)<>80 THEN POKE I2,D(L,2): POKE I2+1,7
2100 D(L,1)=D(L,1)-1: D(L,2)=PEEK(I2-2): POKE I2-2,27: POKE I2-1,15
2110 NEXT: RETURN
2120 '
24

Gevaar: bewegende poorten

regels 2130–2250
De negen poortopeningen schuiven. De =96-tests controleren of drie vakken leeg zijn voordat een opening verplaatst.
2130 FOR D1=1 TO 9
Schuif elke poortopening; de =96-sommen testen drie lege vakken.
2140 D2=(B(D1)-1)*160+(D1*8-1)*2: IF B(D1)<>4 THEN GOTO 2190
2150 A=PEEK(D2+2080)+PEEK(D2+2240)+PEEK(D2+2400)
2160 IF A<>96 THEN GOTO 2240
2170 POKE D2+2560,179: POKE D2+2080,179: POKE D2+2240,179: POKE D2+2400,179
2180 POKE D2,32: POKE D2+160,32: POKE D2+320,32: POKE D2+1920,179
2190 A=PEEK(D2)+PEEK(D2+160)+PEEK(D2+320)
2200 IF A<>96 THEN GOTO 2240
2210 IF B(D1)<>4 THEN POKE D2-160,179
2220 POKE D2,193: POKE D2+160,32: POKE D2+320,32: POKE D2+480,32
2230 POKE D2+640,194: B(D1)=B(D1)+1: IF B(D1)=17 THEN B(D1)=4
Beweeg de opening omlaag; voorbij rij 16 wikkelt hij terug naar rij 4.
2240 NEXT: RETURN
2250 '
25

Het pickup-jingletje

regels 2260–2270
PLAY "mb" betekent achtergrondmuziek, gevolgd door drie stijgende bliepjes.
2260 PLAY "mb": SOUND 2500,0.1: SOUND 3500,0.1: SOUND 5000,0.1: RETURN
PLAY "mb" = muziek op de achtergrond, daarna drie stijgende bliepjes.
2270 '
26

De popupbox

regels 2280–2310
Tekent de dubbele kaderbox achter "Level n" en "Einde".
2280 LOCATE 10,30: PRINT CHR$(201);STRING$(19,CHR$(205));CHR$(187)
2290 LOCATE 11,30: PRINT CHR$(186);SPC(19);CHR$(186): LOCATE 12,30: PRINT CHR$(186);SPC(19);CHR$(186)
2300 LOCATE 13,30: PRINT CHR$(200);STRING$(19,CHR$(205));CHR$(188): RETURN
2310 '
27

De 32 levelrecepten

regel 2320
Elke regel zet Z, AANTAL en BMIN en kiest een layout. De tabellen hergebruiken de eerste 16 recepten voor levels 17–32.
2320 Z=999: AANTAL= 75: BMIN=10: RETURN
Level 1: Z=999, 75 items, bonus daalt 10 per zet, geen doolhof.
2330 Z=999: AANTAL= 75: BMIN=10: GOSUB 1230: RETURN
2340 Z=999: AANTAL= 75: BMIN=10: GOSUB 1500: RETURN
2350 Z=999: AANTAL= 50: BMIN=10: GOSUB 1400: RETURN
2360 Z=999: AANTAL= 50: BMIN=10: GOSUB 1670: RETURN
2370 Z=999: AANTAL= 50: BMIN=10: GOSUB 1810: RETURN
2380 Z=999: AANTAL= 50: BMIN=10: GOSUB 1920: RETURN
2390 Z=999: AANTAL= 50: BMIN=10: GOSUB 1750: RETURN
2400 '
2410 Z= 0.4: AANTAL=125: BMIN= 5: RETURN
Vanaf level 9 beweegt de slang vanzelf; 2410-2480 spiegelen 2320-2390 maar realtime.
2420 Z= 0.6: AANTAL=125: BMIN= 5: GOSUB 1230: RETURN
2430 Z= 0.6: AANTAL=125: BMIN= 5: GOSUB 1500: RETURN
2440 Z= 0.9: AANTAL=100: BMIN= 5: GOSUB 1400: RETURN
2450 Z= 0.9: AANTAL=100: BMIN= 5: GOSUB 1670: RETURN
2460 Z=1 : AANTAL=100: BMIN= 5: GOSUB 1810: RETURN
2470 Z=1 : AANTAL=100: BMIN= 5: GOSUB 1920: RETURN
2480 Z=1.2: AANTAL=100: BMIN= 5: GOSUB 1750: RETURN
Amberkleurige annotaties komen los van de BASIC-listing en veranderen in een gloeiend Sneekie-doolhof.