Sneekie

Sneekie, рядок за рядком

Українська екскурсія вихідним кодом GW-BASIC 1988 року — з поясненнями через 38 років.

Це оригінальний SNEEKIE.BAS з повернутим контекстом. Код показаний саме так, як був написаний; бурштинові нотатки під рядками і картки між секціями — це нові пояснення. Якщо процедура незрозуміла, шукайте її номер рядка нижче — усе згруповано так, як це нумерував GW-BASIC.

Зелений лістинг BASIC з бурштиновими нотатками і схемами лабіринтів навколо.

Одна ідея, що пояснює все: екран і є гра

Тут немає спрайтів, ігрових обʼєктів чи окремої структури даних "змія". Змія, стіни, серця і стріли — це просто символи у текстовій памʼяті екрана PC, а програма читає і записує цю памʼять напряму через PEEK і POKE.

Текстовий екран має 80×25 клітинок. Кожна клітинка має два байти: код символу, потім його колірний атрибут. Отже адреса клітинки така:

offset = (рядок − 1) × 160 + (стовпець − 1) × 2  — 160, бо рядок має 80 клітинок × 2 байти.

Парний байт містить гліф; непарний байт містить атрибут (7 = звичайний, 15 = яскравий). Щоб дізнатися, що перед змією, код просто робить PEEK байта символу в цільовій клітинці і перемикається за знайденим числом. Цей один трюк — картинка і стан є тими самими байтами — пояснює, чому так багато програми рахує екранні зміщення.

▶ Подивитися наживо — керуйте змією і дивіться, як змінюються справжні байти.

Змінні (багато назв нідерландські)

T()змія — список екранних зміщень від хвоста T(ETEL) до голови T(BTEL)
BTEL / ETELіндекс голови / хвоста у T() (teller = лічильник)
E / Fпоточний / попередній напрям (сканкоди 72 80 75 77)
HARTсерця ♥, які ще треба зібрати (hart = серце)
KLAVERтрефи ♣, які ще треба зібрати (klaver = трефа)
BONUS / BMINчасовий бонус і те, наскільки він падає за хід
AANTALскільки предметів кожного типу розсипати (aantal = кількість)
Zсекунди на хід; 999 = покроково, мале число = реальний час
LIVE / LEVELзалишок життів / поточний рівень
ZCORE / ZOREрахунок / рекорд (спеціально лишені числами з рухомою комою — див. рядок 80)
OPочки, які додаються цього разу (передаються процедурі рахунку, 1190)
S() B() D()резервне спливне повідомлення / рядки брам / стан рухомих стріл
VIDEOсегмент памʼяті екрана (&HB000 моно / &HB800 колір)

Що означають символи (CP437)

32 порожня клітинка
219голова змії
186 205 187 188 201 200║═╗╝╔╚тіло змії: прямі лінії і кути
179 196 197 …│─┼стіни лабіринту і рамки
1смайлик — поганий (−50)
3серце (+10)
5трефа (+25)
10камінь — можна штовхати
24 26 27↑→←рухомі стріли — смертельні
атрибут 7 / 15 звичайний / яскравий

Клавіші (сканкоди у E)

72 80 75 77↑↓←→керувати змією
27ESCздатися, якщо застрягли (коштує життя)
67 / 68F9 / F10чит: +життя і пропуск / пропустити рівень

Як проходить один хід (рядки 420–1010)

  1. Чекати до Z секунд на стрілку або дозволити змії зберегти напрям.
  2. Зняти BMIN з бонусу.
  3. Перетворити напрям на крок екрана і визначити клітинку, у яку входить голова.
  4. Зробити PEEK цієї клітинки і відреагувати: порожнє місце, серце/трефа, камінь, смертельна стріла або блок стіною.
  5. Перетворити стару голову на правильний символ ═║╗╝╔╚ і намалювати нову голову .
  6. Підсвітити тіло і просунути стріли/брами рівня на один крок.
  7. Повторювати, доки всі серця і трефи не зібрані.
