...

вторник, 10 апреля 2018 г.

Игра Snake в 95 байт

image

История создания


Змейка (Питон, Удав), как ее называют в народе, одна из первых игр цифровой (компьютерной) эпохи середины 70-ых годов. В то время игры выпускались на отдельном игровом автомате с одной игрой, а сам автомат был под нее стилизован. Примерами таких игр, кроме Snake, являются Space Invaders, Pac-Man, Arkanoid и другие.

Игра Змейка имеет незамысловатый геймплей. Игрок управляет длинной линией с изгибами в 90 градусов с целью «поедания» все большего числа кроликов, представленых в виде точек на экране, от чего увеличивается длина Змейки. Сложность заключается в том, что Змейка не может пересекать саму себя.
С тех пор игра Змейка пережила множество воплощений на разных устройствах. Где-то вместо линии Змейка отображалась символами, так как технически вычислительное устройство не позволяло выводить произвольную графику. На более современных компьютерах Змейка получила возможность поворачиваться на произвольный угол, а не только на 90 градусов. Простая игра и ее идея были перенесены практически на все виды вычислительной техники, даже на программируемые микрокалькуляторы и микроконтроллеры, которые управляют холодильниками и другими бытовыми приборами. Идея Змейки популярна и сейчас, недавний бум пришелся на свежую реинкарнацию в виде сетевой игры slither.io.

Интересуясь программированием, в 90-е годы и после я читал множество литературы, где одной из учебных программ была игра Змейка. Также попадались статьи соревновательного характера: люди старались уложиться в какие-то технические параметры компьютера. Я же в свою очередь тоже практиковался в программировании и писал игру на разных языках и платформах. В электронном журнале на платформе ZX-Spectrum, мне попалась статья с описанием создания Змейки в 256 байт на языке Ассемблер. Автор статьи подробно описал свою работу и заявил, что вряд ли можно написать игру короче, чем 256 байт. Через некоторое время появилась другая версия в 121 байт, но за счет уменьшения размера пострадал геймплей.

Однажды, общаясь с начинающим программистом, я посоветовал написать хоть какой-то законченный проект, и речь зашла про игру Змейка. Я решил поддержать программиста тем, что пообещал написать свою реализацию игры, но не просто так, а на ZX-Spectrum и языке Ассемблер.

Первую версию змейки я написал за пару часов, и весила она чуть больше 150 байт. Я вспомнил про статьи в электронном журнале и захотел побить рекорд. Следующая версия уже весила 100 байт, но и потраченное время разработки перевалило за 6 часов. Остановившись на этом, показал свою версию игры, а начинающий программист – свою, и после я забыл об игре на некоторое время.

Разбирая папку со своими проектами и исходниками, я наткнулся на исходный код своей Змейки и понял, что код можно немного модифицировать и сократить еще на пару байт. Процесс оптимизации занял целый день, а сокращение составило только 5 байт. В итоге игра стала весить 95 байт.

Технические подробности


Технические подробности игры snake в 95 байт
  • 59 строчек кода без комментариев
  • Полная релоцируемость программы (размещение в любой адрес без перекомпиляции)
  • Не используется стек
  • Используется только основной набор регистров: a,b,c,d,e,h,l и r как генератор случайности
  • Без использования процедур ПЗУ
  • Честная инициализация экрана и бордера
  • Классическое управление клавишами: 6,7,8,9 (Sinclair Joystick)
  • Каждую инициализацию псевдослучайным образом расставляться кролики

Код состоит из 3 блоков
  • Инициализация переменных и экрана
  • Опрос клавиш на нажатие и изменение направления движения
  • Обработка игровых событий

Регистры используются в основном как именные переменные, так:
  • Регистр a – используется по как промежуточный результат и манипулятор с отдельными битами
  • Регистровая пара bc – это направление движения принимает всего 4 значения за весь игровой процесс: #ffe0, #0020, #0001, #ffff
  • Регистровая пара de – это текущий индекс обработки массива (атрибут)
  • Регистровая пара hl – это текущие координаты головы змейки в адресном пространстве атрибут

В блоке инициализации de и hl, поменяны местами для сокращения логической операции распределения кроликов

В игре используются два глобальных цикла, от начала программы до конца (полная инициализация) и игровой цикл (после расстановки кроликов)

Код игры

   org #8000
        ld de,#598f;snake xy
        ld hl,#5aff
        ld b,l
        ld c,l
;---
rabbit1 ld (hl),b
        ld a,r
        cp l
        jr z,rabbit2
        inc (hl)
rabbit2 dec hl
        bit 3,h
        jr nz,rabbit1
        ex hl,de
;---
l1      xor a
        out (#fe),a
clr     ld (de),a
        dec de
        bit 6,d
        jr nz,clr
;---
        ld (hl),33
        ld d,#5a
move1   ld a,(de)
        dec a
        cp 254
        jr nc,move2
        ld (de),a
move2   jr nz,move3
        dec (hl)
move3   dec de
        bit 3,d
        jr nz,move1
;---
        ld a,#ef
        in a,(#fe)
        rra
        rra
        jr c,$+5
        ld bc,#ffe0
        rra
        jr c,$+5
        ld bc,#0020
        rra
        jr c,$+5
        ld bc,#0001
        rra
        jr c,$+4
        ld b,e;ld bc,#ffff
        ld c,e
;---
        ld a,(hl)
        and %00100000
        add hl,bc
        or (hl)
        inc a
        cp 7
        jr nc,begin
        ld a,h
        inc a
        and %00000011
        jr z,begin
        jr l1

Let's block ads! (Why?)

Комментариев нет:

Отправить комментарий