Golf Kode Alat Bantu

39

Golf TAS

SMB1 1-1 berakhir

Dengan gaya speedrun berbantu alat dengan twist kode-golf, tujuan dari tantangan ini adalah untuk menyelesaikan World 1-1 dari game Super Mario Bros asli untuk NES dalam bahasa pemrograman pilihan Anda dalam sesedikit mungkin byte, hanya menggunakan input controller dalam game dalam format yang akan saya jelaskan di bawah ini. Program Anda harus menampilkan ke stdoutdaftar baris dalam format ini, dibuat khusus untuk tantangan ini:

up down left right start select A B

Dimulai dengan frame pertama, setiap baris baru mewakili input untuk Pengendali 1 untuk frame tertentu. Urutan tombol per frame tidak masalah, dan mereka dapat dipisahkan dengan jumlah spasi spasi non-baris baru. Semua atau tidak ada atau beberapa nama tombol dapat dimasukkan per baris. Misalnya, program Python sederhana yang menekan D-pad tepat untuk 3 frame dan kemudian menekan A mungkin terlihat seperti ini:

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

Dan hasilnya (yang akan saya masukkan ke emulator saya untuk diverifikasi) adalah:

right
right
right
A

Di sini, kami mendefinisikan 'kesuksesan' sebagai mencapai bendera di akhir Dunia 1-1 seperti yang digambarkan di atas. Skor untuk pengiriman contoh Python ini, jika berhasil (yang tidak), akan menjadi 44 byte , atau panjang asli dari program Python.

Untuk contoh file input yang berfungsi saya buat berdasarkan TAS tercepat saat ini , lihat Github Gist ini: https://gist.github.com/anonymous/6f1a73cbff3cd46c9e1cf8d5c2ff58e1 Perhatikan bahwa file ini melengkapi seluruh permainan.

Tidak ada cara untuk memasukkan input subframe . Juga tidak ada cara untuk memasukkan input pada pengontrol Player 2, tetapi itu juga tidak perlu (atau berguna) untuk menyelesaikan level atau game.

Versi SMB yang digunakan adalah ROM AS / Jepang iNES yang asli (md5sum 811b027eaf99c2def7b933c5208636de - versi USA sama persis dengan versi Jepang sehingga keduanya dapat berfungsi, ROM umumnya berlabel Super Mario Bros (JU) (PRG 0)atau serupa).

Untuk menguji pengiriman, saya akan menjalankan program, menyalurkannya stdoutke file input.txt, dan memuatnya ke FCEUX menggunakan skrip Lua yang mario.luasaya tulis untuk tantangan ini:

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;

Perintah spesifik yang akan saya gunakan adalah fceux mario.nes --loadlua mario.lua. Tidak ada batasan waktu untuk program, meskipun mereka akhirnya harus berakhir.

Ini adalah Bash one-liner kecil yang saya buat untuk mengonversi file film FCEUX (.fm2) ke input.txt untuk skrip saya, jika itu membantu:

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

Untuk referensi, berikut adalah peta Dunia 1-1 dengan resolusi penuh (buka gambar di tab baru untuk resolusi penuh): (sumber: mariouniverse.com )Dunia 1-1

Catatan: Sekilas, ini mungkin tampak seperti tantangan kompleksitas Kolmogorov pada file input.txt yang saya berikan. Namun, pada kenyataannya tantangannya lebih kompleks dari itu karena (a) input.txt yang saya berikan jelas bukan yang sesingkat mungkin dan (b) tidak pernah ada upaya untuk membuat set penekanan tombol sesingkat mungkin untuk SMB dalam format ini. . 'Tombol paling sedikit yang mungkin' diketahui TAS berbeda karena memungkinkan untuk menahan tombol untuk waktu yang lama, yang akan menambah panjang pada output yang diinginkan dalam tantangan ini.

Harry
sumber
1
Meskipun Anda telah memberikan video tingkat tersebut, saya tidak dapat menghitung berapa banyak hak dalam video tersebut. Bisakah Anda memberi tahu kami langkah yang diperlukan?
1
Apakah Anda memposting ini di Sandbox? Saya tidak ingat itu.
1
Saya pikir ini sangat lucu Anda memiliki 16 upvotes dan tidak ada jawaban :)
2
@JackBates itu pertanda pertanyaan yang baik, menantang, non-sepele
FlipTack
1
404 pada gambar peta resolusi penuh yang saya pikir
Liam

Jawaban:

20

Python 2, 69 48 46 44 byte

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

Lihat beraksi di youtube!

Ditemukan secara otomatis dengan (versi modifikasi dari) skrip hacky ini:

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
orlp
sumber
1
@ Harry Harap verifikasi versi baru.
orlp
1
@ Harry Saya baru saja menambahkan versi baru yang menghemat 2 byte lebih banyak dengan ... tidak menggunakan tombol B! Ini hampir tidak cocok dalam 99 pengulangan, hampir harus membuang satu byte untuk melakukan 100+ pengulangan.
orlp
1
Versi 44-byte juga dikonfirmasi, menyenangkan untuk ditonton!
Harry
1
Ahh, ini adalah jawaban yang saya cari, tetapi saya tidak dapat menemukan angka yang tepat !! Dilakukan dengan sangat baik.
Lynn
1
@Harry Ini rekaman saya: youtube.com/watch?v=2-I1EEOlQYA
orlp
5

Python 2, 107 byte

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
Lynn
sumber
Sangat mengesankan dan sudah jauh lebih pendek dari yang saya kira! Mungkin seharusnya aku terjebak dengan permainan penuh, haha. Saya juga menguji ini dan dapat mengonfirmasi bahwa itu menyelesaikan level, jika saya bisa merekamnya, mungkin saya akan mengunggah semuanya sebagai video YouTube!
Harry
1

JavaScript (ES6), 59 karakter

_=>`start

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

Ini menghasilkan teks yang sama dengan jawaban orp . Saya mencoba menggunakan metode yang lebih baik, tetapi film yang saya konversi menjadi input.txtfile tidak selalu diputar dengan benar. Setiap kali saya mencoba menjalankan emulator dari cmd, saya mendapat pesan kesalahan "an unknown error occurred".

Luke
sumber
Tidak dapat menjalankannya sekarang di ujung saya, tetapi jika itu menghasilkan input.txt yang sama dengan jawaban orlp maka kita akan menyebutnya diverifikasi!
Harry