10 REM SNEEKIE
20 REM MS(X)DOS Computer Magazine
30 REM GW-Basic versie
40 REM door HerbySoft
70 REM
1

Завантаження і пошук екрана

рядки 80–100
Три завдання у двох рядках. DEFINT A-Y робить змінні A…Y цілими, але залишає Z* числами з рухомою комою; тому таймер і рахунок названі Z, ZCORE, ZORE. SCREEN 0:WIDTH 80 вибирає текст 80×25, а PEEK(&H449) питає BIOS, чи це монохромний або кольоровий екран.
80 DEFINT A-Y: SCREEN 0: WIDTH 80: CLS: ZORE=0: RANDOMIZE TIMER: DEF SEG=&H0
DEFINT A-Y = цілі; Z* лишаються з рухомою комою (TIMER потребує дробів, рахунок може перевищити 32767). SCREEN 0:WIDTH 80 = текст 80x25. RANDOMIZE TIMER ініціалізує генератор.
90 IF PEEK(&H449)=7 THEN VIDEO=&HB000 ELSE VIDEO=&HB800
PEEK(&H449) — байт відеорежиму BIOS. Режим 7 = монохром на &HB000; інакше колір на &HB800.
100 DEF SEG=VIDEO: CLS: DIM T(15000),S(168),B(10),D(80,3)
DEF SEG=VIDEO спрямовує PEEK/POKE на екранну памʼять. Масиви: T()=змія, S()=копія для вікна, B()=рядки брам, D()=стріли.
2

Малювання рамки і панелі рахунку

рядки 110–220
Звичайний LOCATE…PRINT малює сталі елементи: зовнішню рамку, заголовок і легенду внизу. Останній рядок робить POKE чотирьох іконок прямо у фіксовані екранні зміщення.
110 LOCATE 1, 1: PRINT CHR$(218);STRING$(78,CHR$(196));CHR$(191);
Верхня межа рамки: кут + 78 ліній + кут.
120 LOCATE 2, 1: PRINT CHR$(179);SPC(78);CHR$(179);
130 LOCATE 2,17: PRINT "**** Sneekie **** (c) juli '88 by HerbySoft";
Заголовок у верхній смузі.
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);
Нижня межа рамки.
210 POKE 3396,1: POKE 3556,10: POKE 3526,5: POKE 3366,3
Покласти чотири іконки легенди просто в екранну памʼять за зміщенням: смайлик(1), камінь(10), трефа(5), серце(3).
220 '
3

Початок нової гри

рядок 230
Обнулити рахунок, дати три життя і пройти рівні 1→32.
230 ZCORE=0: LIVE=3
Нова гра: рахунок 0, три життя.
4

Цикл рівнів

рядки 240–310
Кожен рівень очищає 17 внутрішніх рядків, ставить двоклітинкову змію в центрі і через ON LEVEL GOSUB переходить до рецепта цього рівня.
240 FOR LEVEL=1 TO 32
250 FOR I=1 TO 17: LOCATE 3+I,1: PRINT CHR$(179);SPC(78);CHR$(179): NEXT
Очистити 17 внутрішніх рядків, лишаючи бічні стіни.
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
Початкова змія: хвіст на зміщенні 2000 (рядок 13), голова на 1840 (рядок 12, прямо над ним) -> дивиться вгору. BTEL=2 — слот голови в T(), ETEL=1 — хвіст.
290 POKE T(BTEL),219: POKE T(ETEL),186: POKE T(BTEL)+1,15
Малюнок: голова = блок (219), хвіст = подвійна лінія (186), голова яскрава (15).
300 E=72: F=72: HART=0: KLAVER=0: BONUS=10000: OP=0: GOSUB 1190
Скидання на рівень: напрям угору (E=F=72), нічого не зібрано, бонус 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 -> рецепт рівня (2320..2480): швидкість, кількість предметів, крок бонусу і лабіринт. Рівні 17-32 повторюють ті самі 16.
5

Статусний рядок і розсипання предметів

