도구 보조 코드 골프


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.