Sneekie, рядок за рядком
Українська екскурсія вихідним кодом GW-BASIC 1988 року — з поясненнями через 38 років.
Це оригінальний SNEEKIE.BAS з повернутим контекстом. Код показаний саме так, як був написаний; бурштинові нотатки під рядками і картки між секціями — це нові пояснення. Якщо routine незрозуміла, шукайте її номер рядка нижче — усе згруповано так, як це нумерував GW-BASIC.
Одна ідея, що пояснює все: екран і є гра
Тут немає sprites, game objects чи окремої структури даних "змія". Змія, стіни, серця і стріли — це просто символи у текстовій памʼяті екрана PC, а програма читає і записує цю памʼять напряму через PEEK і POKE.
Текстовий екран має 80×25 клітинок. Кожна клітинка має два байти: код символу, потім його колірний атрибут. Отже адреса клітинки така:
offset = (рядок − 1) × 160 + (стовпець − 1) × 2 — 160, бо рядок має 80 клітинок × 2 байти.
Парний байт містить glyph; непарний байт містить атрибут (7 = звичайний, 15 = яскравий). Щоб дізнатися, що перед змією, код просто робить PEEK байта символу в цільовій клітинці і перемикається за знайденим числом. Цей один трюк — картинка і стан є тими самими байтами — пояснює, чому так багато програми рахує screen offsets.
▶ Подивитися наживо — керуйте змією і дивіться, як змінюються справжні байти.
Змінні (багато назв нідерландські)
| T() | змія — список screen offsets від хвоста T(ETEL) до голови T(BTEL) |
| BTEL / ETEL | індекс голови / хвоста у T() (teller = лічильник) |
| E / F | поточний / попередній напрям (scancodes 72 80 75 77) |
| HART | серця ♥, які ще треба зібрати (hart = серце) |
| KLAVER | трефи ♣, які ще треба зібрати (klaver = трефа) |
| BONUS / BMIN | часовий bonus і те, наскільки він падає за хід |
| AANTAL | скільки предметів кожного типу розсипати (aantal = кількість) |
| Z | секунди на хід; 999 = покроково, мале число = real-time |
| LIVE / LEVEL | залишок життів / поточний рівень |
| ZCORE / ZORE | score / high score (спеціально лишені floating-point — див. рядок 80) |
| OP | очки, які додаються цього разу (передаються routine рахунку, 1190) |
| S() B() D() | backup popup / рядки брам / стан рухомих стріл |
| VIDEO | сегмент памʼяті екрана (&HB000 mono / &HB800 color) |
Що означають символи (CP437)
| 32 | порожня клітинка | |
| 219 | █ | голова змії |
| 186 205 187 188 201 200 | ║═╗╝╔╚ | тіло змії: прямі лінії і кути |
| 179 196 197 … | │─┼ | стіни лабіринту і рамки |
| 1 | ☺ | смайлик — поганий (−50) |
| 3 | ♥ | серце (+10) |
| 5 | ♣ | трефа (+25) |
| 10 | ◙ | камінь — можна штовхати |
| 24 26 27 | ↑→← | рухомі стріли — смертельні |
| attr 7 / 15 | звичайний / яскравий |
Клавіші (scancodes у E)
| 72 80 75 77 | ↑↓←→ | керувати змією |
| 27 | ESC | здатися, якщо застрягли (коштує життя) |
| 67 / 68 | F9 / F10 | cheat: +життя і пропуск / пропустити рівень |
Як проходить один хід (рядки 420–1010)
- Чекати до
Zсекунд на стрілку або дозволити змії зберегти напрям. - Зняти
BMINз bonus. - Перетворити напрям на крок екрана і визначити клітинку, у яку входить голова.
- Зробити
PEEKцієї клітинки і відреагувати: порожнє місце, серце/трефа, камінь, смертельна стріла або блок стіною. - Перетворити стару голову на правильний символ ═║╗╝╔╚ і намалювати нову голову █.
- Підсвітити тіло і просунути стріли/брами рівня на один крок.
- Повторювати, доки всі серця і трефи не зібрані.