рядки 320–360
Показати бонус, життя і рівень, а потім розсипати AANTAL сердець і AANTAL смайликів на випадкові порожні клітинки.
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
Розсипати предмети: AANTAL разів кидаємо один смайлик (небезпека) і одне серце.
350 L=1: GOSUB 1150: L=3: GOSUB 1150: IF K1=1 THEN HART=HART+1
GOSUB 1150 кладе символ у випадкову порожню клітинку. K1=1 означає, що серце лягло -> рахуємо в HART.
360 NEXT
6

Вікно “Рівень n”

рядки 370–410
Скопіювати частину екрана під спливним вікном у S(), намалювати рамку, дочекатися клавіші і вставити екран назад, щоб не лишити дірки.
370 FOR I=1 TO 42: FOR I3=0 TO 3: S(I+I3*42)=PEEK(1497+I+I3*160): NEXT: NEXT
Зберегти ділянку 4x42 під вікном у S(), щоб потім відновити (1497 = верхній лівий кут, +160 на рядок).
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)
Очистити буфер клавіатури BIOS (head:=tail), щоб випадкова клавіша не пропустила вікно, тоді чекати клавішу.
410 FOR I=1 TO 42: FOR I3=0 TO 3: POKE 1497+I+I3*160,S(I+I3*42): NEXT: NEXT
Вставити збережену ділянку назад, стираючи вікно.
7

Цикл руху — читання клавіші

рядки 420–460
Серце гри. На кожному такті код чекає до Z секунд на клавішу. Ранні рівні чекають безкінечно; пізніші рухаються самі.
420 WHILE+ KLAVER+HART>0
Грати рівень, поки не зібрані всі серця ТА трефи (HART+KLAVER = 0).
430 A$=INKEY$: Z2=0: Z1=TIMER
Узяти клавішу, що вже чекає; запустити таймер.
440 WHILE+ A$="" AND Z2<Z
450 Z2=TIMER-Z1: A$=INKEY$
Опитувати INKEY$, поки не зʼявиться клавіша або не мине Z секунд. Z=999 на початку (чекати вічно, покроково); пізніше — частка секунди (змія рухається сама).
460 WEND
8

Витрата бонусу і сортування клавіші

рядки 470–650
Кожен такт віднімає BMIN від бонусу. Потім код визначає, чи клавіша є стрілкою, ESC або марним вводом.
470 IF BONUS>0 THEN BONUS=BONUS-BMIN
Кожен хід знімає BMIN з бонусу.
480 LOCATE 23,73: PRINT USING "######";BONUS
490 IF LEN(A$)<>1 THEN GOTO 640
Справжня стрілка — рядок із 2 символів, тож довжина <> 1 означає хід (або таймаут) -> обробка на 640.
500 IF ASC(A$)<>27 THEN GOTO 910
Це один символ. Якщо не ESC (27), це сміття -> 910 (малий штраф, без ходу).
510 FOR I=1 TO 3
ESC (або перехід сюди після смертельного удару): процедура смерті / здачі.
520 SOUND 2000,3: SOUND 3000,3: SOUND 4000,3: SOUND 3000,3
530 NEXT
540 IF PLAY(0)<>0 THEN GOTO 540
Чекати, поки спорожніє черга звуку (PLAY(0) = ноти ще лунають).
550 WHILE+ ETEL<=BTEL
Розмотати всю змію, з хвоста...
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
...стерти кожну клітинку (пробіл + звичайний атрибут) з писком...
590 ETEL=ETEL+1: OP=BMIN*-1: GOSUB 1190
...просуваючи хвіст і знімаючи бонус.
600 WEND
610 LIVE=LIVE-1: HART=0: KLAVER=0
Втратити життя; обнулити лічильники сердець/треф.
620 IF LIVE=0 THEN LEVEL=32 ELSE LEVEL=LEVEL-1
Останнє життя? LEVEL=32, щоб цикл FOR завершився (кінець гри). Інакше LEVEL-1, щоб NEXT повторив рівень.
630 GOTO 1080
640 IF LEN(A$)=2 THEN E=ASC(MID$(A$,2,1))
Клавіша з 2 символів: узяти скан-код із другого байта в E (новий напрям). Таймаут лишає E без змін, тож змія рухається далі.
650 A=T(BTEL)
A = де зараз голова.
9

