Araç Destekli Kod Golf


39

TAS Golf

SMB1 1-1 biten

Bir kod destekli twist ile alet destekli bir speedrun tarzında, bu zorluğun amacı, seçtiğiniz programlama dilinde NES için orijinal Super Mario Bros oyununun 1-1 dünyasını mümkün olan en az baytta tamamlamak. sadece oyun içi denetleyici girişlerini kullanarak aşağıda tarif edeceğim formatta. Programınız , bu sorun için özel olarak oluşturulmuş, bu formattaki bir satır listesine çıkmalıdır:stdout

up down left right start select A B

İlk kareden başlayarak, her yeni satır, belirli bir kareye ait Kontrolör 1 için girişleri temsil eder. Kare başına düğme sırası önemli değildir ve herhangi bir miktarda yeni satır olmayan beyaz boşlukla ayrılabilir. Düğme adlarının tümü ya da hiçbiri ya da hiçbiri satır başına dahil edilebilir. Örneğin, D-pad'i 3 kare için sağa ve ardından A'ya basan basit bir Python programı şöyle görünebilir:

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

Ve (doğrulamak için öykünücüme besleyeceğim) çıktısı:

right
right
right
A

Burada, 'başarıyı' yukarıda gösterilen Dünya 1-1'inin bayraklarına ulaşmak olarak tanımlarız. Bu örnek için verilen puan Python gönderimi başarılı olmuşsa (ki başarısız olursa) 44 bayt veya Python programının orijinal uzunluğu olacaktır.

Geçerli en hızlı TAS'ye göre oluşturduğum örnek bir çalışma giriş dosyası için şu Github Gist'e bakın: https://gist.github.com/anonymous/6f1a73cbff3cd46c9e1cf8d5c2ff58e1 Bu dosyanın tüm oyunu tamamladığına dikkat edin.

Alt çerçeve girişlerini girmenin bir yolu yoktur . Oyuncu 2'nin kontrol ünitesine girişleri girmenin bir yolu yoktur, ancak seviyeyi veya oyunu tamamlamak için de gerekli (veya faydalı) olmamalıdır.

Kullanılan SMB sürümü orijinal ABD / Japonya iNES ROM'u olacaktır (md5sum 811b027eaf99c2def7b933c5208636de - ABD sürümü, Japonca sürümüyle tamamen aynıdır, bu nedenle çalışacak, ROM genellikle etiketli Super Mario Bros (JU) (PRG 0)veya benzeridir).

Gönderimleri test etmek için programları çalıştıracağım, stdoutonları bir input.txt dosyasına aktaracağım ve mario.luabu meydan okuma için yazdığım Lua betiğini kullanarak FCEUX'a yükleyeceğim :

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;

Kullanacağım belirli komut fceux mario.nes --loadlua mario.lua. Programların herhangi bir zaman sınırı yoktur, ancak sonunda sona erdirmeleri gerekir.

Bu, FCEUX film (.fm2) dosyasını betiğim için bir input.txt dosyasına dönüştürmek için yaptığım küçük bir Bash tek-liner:

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

Başvuru için, burada Dünya 1-1'in tam çözünürlüklü bir haritası var (resmi tam çözünürlük için yeni bir sekmede aç): (kaynak: mariouniverse.com )Dünya 1-1

Not: İlk bakışta, bu benim input.txt dosyamdaki bir Kolmogorov karmaşıklığı mücadelesi gibi görünebilir. Ancak, gerçekte, zorluk bundan daha karmaşık çünkü (a) sağladığım girdi.txt kesinlikle mümkün olan en kısa yol değil ve (b) bu ​​formatta SMB için mümkün olan en kısa tuşa basma kümesini yaratma girişimi hiç olmadı . 'Mümkün olan en az sayıda düğme' bilinen TAS farklıdır, çünkü düğmelere uzun süre basılı tutulmasına izin verir, bu da bu zorlukla istenen çıktıya uzunluk katar.


1
Düzeyde bir video sağlarken, videoda kaç hak olduğunu sayamam. Bize gereken hareketleri söyler misiniz?

1
Bunu Sandbox'a mı gönderdin? Hatırlamıyorum

1
Bence 16 oy ve cevap yok :) oldukça komik :)

2
@JackBates bu iyi, zorlu, önemsiz bir sorunun
işaretidir

1
404 tam çözünürlüklü harita görüntüsü üzerinde sanırım
Liam

Yanıtlar:


20

Python 2, 69 48 46 44 bayt

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

Youtube'da çalışırken görün!

Bu hacky betiğinin otomatik olarak (değiştirilmiş bir sürümü ile) bulundu:

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 Lütfen yeni sürümü doğrulayın.
orlp

1
@Harry B düğmesini kullanarak ... 2 bayttan daha fazla tasarruf sağlayan yeni bir sürüm daha ekledim! 99 tekrara bile sığmadı, neredeyse 100'den fazla tekrar yaparken bayt harcamak zorunda kaldı.
orlp

1
44-byte versiyonu da onaylandı, izlemesi eğlenceli!
Harry,

1
Ahh, bu benim aradığım cevaptı, ama doğru sayıları bulamadım !! Çok iyi yapmışsın.
Lynn,

1
@Harry Bu benim bir kayıttır: youtube.com/watch?v=2-I1EEOlQYA
orlp

5

Python 2, 107 bayt

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

Çok etkileyici ve düşündüğümden çok daha kısa! Belki de tüm oyun boyunca sıkışıp kalmalıydım, haha. Ayrıca bunu test ettim ve seviyeyi tamamladığını doğrulayabilirim, eğer kaydedebilsem belki hepsini YouTube videoları olarak yüklerim!
Harry,

1

JavaScript (ES6), 59 karakter

_=>`start

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

Bu, orlp'in cevabı ile aynı metni çıkarır . Kendimden daha iyi bir yöntem bulmayı denedim, ancak bir input.txtdosyaya dönüştürdüğüm filmler her zaman düzgün bir şekilde oynatılmadı. Emülatörü cmd'den çalıştırmayı denediğimde, bir hata bildirdim "an unknown error occurred".


Şu anda benim tarafımda çalıştıramıyorum, ancak orlp'in yanıtıyla aynı input.txt dosyasını çıkarırsa, doğrulanmış olarak adlandırırız!
Harry,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.