Codice golf assistito da utensili


39

TAS Golf

Finale SMB1 1-1

Nello stile di uno speedrun assistito da utensili con un tocco di code-golf, l'obiettivo di questa sfida è quello di completare il mondo 1-1 del gioco originale Super Mario Bros per il NES nel linguaggio di programmazione scelto nel minor numero di byte possibile, usando solo gli input del controller di gioco nel formato che descriverò di seguito. Il tuo programma deve produrre stdoutun elenco di righe in questo formato, creato appositamente per questa sfida:

up down left right start select A B

A partire dal primo frame, ogni newline rappresenta gli ingressi per il Controller 1 per un frame specifico. L'ordine dei pulsanti per frame non ha importanza e possono essere separati da qualsiasi quantità di spazio bianco non newline. Tutti o nessuno o alcuni dei nomi dei pulsanti possono essere inclusi per riga. Ad esempio, un semplice programma Python che preme il D-pad a destra per 3 fotogrammi e quindi preme A potrebbe apparire così:

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

E il suo output (che vorrei inserire nel mio emulatore per verificare) sarebbe:

right
right
right
A

Qui, definiamo il "successo" come raggiungere la bandiera alla fine del Mondo 1-1 nella foto sopra. Il punteggio per questo esempio di invio di Python, se ha avuto successo (cosa che non ha successo), sarebbe 44 byte , o la lunghezza originale del programma Python.

Per un esempio di file di input funzionante che ho creato sulla base dell'attuale TAS più veloce , vedere questo Github Gist: https://gist.github.com/anonymous/6f1a73cbff3cd46c9e1cf8d5c2ff58e1 Nota che questo file completa l'intero gioco.

Non è possibile immettere input di sottotelaio . Inoltre, non è possibile immettere input nel controller di Player 2, ma ciò non dovrebbe essere necessario (o utile) per completare il livello o il gioco.

La versione di SMB utilizzata sarà la ROM iNES originale USA / Giappone (md5sum 811b027eaf99c2def7b933c5208636de - la versione USA è esattamente la stessa della versione giapponese, quindi funzionerà, la ROM è comunemente etichettata Super Mario Bros (JU) (PRG 0)o simile).

Per testare gli invii, stdouteseguirò i programmi, li instraderò in un file input.txt e li caricherò in FCEUX usando questo script Lua che mario.luaho scritto per questa sfida:

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;

Il comando specifico che userò è fceux mario.nes --loadlua mario.lua. I programmi non hanno limiti di tempo, anche se alla fine devono terminare.

Questa è una piccola riga di Bash che ho creato per convertire un file di film FCEUX (.fm2) in un input.txt per il mio script, se aiuta:

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

Per riferimento, ecco una mappa a piena risoluzione del Mondo 1-1 (apri l'immagine in una nuova scheda per la piena risoluzione): (fonte: mariouniverse.com )Mondo 1-1

Nota: a prima vista, può sembrare una sfida alla complessità di Kolmogorov sul mio file input.txt. Tuttavia, in realtà la sfida è più complessa di così perché (a) input.txt che ho fornito non è sicuramente il più breve possibile e (b) non c'è mai stato un tentativo di creare il set più breve possibile di tasti premuti per le PMI in questo formato . Il minor numero possibile di TAS noti è diverso perché consente di tenere i pulsanti a lungo, il che aggiungerebbe lunghezza all'output desiderato in questa sfida.


1
Mentre hai fornito un video di livello, non posso contare quanti diritti ci sono nel video. Potresti dirci le mosse necessarie?

1
Hai pubblicato questo nella sandbox? Non me lo ricordo.

1
Penso che sia abbastanza divertente che tu abbia 16 voti e nessuna risposta :)

2
@JackBates questo è il segno di una domanda buona, stimolante, non banale
FlipTack

1
404 su quell'immagine di mappa ad alta risoluzione penso
Liam

Risposte:


20

Python 2, 69 48 46 44 byte

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

Guardalo in azione su YouTube!

Trovato automaticamente con (una versione modificata di) questo script hacky:

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
@Harry Verifica la nuova versione.
Orlp

1
@Harry Ho appena aggiunto un'altra nuova versione che salva altri 2 byte di ... non usando il pulsante B! Si adatta a malapena alle 99 ripetizioni, quasi ha dovuto sprecare un byte nel fare oltre 100 ripetizioni.
Orlp

1
Confermata anche la versione a 44 byte, divertente da guardare!
Harry,

1
Ahh, questo è il tipo di risposta che cercavo, ma non sono riuscito a trovare i numeri giusti !! Molto ben fatto.
Lynn,

1
@Harry Questa è una mia registrazione: 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

Molto impressionante e già molto più corto di quanto pensassi! Forse avrei dovuto rimanere bloccato con il gioco completo dopo tutto, ahah. Inoltre ho provato questo e posso confermare che completa il livello, se riesco a farlo registrare forse li caricherò tutti come video di YouTube!
Harry,

1

JavaScript (ES6), 59 caratteri

_=>`start

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

Questo genera lo stesso testo della risposta di orlp . Ho provato a trovare un metodo migliore, ma i film che ho convertito in un input.txtfile non sono stati sempre riprodotti correttamente. Ogni volta che ho provato a eseguire l'emulatore da cmd, ho ricevuto un errore indicando "an unknown error occurred".


Non posso eseguirlo ora da parte mia, ma se emette lo stesso input.txt della risposta di orlp, lo chiameremo verificato!
Harry,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.