Хабрахабр

[Перевод] Как я научил ИИ играть в Tetris для NES. Часть 1: анализ кода игры

В этой статье я исследую обманчиво простые механики Nintendo Tetris, а во второй части расскажу, как создал ИИ, эксплуатирующий эти механики.

Попробуйте сами

О проекте

Для тех, кому не хватает упорства, терпения и времени, необходимых для освоения Nintendo Tetris, я создал ИИ, способный играть самостоятельно. Вы наконец-то сможете добраться до уровня 30 и даже дальше. Вы увидите, как получить максимальное количество очков и понаблюдаете за бесконечным изменением счётчиков рядов, уровней и статистики. Узнаете, какие цвета появляются на уровнях, выше которых не мог забраться человек. Посмотрите, насколько далеко можно зайти.

Требования

Для запуска ИИ вам понадобится универсальный эмулятор NES/Famicom FCEUX. Искусственный интеллект был разработан для FCEUX 2.2.2, самой новой версии эмулятора на время написания статьи.

Попробуйте поискать его в Google. Также вам понадобится ROM-файл Nintendo Tetris (версия для США).

Скачивание

Распакуйте lua/NintendoTetrisAI.lua из этого zip-файла с исходниками.

Запуск

Запустите FCEUX. В меню выберите File | Open ROM… В диалоговом окне Open File выберите ROM-файл Nintendo Tetris и нажмите Open. Запустится игра.

После этого нажмите Run. В меню выберите File | Lua | New Lua Script Window… В окне the Lua Script введите путь к NintendoTetrisAI.lua или нажмите кнопку Browse, чтобы найти его.

Оставьте тип игры A-Type, а музыку можете выбирать любую. Скрипт на Lua перенаправит вас на первый экран меню. Нажмите на Start (Enter), чтобы перейти к следующему экрану меню. На медленных компьютерах музыка может играть очень дёргано, тогда стоит её отключить. Нажмите на Start, чтобы начать игру. Во втором меню можно с помощью клавиш со стрелками изменить начальный уровень. И здесь управление перехватит ИИ.

Максимальный начальный уровень — девятнадцатый. Если после выбора уровня на втором экране меню зажать кнопку геймпада A (изменить раскладку клавиатуры можно в меню Config | Input...) и нажать Start, то начальный уровень будет на 10 больше выбранного значения.

Конфигурация

Чтобы игра шла быстрее, откройте скрипт Lua в текстовом редакторе. В начале файла найдите следующую строку.

PLAY_FAST = false

Замените false на true, как показано ниже.

PLAY_FAST = true

Затем нажмите кнопку Restart в окне Lua Script. Сохраните файл.

Механики Nintendo Tetris

Описание тетримино

Каждой фигуре тетримино соответствует однобуквенное название, напоминающее её форму.

Дизайнеры Nintendo Tetris произвольным образом задали показанный выше порядок тетримино. Фигуры показаны в той ориентации, в которой они появляются на экране, а схема создаёт почти симметричную картинку (возможно, поэтому выбран такой порядок). Индекс последовательности даёт каждому тетримино уникальный числовой ID. Идентификаторы последовательности и типа важны на уровне программирования; кроме того, они проявляют себя в порядке фигур, отображаемом в поле статистики (см. ниже).

19 ориентаций используемых в Nintendo Tetris тетримино закодированы в таблице, расположенной по адресу $8A9C памяти консоли NES. Каждая фигура представлена как последовательность из 12 байтов, которые можно разбить на тройки (Y, tile, X), описывающие каждый квадрат в фигуре. Указанные выше hex-значения координат выше $7F обозначают отрицательные целые числа ($FF= −1, а $FE = −2).

; Y0 T0 X0 Y1 T1 X1 Y2 T2 X2 Y3 T3 X3

8A9C: 00 7B FF 00 7B 00 00 7B 01 FF 7B 00 ; 00: T up
8AA8: FF 7B 00 00 7B 00 00 7B 01 01 7B 00 ; 01: T right
8AB4: 00 7B FF 00 7B 00 00 7B 01 01 7B 00 ; 02: T down (spawn)
8AC0: FF 7B 00 00 7B FF 00 7B 00 01 7B 00 ; 03: T left

8ACC: FF 7D 00 00 7D 00 01 7D FF 01 7D 00 ; 04: J left
8AD8: FF 7D FF 00 7D FF 00 7D 00 00 7D 01 ; 05: J up
8AE4: FF 7D 00 FF 7D 01 00 7D 00 01 7D 00 ; 06: J right
8AF0: 00 7D FF 00 7D 00 00 7D 01 01 7D 01 ; 07: J down (spawn)

8AFC: 00 7C FF 00 7C 00 01 7C 00 01 7C 01 ; 08: Z horizontal (spawn)
8B08: FF 7C 01 00 7C 00 00 7C 01 01 7C 00 ; 09: Z vertical

8B14: 00 7B FF 00 7B 00 01 7B FF 01 7B 00 ; 0A: O (spawn)

8B20: 00 7D 00 00 7D 01 01 7D FF 01 7D 00 ; 0B: S horizontal (spawn)
8B2C: FF 7D 00 00 7D 00 00 7D 01 01 7D 01 ; 0C: S vertical

8B38: FF 7C 00 00 7C 00 01 7C 00 01 7C 01 ; 0D: L right
8B44: 00 7C FF 00 7C 00 00 7C 01 01 7C FF ; 0E: L down (spawn)
8B50: FF 7C FF FF 7C 00 00 7C 00 01 7C 00 ; 0F: L left
8B5C: FF 7C 01 00 7C FF 00 7C 00 00 7C 01 ; 10: L up

8B68: FE 7B 00 FF 7B 00 00 7B 00 01 7B 00 ; 11: I vertical
8B74: 00 7B FE 00 7B FF 00 7B 00 00 7B 01 ; 12: I horizontal (spawn)

8B80: 00 FF 00 00 FF 00 00 FF 00 00 FF 00 ; 13: Unused

Однако в различных частях кода $13 обозначает, что идентификатору ориентации активного тетримино не присвоено значение. Внизу таблицы есть одна неиспользованная запись, потенциально дающая возможность добавления ещё одной ориентации.

Для простоты чтения ниже представлены координаты квадратов в десятичном виде.

-- , { X1, Y1 }, { X2, Y2 }, { X3, Y3 }, },

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть