ツールアシストコードゴルフ


39

TASゴルフ

SMB1 1-1終了

コードゴルフツイストを備えたツールアシストスピードランのスタイルで、この課題の目標は、選択したプログラミング言語で元のスーパーマリオブラザーズゲームのワールド1-1をできるだけ少ないバイトで完了することです。以下で説明する形式のゲーム内コント​​ローラー入力のみを使用します。プログラムは、このチャレンジ専用に作成されたこの形式の行のリストに出力する必要があります。stdout

up down left right start select A B

最初のフレームから開始して、各改行は特定のフレームのコントローラー1の入力を表します。フレームごとのボタンの順序は重要ではなく、任意の量の改行以外の空白で区切ることができます。ボタン名のすべてまたはすべて、または一部を行ごとに含めることができます。たとえば、Dパッドを3フレーム右に押してからAを押す単純なPythonプログラムは次のようになります。

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のバージョンは、元のUSA / Japan iNES ROM(md5sum 811b027eaf99c2def7b933c5208636de-USAバージョンは日本語バージョンとまったく同じであるため、どちらでも動作します。ROMは一般的にラベル付けされているSuper Mario Bros (JU) (PRG 0)か、類似しています)。

提出物をテストするには、プログラムを実行し、それらstdoutをinput.txtファイルにパイプして、mario.luaこのチャレンジ用に作成したこのLuaスクリプトを使用してFCEUXにロードします。

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です。プログラムは最終的に終了する必要がありますが、プログラムに時間制限はありません。

これは、FCEUXムービー(.fm2)ファイルをスクリプト用のinput.txtに変換するために作成した小さなBashワンライナーです。

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

参考のために、ここにWorld 1-1のフル解像度マップを示しますフル解像度の画像を新しいタブで開きます):(ソース:mariouniverse.comワールド1-1

注:一見、これは、指定されたinput.txtファイルでのコルモゴロフの複雑さの挑戦のように思えるかもしれません。ただし、実際には、チャレンジはそれよりも複雑です。なぜなら、(a)私が提供したinput.txtは明らかに最短ではなく、(b)この形式でSMBの最短のキー押下セットを作成しようとしたことがないためです。 。TASで知られている「可能な最小のボタン」は、ボタンを長時間保持できるため、この課題で望ましい出力に長さが追加されるため、異なります。


1
レベルのビデオを提供しましたが、ビデオに含まれる権利の数を数えることはできません。必要な動きを教えてください。

1
これをサンドボックスに投稿しましたか?覚えていない。

1
16のアップ投票があり、回答がないのは非常におかしいと思います:)

2
良い、challengjng、非自明な問題の兆候だ@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
@Harry新しいバージョンを確認してください。
orlp

1
@ハリー私はちょうど2つのバイトを節約する別の新しいバージョンを追加しました... Bボタンを使用しないで!99回のリピートにはほとんど適合せず、100回以上のリピートを行うために1バイトをほとんど無駄にしなければなりませんでした。
orlp

1
44バイトバージョンも確認されており、見ていて楽しい!
ハリー

1
ああ、これは私がしようとしていた答えの一種ですが、私は正しい数字を見つけることができませんでした!! とてもうまくできました。
リン

1
@ハリーこれは私の録音です:youtube.com/watch
v=

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のanswerと同じテキストが出力されます。私は自分でより良い方法を考え出そうとしましたが、input.txtファイルに変換した映画は常に適切に再生されませんでした。cmdからエミュレータを実行しようとするたびに、を示すエラーが表示されました"an unknown error occurred"


私の側では今すぐ実行できませんが、orlpの答えと同じinput.txtを出力する場合は、検証済みと呼びます!
ハリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.