Инструментальный код Гольф


39

ТАС Гольф

SMB1 1-1 окончание

В стиле ускоренного запуска с помощью инструмента с поворотом кода в гольф цель этой задачи состоит в том, чтобы завершить Мир 1-1 оригинальной игры Super Mario Bros для NES на выбранном вами языке программирования за минимальное количество байтов, насколько это возможно, используя только входы игрового контроллера в формате, который я опишу ниже. Ваша программа должна вывести stdoutсписок строк в этом формате, созданный специально для этой задачи:

up down left right start select A B

Начиная с первого кадра, каждая новая строка представляет входные данные для контроллера 1 для определенного кадра. Порядок кнопок на кадр не имеет значения, и они могут быть разделены любым количеством пробелов без новой строки. Все или никакие или некоторые из названий кнопок могут быть включены в строку. Например, простая программа на Python, которая нажимает D-pad на 3 кадра, а затем нажимает A, может выглядеть так:

for _ in range(3): print('right')
print('A')

И его вывод (который я проверю в своем эмуляторе) будет:

right
right
right
A

Здесь мы определяем «успех» как достижение флага в конце Мира 1-1, изображенного выше. Оценка для этого примера представления Python, если она прошла успешно (чего не происходит), составила бы 44 байта , или исходную длину программы Python.

Для примера рабочего входного файла, который я создал на основе текущего самого быстрого TAS , см. Этот Github Gist: https://gist.github.com/anonymous/6f1a73cbff3cd46c9e1cf8d5c2ff58e1 Обратите внимание, что этот файл завершает всю игру.

Нет способа ввода входных данных субкадра . Также нет способа ввода входных данных в контроллер игрока 2, но это также не должно быть необходимым (или полезным) для прохождения уровня или игры.

Используемой версией SMB будет исходное ПЗУ iNES для США / Японии (md5sum 811b027eaf99c2def7b933c5208636de - версия для США точно такая же, как и для японской версии, поэтому либо будет работать, ПЗУ обычно помечается Super Mario Bros (JU) (PRG 0)или аналогично).

Чтобы проверить представленные материалы, я буду запускать программы, stdoutпомещать их в файл input.txt и загружать их в FCEUX, используя скрипт Lua, который mario.luaя написал для этой задачи:

for line in io.lines('input.txt') do
   local t = {}
   for w in line:gmatch("%S+") do
      t[w] = true;
   end;
   joypad.set(1, t);
   emu.frameadvance();
end;
while (true) do
   emu.frameadvance();
end;

Команда конкретного Я буду использовать это fceux mario.nes --loadlua mario.lua. Нет ограничений по времени для программ, хотя они должны в конечном итоге прекратить.

Это небольшая строчка из Bash, которую я сделал, чтобы конвертировать файл фильма FCEUX (.fm2) в файл input.txt для моего сценария, если это поможет:

cat movie.fm2 | cut -d'|' -f 3 | sed 's/\.//g' | sed 's/R/right /g' | sed 's/L/left /g' | sed 's/D/down /g' | sed 's/U/up /g' | sed 's/T/start /g' | sed 's/S/select /g' | sed 's/B/B /g' | sed 's/A/A /g' | tail -n +13 > input.txt

Для справки: карта мира 1-1 в полном разрешении (откройте изображение на новой вкладке для просмотра в полном разрешении): (источник: mariouniverse.com )Мир 1-1

Примечание. На первый взгляд это может показаться проблемой сложности Колмогорова в моем файле input.txt. Однако на самом деле задача более сложная, чем та, потому что (a) предоставленный мною input.txt определенно не самый короткий и (b) никогда не было попытки создать максимально короткий набор нажатий клавиш для SMB в этом формате. , «Наименьшее количество возможных кнопок», известное TAS, отличается тем, что позволяет удерживать кнопки в течение длительного времени, что увеличит длину до желаемого результата в этой задаче.