Чити і поворот голови

рядки 660–700
F10 пропускає рівень, F9 додає життя і пропускає. Інакше напрям перекладається в крок екрана: ±160 для рядка, ±2 для стовпця.
660 IF E=68 THEN GOTO 1080
Скан-код 68 = F10: перейти на наступний рівень.
670 IF E=67 THEN LIVE=LIVE+1: GOTO 1080
Скан-код 67 = F9: безкоштовне життя і перехід далі.
680 IF E=80 THEN A=A+160 ELSE IF E=72 THEN A=A-160
Перетворити напрям на крок екрана: +/-160 = рядок угору/вниз, +/-2 = стовпець ліворуч/праворуч. Тепер A — цільова клітинка.
690 IF E=77 THEN A=A+2 ELSE IF E=75 THEN A=A-2
700 D=PEEK(A)
Подивитися, що вже є в тій клітинці.
10

Що в наступній клітинці?

рядки 710–900
Головне рішення: розгалуження за символом, що лежить попереду.
  • 32 порожньо → ковзнути вперед (стерти хвіст, додати голову).
  • 5 ♣ трефа → +25 і рости (хвіст не стирається).
  • 3 ♥ серце → +10 і рости; після 16-го рівня воно ще й породжує нову трефу.
  • 10 ◙ камінь → штовхнути, якщо клітинка за ним порожня, інакше рух заблоковано.
  • 1 ☺ смайлик → −50 і вирости на ньому.
  • 24/26/27 стріла → миттєва смерть.
Цікавий поворот: з'їдене серце чи трефа породжує нові смайлики, тож поле стає жвавішим, поки ти його розчищаєш.
710 IF D<>32 THEN GOTO 740
32 = порожньо -> просто рухатися.
720 POKE T(ETEL),32: POKE T(ETEL)+1,7: SOUND 1500,0.1: ETEL=ETEL+1
Стерти клітинку хвоста і просунути вказівник хвоста, тож змія сунеться вперед тієї ж довжини.
730 GOTO 920
740 IF D<>5 THEN GOTO 770
5 = трефа (вартість 25).
750 L=1: GOSUB 1150: GOSUB 2260
Кинути десь новий смайлик (L=1) і програти дзвін — збирання ущільнює екран.
760 OP=25: GOSUB 1190: KLAVER=KLAVER-1: GOTO 920
+25, на одну трефу менше, кінець. Хвіст тут не стирається, тож їжа ВИРОЩУЄ змію.
770 IF D<>3 THEN GOTO 800
3 = серце (вартість 10).
780 IF LEVEL>16 THEN L=5: GOSUB 1150: IF K1=1 THEN KLAVER=KLAVER+1
На важкій половині (рівні після 16) серце також породжує нову трефу; якщо вона лягла, додати її до треф, які треба зібрати.
790 L=1: GOSUB 1150: GOSUB 2260: OP=10: GOSUB 1190: HART=HART-1: GOTO 920
Породити смайлик, дзвін, +10, на одне серце менше, кінець (ріст).
800 IF D<>10 THEN GOTO 870
10 = камінь -> спробувати штовхнути.
810 TA=A: IF E=80 THEN TA=TA+160 ELSE IF E=72 THEN TA=TA-160
TA = клітинка з іншого боку каменя, у тому ж напрямі.
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
Якщо та далека клітинка не порожня, камінь не зрушити -> 910 (заблоковано).
850 POKE TA,10: POKE T(ETEL),32: POKE T(ETEL)+1,7
Інакше заштовхнути камінь у TA, стерти хвіст і рухатися.
860 SOUND 1500,0.1: ETEL=ETEL+1: GOTO 920
870 IF D<>1 THEN GOTO 900
1 = смайлик — поганий.
880 FOR I=50 TO 1 STEP -1: SOUND 600+75*I,0.35: NEXT
Спадний скрик із 50 нот.
890 OP=-50: GOSUB 1190: L=1: GOSUB 1150: GOTO 920
-50, кинути ще один смайлик і наповзти на нього (ріст).
900 IF D=24 OR D=26 OR D=27 THEN GOTO 510
24/26/27 = рухома стріла -> миттєва смерть (перехід на 510).
11

