도구 보조 코드 골프


39

TAS 골프

SMB1 1-1 결말

코드 골프 트위스트 가 포함 된 툴 지원 스피드 런 스타일 에서이 과제의 목표는 선택한 프로그래밍 언어로 NES를위한 오리지널 Super Mario Bros 게임 의 세계 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 끝에서 깃발에 도달하는 것으로 정의합니다. 이 예제의 파이썬 제출에 대한 점수 (성공하지 않은 경우)는 44 바이트 또는 원래 길이의 Python 프로그램입니다.

현재 가장 빠른 TAS 기반으로 생성 한 작업 입력 파일의 예는 다음 Github Gist를 참조하십시오. https://gist.github.com/anonymous/6f1a73cbff3cd46c9e1cf8d5c2ff58e1 이 파일은 전체 게임을 완료합니다.

서브 프레임 입력 을 입력 할 방법이 없습니다 . Player 2의 컨트롤러에는 입력을 입력 할 수있는 방법이 없지만 레벨이나 게임을 완료하는 데 필요하거나 유용하지 않아야합니다.

사용되는 SMB의 버전은 원래 USA / Japan iNES ROM (md5sum 811b027eaf99c2def7b933c5208636de)입니다. USA 버전은 일본어 버전과 동일하므로 작동합니다. ROM은 일반적으로 레이블이 붙어 Super Mario Bros (JU) (PRG 0)있거나 비슷합니다.

제출물을 테스트하기 위해 프로그램을 실행하고 stdoutinput.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

참고로, 다음은 세계 1-1의 고해상도지도입니다 (전체 해상도를 위해 새 탭에서 이미지 열기) : (source : mariouniverse.com )세계 1-1

참고 : 언뜻보기에 이것은 주어진 input.txt 파일에서 Kolmogorov 복잡성 문제처럼 보일 수 있습니다. 그러나 실제로 문제는 (a) 내가 제공 한 input.txt가 가장 짧지 않고 (b)이 형식으로 SMB에 대해 가장 짧은 키 누르기를 만들려는 시도가 없었기 때문에 그 문제보다 더 복잡합니다. . TAS로 알려진 '가장 작은 버튼'은 버튼을 오랫동안 누르고 있기 때문에이 도전에서 원하는 출력에 길이를 더할 수 있기 때문에 다릅니다.


1
레벨의 동영상을 제공했지만 동영상에 얼마나 많은 권한이 있는지 계산할 수 없습니다. 필요한 움직임을 알려주시겠습니까?

1
이것을 샌드 박스에 게시 했습니까? 기억이 안나요

1
나는 당신이 16 개의

2
@JackBates 그것은 좋은, challengjng, 사소한 질문의 표시입니다
FlipTack

1
내가 생각하는 전체 해상도지도 이미지에 404
Liam

답변:


20

파이썬 2, 69 48 46 44 바이트

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

유튜브에서 실제로 그것을보십시오!

이 해키 스크립트로 (수정 된 버전의) 자동 발견 :

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
@Harry 방금 B 버튼을 사용하지 않고 2 바이트를 더 절약하는 새로운 버전을 추가했습니다! 99 반복에 거의 맞지 않으며 거의 ​​100 + 반복을 할 때 바이트를 낭비해야했습니다.
orlp

1
44 바이트 버전도 확인하고 재미있게 보았습니다!
Harry

1
아아, 이것은 내가 원하는 종류의 대답이지만 올바른 숫자를 찾을 수 없었습니다!! 아주 잘 했어요
Lynn

1
@Harry 이것은 내 기록입니다 : youtube.com/watch?v=2-I1EEOlQYA
orlp

5

파이썬 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 비디오로 업로드 할 것입니다!
Harry

1

자바 스크립트 (ES6), 59 자

_=>`start

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

그러면 orlp의 답변 과 동일한 텍스트가 출력 됩니다. 더 나은 방법을 스스로 시도했지만 input.txt파일 로 변환 한 영화 가 항상 제대로 재생되지는 않았습니다. cmd에서 에뮬레이터를 실행하려고 할 때마다 오류가 발생했습니다 "an unknown error occurred".


지금 당장 실행할 수는 없지만 orlp의 답변과 동일한 input.txt를 출력하면 확인이라고합니다!
Harry
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.