1
Хотя вы предоставили видео уровня, я не могу сосчитать, сколько прав на видео. Не могли бы вы рассказать нам о необходимых шагах?

1
Вы разместили это в Песочнице? Я не помню этого.

1
Я думаю, это довольно забавно, у вас есть 16 голосов и нет ответов :)

2
@JackBates - признак хорошего, непростого, нетривиального вопроса
FlipTack,

1
404 на этом полном изображении карты разрешения, я думаю
Лиам

Ответы:


20

Python 2, 69 48 46 44 байтов

print"start\n\n"*19+(27*"A right\n"+"\n")*99

Посмотрите это в действии на YouTube!

Автоматически обнаруживается с помощью (модифицированной версии) этого хакерского скрипта:

start = 18
oncycle = 21
offcycle = 4


while true do
    emu.poweron()
    -- emu.speedmode("maximum")

    starting = 0
    i = 0
    frames = 0
    last_mario_x = -1

    emu.message(start .. " " .. oncycle .. " ".. offcycle)


    state = 0
    while state ~= 6 and state ~= 11 and frames < 4000 do
        if frames > 500 and frames % 100 == 0 then
            mario_x = memory.readbyte(0x6D) * 0x100 + memory.readbyte(0x86)
            if mario_x == last_mario_x then emu.message("stuck " .. mario_x .. " " .. last_mario_x); break end
            last_mario_x = mario_x
        end

        if starting < start then
            joypad.set(1, {start=1})
            emu.frameadvance(); frames = frames + 1;
            joypad.set(1, {})
            emu.frameadvance(); frames = frames + 1;
            starting = starting + 1
        else
            if i < oncycle then
                joypad.set(1, {A=1, B=1, right=1})
                i = i + 1
            else
                joypad.set(1, {})
                i = i +  1
                if i == oncycle + offcycle then
                    i = 0
                end
            end

            emu.frameadvance()
            frames = frames + 1
        end

        state = memory.readbyte(0x000E)
        if state == 4 then
            emu.message("success!")
            os.exit()
            break
        end

    end

    if start < 30 then
        start = start + 1
    elseif offcycle < 10 then
        start = 18
        offcycle = offcycle + 1
    else
        offcycle = 1
        oncycle = oncycle + 1
    end
end

1
@ Гарри Пожалуйста, подтвердите новую версию.
orlp

1
@ Гарри, я только что добавил еще одну новую версию, которая экономит еще 2 байта, не используя кнопку B! Он едва вписывается в 99 повторов, почти пришлось тратить байт на выполнение 100+ повторов.
orlp

1
44-байтовая версия также подтвердила, интересно смотреть!
Гарри

1
Ааа, это такой ответ, который я искал, но я не мог найти правильные цифры! Очень красиво сделано.
Линн

1
@Harry Это моя запись: youtube.com/watch?v=2-I1EEOlQYA
orlp

5

Python 2, 107 байт

i=0
print'\n'*33+'start'
for c in'~~22 +  2 2? @  F        . \r0'+'@'*10:print'A B right\n'[i:]*ord(c);i^=2

Очень впечатляет и уже намного короче, чем я думал! Может, мне все-таки следовало играть в полную версию, ха-ха. Также я проверил это и могу подтвердить, что он завершает уровень, если я смогу сделать это для записи, может быть, я загружу их все как видео YouTube!
Гарри

1

JavaScript (ES6), 59 символов

_=>`start

`[a="repeat"](19)+(`A right
`[a](27)+`
`)[a](99)

Это выводит тот же текст, что и ответ orlp . Я сам пытался придумать лучший метод, но фильмы, которые я конвертировал в input.txtфайл, не всегда воспроизводились должным образом. Всякий раз, когда я пытался запустить эмулятор из cmd, я получал сообщение об ошибке "an unknown error occurred".


Не могу запустить его прямо сейчас на моем конце, но если он выведет тот же input.txt, что и ответ orlp, мы назовем его проверенным!
Гарри
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.