Заблоковано — стіни і власний хвіст

рядок 910
Стіна або власне тіло не вбивають. Змія стоїть, зберігає старий напрям, втрачає трохи бонусу і дзижчить.
910 E=F: OP=BMIN*-1: GOSUB 1190: SOUND 1000,5: GOTO 1020
Стіна або власне тіло: не зайти. Зберегти старий напрям (E=F), втратити трохи бонусу, дзижчати, пропустити хід. Стіни тут не вбивають.
12

Малювання тіла, ріст голови, анімація

рядки 920–1020
Стара клітинка голови стає правильним символом рамки, нова голова додається, тіло блимає, а ворожа процедура цього рівня робить крок.
920 IF (E=77 AND F=77) OR (E=75 AND F=75) THEN POKE T(BTEL),205: GOTO 980
Прямий горизонтальний хід -> клітинка, яку покидаєш, стає = (205).
930 IF (E=80 AND F=80) OR (E=72 AND F=72) THEN POKE T(BTEL),186: GOTO 980
Прямий вертикальний хід -> клітинка, яку покидаєш, стає || (186).
940 IF (E=80 AND F=77) OR (E=75 AND F=72) THEN POKE T(BTEL),187: GOTO 980
Ці чотири рядки обирають символ кута для повороту з нового напряму E і старого 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
Додати нову голову: BTEL+1, зберегти зміщення в T(BTEL), запамʼятати F=E, намалювати блок (219).
990 IF BTEL=15000 THEN GOTO 510
Якщо масив сліду заповнений (15000), змії нікуди рости -> смерть.
1000 FOR I=BTEL TO ETEL STEP -2: POKE T(I)+1,15: POKE T(I-1)+1,7: NEXT
Мерехтіння: крок по тілу через два, роблячи парні клітинки яскравими (15), а сусідні звичайними (7). BTEL міняє парність щоходу, тож яскраві риски ніби повзуть.
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 -> анімація рівня: 1170 (нічого) на спокійних рівнях або рушії стріл/брам (2130/1830/1970).
1020 WEND
13

Рівень пройдено — забрати бонус

рядки 1030–1080
Залишковий бонус переходить у рахунок по пʼять очок за раз, після чого ви отримуєте додаткове життя.
1030 WHILE+ BONUS>0
Рівень пройдено. Перелити залишок бонусу в рахунок, по 5 за раз...
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
...тоді нагородити проходження +1 життям.
1080 NEXT LEVEL
14

Кінець / грати знову

рядки 1090–1140
Після всіх 32 рівнів або коли життя закінчилися, код показує Einde, питає про повтор і або стартує знову, або завершується.
1090 GOSUB 2280: LOCATE 11,33: PRINT "Einde"
Усі 32 пройдено (або життя скінчились): показати 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 = так -> рестарт на 230; інакше очистити, подякувати гравцю, END.
1140 '
15

Поставити предмет у випадкову клітинку

рядки 1150–1180
Вибрати випадкове парне зміщення у полі. Парне означає байт символу, не байт кольору. Заповнюється лише порожня клітинка.
1150 K1=0: K=INT(RND*2720+480): IF K MOD 2=1 THEN K=K+1
Випадкове парне зміщення в полі (480..3200); парне = байт символу, не байт кольору.
1160 IF PEEK(K)=32 THEN POKE K,L: K1=1
Лише якщо клітинка порожня (32): записати туди L і підняти прапор K1=1 (лягло).
1170 RETURN
1180 '
16

Рахунок і рекорд

рядки 1190–1220
Додати OP до рахунку і оновити рекорд, якщо його побито.
1190 ZCORE=ZCORE+OP: LOCATE 22,73: PRINT USING "######";ZCORE
Додати OP до рахунку і перемалювати його.
1200 IF ZCORE>ZORE THEN ZORE=ZCORE: LOCATE 22,46: PRINT USING "######";ZORE
Побито рекорд? оновити ZORE і показати.
1210 RETURN
1220 '
17

