Pull to refresh

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

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

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

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

Первый прототип, размером 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 байта. Так что правильное название топика: «Самая маленькая гоночная игра в мире»
Tags:
Hubs:
+324
Comments133

Articles

Change theme settings