Игра 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

© Habrahabr.ru