Как стать автором
Обновить

Самая маленькая игра в мире (58 байт)

Assembler
Для тех, кто читал статью в песочнице: добавил раздел «Можно ли сделать игру меньше?».

Прочитав историю одного байта, вспомнил свою историю.

Когда я учился в школе и только начинал программировать меня очень привлекал ассемблер и оптимизация. А именно — кропотливая оптимизация, с подсчетам тактов и байтов. На летних каникулах у меня с двоюродным братом появилась идея написать самую маленькую игру в мире.

Первый прототип, размером 80 байт, был готов на следующий день. (Поскольку о контроле версий тогда я даже не догадывался, то остается верить воспоминаниям). С этого момента началась моя борьба за байты. Помню, довольно быстро размер был уменьшен до 65 (или около того), дальше каждый байт давался все с большим и большим трудом. К концу лета результат был 58 байт.

Сюжет и управление


Вы несетесь по трассе на грузовике с двумя прицепами. Слева от вас разделительная полоса, справа обочина укрытая травой. На дороге встречаются люди и деревья (может ямы). Ваша задача: не сбивать людей и не врезаться в деревья (не попадать в ямы).
Управление: стрелки влево-вправо — поворот; Esc — пауза.


Скриншот




Исходный код


begin: <br>
; ds указывает на видеопамять <br>
push 0b800H <br>
pop ds <br>
; установить графический режим 40×25 <br>
int 10H <br>
; bx = 700H - смещение, по которому находиться грузовик <br>
mov bh, 7H <br>
<br>
main_loop: <br>
; Задержка и вывод грузовика на экран <br>
xchg cx, ax ; mov ah, 0 <br>
int 1AH <br>
mov [bx], dl <br>
delay: <br>
int 1AH <br>
cmp [bx], dl <br>
je delay <br>
<br>
; si - смещение следующего препятствия <br>
xchg ax, si <br>
add al, dl <br>
xchg ax, si <br>
<br>
xchg ax, cx ; mov cx, 0 <br>
<br>
; Получение нажатой клавиши <br>
in al, 60H <br>
cmp al, 77 <br>
jnz keytest1 <br>
; вправо <br>
inc bx <br>
inc bx <br>
keytest1: <br>
; влево <br>
ja keytest2 <br>
dec bx <br>
dec bx <br>
keytest2: <br>
; очистка буфера клавиатуры <br>
mov ah, 0CH <br>
int 21H <br>
; скролл экрана на 1 строчку <br>
mov ax, 0701H <br>
mov dx, 1827H <br>
int 10H <br>
<br>
; вывод препятствия <br>
mov [si], ax <br>
; вывод травы и разделительной полосы <br>
mov [di+51], dx <br>
; проверка что перед грузовиком нет препятствий <br>
cmp [bx], dh <br>
ja main_loop <br>
<br>
ret <br>

Архив с исходником и бинарником (для компиляции использовался Tasm)

Комментарии


В XP программа работает, но таймер работает не гладко и сначала не обнулено состояние клавиатуры. В DosBox'е работает без проблем.

В исходнике, две инструкции (push 0b800H и mov [di+51], dx) записаны в машинном коде (db 68H, 00H, 0b8H и db 89H, 55H, 51H), это связано с тем, что Tasm их не воспринимал в режиме компиляции по умолчанию. По-моему он требовал включения инструкций x386, хотя могу и ошибаться.

Можно ли сделать игру меньше?


Скорее всего — да. Много места занимает прокрутка экрана (8 байт) и задержка (10 байт). Если поменять направление движения (препятствия надвигаться снизу вверх), то скролл можно заменить быстрым выводом символа перевода строки (mov al, 0Ch; int 29h). Задержку можно заменить проверкой состояния двойного слова по адресу 0040:006Сh. Там должен находиться счетчик отсчетов таймера с полуночи (Timer ticks since midnight).

UPD: Спасибо! Перенес в блог «Ассемблер»

UPD2: Imp5 подсказывает, что я не совсем прав. Shifticida — игра для двоих игроков, которая занимает 32 байта. Так что правильное название топика: «Самая маленькая гоночная игра в мире»
Теги:ассемблеригрыоптимизация
Хабы: Assembler
Всего голосов 329: ↑326.5 и ↓2.5 +324
Просмотры44.5K

Похожие публикации

Аудит и оптимизация QA-процессов
25 июня 202113 000 ₽Лаборатория Качества
Программист iOS
19 июня 202172 000 ₽GeekBrains
PHP программист
19 июня 202148 000 ₽GeekBrains
Программист Android
19 июня 202184 000 ₽GeekBrains
WEB-разработчик
19 июня 202196 000 ₽GeekBrains

Лучшие публикации за сутки