Схема: лабіринт

рядки 1230–1390
Вкладені цикли малюють мережу одинарних ліній і перехресть: найщільніший лабіринт.
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

Схема: розкидані камені

рядки 1400–1490
Кладе камені ◙ зигзагом. Допоміжна процедура на рядку 1480 ставить символ у стовпець X, рядок 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
Робоча конячка: POKE один символ у стовпець X, рядок Y (тут камінь, 10). Спільна для кількох схем.
1490 '
19

Схема: кімнати з дверима

рядки 1500–1660
Будує сітку кімнат, а потім читає DATA-координати, щоб пробити проходи у стінах.
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
READ 13 пар координат із DATA і пробити двері крізь стіни кімнат.
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: координати дверей (пари рядок,стовпець).
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

Схема: вертикальні брами

рядки 1670–1740
Колонки з отвором у три клітинки; B(I) памʼятає рядок отвору кожної брами.
1670 FOR I=1 TO 9: B(I)=6+I
B(I) = рядок отвору брами I. Намалювати повний стовпець, тоді стерти отвір на 3 клітинки і закрити його.
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

Схема: брами + камені

рядки 1750–1800
Схема брам плюс розсипані камені.
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

Небезпека: стріли вгору

рядки 1810–1910
Кожна парна колонка отримує стрілу вгору, яка на кожному такті піднімається на рядок і загортається зверху. Стріла на голові смертельна.
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
Коли стріла вибігає за верх (рядок 4), вона загортається на інший бік (+2720 = 17 рядків).
1860 IF PEEK(I2-160)=219 THEN RETURN 510
Стріла ось-ось стане на голову (219)? RETURN 510 = смерть.
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
Інакше відновити звільнену клітинку, посунути стрілу на рядок, намалювати, памʼятаючи в D(I,2), що було під нею.
1900 NEXT: RETURN
1910 '
23

Небезпека: горизонтальні стріли

рядки 1920–2120
У кожному рядку рухаються дві стріли: одна праворуч, одна ліворуч. На краю вони загортаються назад.
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
Рухати вертикальні стріли: одна праворуч (26), одна ліворуч (27) на рядок, щокадру.
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
Влучив у голову (219)? смерть.
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
Влучив у голову (219)? смерть.
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

Небезпека: рухомі брами

рядки 2130–2250
Девʼять отворів у брамах зсуваються. Тести =96 перевіряють, що три клітинки порожні перед переміщенням отвору.
2130 FOR D1=1 TO 9
Для кожної з 9 брам зсунути отвір; суми =96 перевіряють, що три клітинки порожні перед зсувом.
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
Посунути отвір на рядок униз; за рядком 16 він загортається назад на рядок 4.
2240 NEXT: RETURN
2250 '
25

Дзвін предмета

рядки 2260–2270
PLAY "mb" означає фонову музику, потім ідуть три висхідні сигнали.
2260 PLAY "mb": SOUND 2500,0.1: SOUND 3500,0.1: SOUND 5000,0.1: RETURN
PLAY "mb" = музика у фоні (не блокувати), потім три висхідні сигнали.
2270 '
26

Спливна рамка

рядки 2280–2310
Малює подвійну рамку за "Level n" і "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

32 рецепти рівнів

рядок 2320
Кожен рядок задає Z, AANTAL і BMIN, а також вибирає схему. Таблиці повторно використовують перші 16 рецептів для рівнів 17–32.
2320 Z=999: AANTAL= 75: BMIN=10: RETURN
Рівень 1: Z=999 (покроково), розсипати по 75 кожного, бонус падає 10/хід, без лабіринту.
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
Від рівня 9 (Z<1) змія рухається сама і прискорюється; 2410-2480 дзеркалять 2320-2390, але в реальному часі.
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
Бурштинові нотатки відриваються від BASIC-лістингу і стають світним лабіринтом Sneekie.