Как написать игру для компьютера, в котором нет устройств ввода и вывода

в 8:14, , рубрики: a fistful of relays, логические игры, ненормальное программирование, Программирование, старое железо

Что можно сделать с компьютером на электромагнитных реле у которого нет никаких устройств ввода, а из устройств вывода — только дамп восьми регистров?

Поиграть в игры, конечно! Играли же древние люди на калькуляторах МК-61/52, которые лишь немногим нагляднее.

Как написать игру для компьютера, в котором нет устройств ввода и вывода - 1

Угадай число

Начал я с игры, где компьютер с помощью половинного деления должен найти загаданное игроком целое число от 0 до 100.

Свою догадку компьютер записывает в регистр A, а затем останавливается.

Значения всех регистров можно увидеть благодаря светодиодам, встроенным в реле:

Как написать игру для компьютера, в котором нет устройств ввода и вывода - 2

Теперь игрок должен изменить код программы в ПЗУ, заменив константу, загружаемую в регистр D. Если там не 0, это значит, что предположение больше загаданного числа. Иначе — меньше. После этого нужно нажать кнопку «продолжить работу». Проверив регистр D, компьютер использует прежнее предположение как верхний или нижний предел в следующей попытке.

Первая версия программы
  MOVI B, 1       ; 00: 10000001 00000001
  MOVI C, 101     ; 01: 10000010 01100101
 Loop:
  ADD A, B, C     ; 02: 01001000 00011010
  SHR A, A        ; 03: 01111000 00001100
  HALT            ; 04: 00010000 00000000
  MOVI D, guess   ; 05: 10000011 iiiiiiii
  OR F, D, D      ; 06: 01101000 00110011
  JMP NZ, Greater ; 07: 11100111 00001010
  MOV B, A        ; 08: 00011001 00000000
  JMP Loop        ; 09: 10000111 00000010
 Greater:
  MOV C, A        ; 0a: 00011010 00000000
  JMP Loop        ; 0b: 10000111 00000010

Как написать игру для компьютера, в котором нет устройств ввода и вывода - 3

Недостаток первой программы в том, что ей неудобно пользоваться. Это можно понять, посмотрев на фотографию ПЗУ — не очень-то легко переключать такие маленькие тумблеры, играя в игру (а ведь при этом надо ещё и следить, чтобы программу случайно не испортить).

Поэтому я придумал другой вариант ввода. Для отладки рядом с каждым регистром предусмотрен тумблер для сброса его значения. Его переключать намного удобнее, чем менять ПЗУ.

Теперь компьютер заранее заносит единицу в регистр D, а игрок либо сбрасывает его (если догадка меньше, чем задуманное число), либо оставляет как есть (если догадка больше).

Финальная версия программы

  MOVI B, 1       ; 00: 10000001 00000001
  MOVI C, 101     ; 01: 10000010 01100101
 Loop:
  ADD A, B, C     ; 02: 01001000 00011010
  SHR A, A        ; 03: 01111000 00001100
  MOVI D, 1       ; 04: 10000011 00000001
  HALT            ; 05: 00010000 00000000
  OR F, D, D      ; 06: 01101000 00110011
  JMP NZ, Greater ; 07: 11100111 00001010
  MOV B, A        ; 08: 00011001 00000000
  JMP Loop        ; 09: 10000111 00000010
 Greater:
  MOV C, A        ; 0a: 00011010 00000000
  JMP Loop        ; 0b: 10000111 00000010

Игра вычитания (игра Баше)

Другая классическая игра, которую часто реализуют начинающие программисты — игра Баше.
В ней два игрока из кучки, содержащей первоначально N предметов, по очереди берут не менее одного и не более М предметов. Проигравшим считается тот, кому нечего брать.

Как написать игру для компьютера, в котором нет устройств ввода и вывода - 4

В моём варианте игра идёт с компьютером. Изначально в кучке 21 предмет (например, 21 спичка). Игроки берут от 1 до 3 спичек в свой ход, а выигрывает тот, кто берёт последнюю спичку.

В игре есть выигрышная стратегия для первого игрока — всегда оставлять число спичек, которое кратно четырём. Так как 0 тоже кратно четырём, то второй игрок привести игру в эту позицию не сможет, а значит проиграет.

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

Первая версия программы

  MOVI A, 21   ; 00: 10000000 00001101
 Loop:
  HALT         ; 01: 00010000 00000000
  MOVI B, move ; 02: 10000001 000000mm
  SUB A, A, B  ; 03: 01011000 00001001
  AND C, A, 3  ; 04: 01100010 10001011
  MOVI Z, C, 1 ; 05: 10010010 00000001
  SUB A, A, C  ; 06: 01011000 00001010
  JMP Loop     ; 07: 10000111 00000001

В первой версии использовался тот же подход, что и для «угадай число» — в свой ход нужно было закодировать число спичек внутри одной из инструкций. Даже можно было считерить и взять все спички сразу, а компьютер ничего не заметит.

Но потом я переписал и эту программу тоже. Теперь в три регистра (B, C, D) компьютер заносит по 1, а игрок должен сбросить 0, 1 или 2 из них. Оставшиеся единицы — это те спички, которые он берёт. Читерить тоже можно, если сбросить все три регистра (как будто не берёшь ничего).

Финальная версия программы

 MOVI A, 21   ; 00: 10000000 00010101
 Loop:
  MOVI B, 1    ; 01: 10000001 00000001
  MOVI C, 1    ; 02: 10000010 00000001
  MOVI D, 1    ; 03: 10000011 00000001
  HALT         ; 04: 00010000 00000000
  SUB A, A, B  ; 05: 01011000 00001001
  SUB A, A, C  ; 06: 01011000 00001010
  SUB A, A, D  ; 07: 01011000 00001011
  AND C, A, 3  ; 08: 01100010 10001011
  MOVI Z, C, 1 ; 09: 10010010 00000001
  SUB A, A, C  ; 0a: 01011000 00001010
  JC Exit      ; 0b: 10110111 00001101
  JNZ Loop     ; 0c: 11100111 00000001
 Exit:
  HALT         ; 0d: 00010000 00000000

Конечно программа получилось несколько длиннее, но зато пользоваться ей значительно удобнее.

Дальше я планирую допаять ПЗУ (сейчас есть только 32 слова из возможных 64), а также добавить-таки устройство ввода в виде матрицы из тумблеров. Может тогда получится сделать хотя бы крестики-нолики.

Автор: Dovgaluk

Источник


* - обязательные к заполнению поля