던전 크롤러


40

입력

  • 던전의 벽을 나타내는 이진 행렬
  • 던전 내 플레이어 의 위치(엑스,와이)
  • 플레이어가 현재 향하고 있는 방향 (0 = 북쪽, 1 = 동쪽, 2 = 남쪽, 3 = 서쪽)

산출

의 ASCII 아트로, 플레이어의 시야에있는 벽의 의사 3D 표현 문자.30×10

다음은 가능한지도 프레임과 해당지도 및 나침반과 함께지도를 끊는 데 도움이되는 몇 가지 가능한 출력 프레임입니다.

생기

사양

시야

플레이어는 자신의 시야에 에서 레이블이 지정된 벽이 있습니다 . 다음은 가능한 모든 방향에서 플레이어를 기준으로 한 벽의 위치 (노란색)입니다.13에이

시야

벽 그리기

벽은 이전에 그린 부분이 더 가까운 벽으로 덮어 쓰기 될 수 있으므로 에서 까지이 순서대로 그려 져야합니다. 최종 결과가 동일한 경우에는 물론 다르게 구현할 수 있습니다.에이

전체 출력은 7 개 문자 구별 그려진 : " ", "'", ".", "|", "-", "_"":".

이 챌린지의 바디에있는 벽의 모양을 자세히 설명하면 벽이 너무 길어지기 때문에 대신 다음 TIO 링크에 제공됩니다.

온라인으로 사용해보십시오!

주어진 벽에 속하지 않은 문자 "?"는이 다이어그램에서 로 표시됩니다 . 그것들은 전혀 그려지지 않은 '투명한'문자로 취급되어야합니다. 반면, 벽 내의 모든 공간은 '단단한'공간이며 이전에 그려진 다른 문자를 덮어 써야합니다.

규칙

입력 정보

  • 당신은 걸릴 수 있습니다 , , 및 합리적인 형식으로.엑스와이
  • 0 인덱스 또는 1 인덱스 좌표를 사용할 수 있습니다.
  • 길 찾기에 4 가지 값을 선택할 수 있습니다.
  • 행렬은 이상이어야 합니다.×
  • 가장자리에 항상 주변 벽이 있다고 가정 할 수 있습니다.
  • 플레이어는 빈 사각형에 있어야합니다.
  • 입력이 유효합니다.

출력에 대하여

  • 벽은 설명대로 정확하게 그려야합니다.
  • 그러나 단일 문자열, 문자열 배열, 문자 매트릭스 등의 출력 형식도 유연합니다.
  • 선행 및 후행 공백은 일관된 한 허용됩니다.

이것은 입니다.

테스트 사례

모든 테스트 사례는 다음 매트릭스를 사용합니다.

[ [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
  [ 1, 0, 1, 1, 1, 0, 0, 0, 0, 1 ],
  [ 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 ],
  [ 1, 0, 0, 0, 0, 0, 1, 1, 0, 1 ],
  [ 1, 0, 0, 1, 0, 0, 0, 1, 0, 1 ],
  [ 1, 0, 0, 1, 1, 0, 1, 1, 0, 1 ],
  [ 1, 1, 1, 1, 0, 0, 0, 0, 0, 1 ],
  [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
  [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] ]

다음 입력은 이 왼쪽 상단 모서리를 가리키는 0 인덱스 좌표 를 사용합니다.(0,0)

x=3, y=3, d=0
x=6, y=4, d=3
x=4, y=4, d=1
x=1, y=5, d=2
x=7, y=7, d=3
x=6, y=6, d=1
x=8, y=1, d=2
x=7, y=6, d=1

예상 출력 :

------------------------------    ------------------------------
 x=3, y=3, d=0:                    x=6, y=4, d=3:
------------------------------    ------------------------------
__                          __    '.                          .'
  |'.                    .'|        |                        |  
  |   '.--------------.'   |        |----.                   |  
  |    |              |    |        |    | '.--------.       |  
  |    |              |    |        |    |  |        |       |  
  |    |              |    |        |    |  |        |       |  
  |    |              |    |        |    | .'--------'       |  
  |   .'--------------'.   |        |----'                   |  
__|.'                    '.|__      |                        |  
                                  .'                          '.
------------------------------    ------------------------------
 x=4, y=4, d=1:                    x=1, y=5, d=2:
------------------------------    ------------------------------
                            .'    __ ________________________ .'
                           |        |                        |  
-------.              .----|        |                        |  
       | '.--------.' |    |        |                        |  
       |  |        |  |    |        |                        |  
       |  |        |  |    |        |                        |  
       | .'--------'. |    |        |                        |  
-------'              '----|        |                        |  
                           |      __|________________________|  
                            '.                                '.
------------------------------    ------------------------------
 x=7, y=7, d=3:                    x=6, y=6, d=1:
------------------------------    ------------------------------
'.                                '.                            
  |'.                               |'.                         
  |   '.                            |   '.                      
  |    | '.                 .-      |    |--.--------.--------.-
  |    |  |:               :|       |    |  |        |        | 
  |    |  |:               :|       |    |  |        |        | 
  |    | .'                 '-      |    |--'--------'--------'-
  |   .'                            |   .'                      
  |.'                               |.'                         
.'                                .'                            
------------------------------    ------------------------------
 x=8, y=1, d=2:                    x=7, y=6, d=1:
------------------------------    ------------------------------
'.                          __    '.                            
  |'.                    .'|        |                           
  |   '.              .'   |        |----.--------------.-------
  |    | '.        .' |    |        |    |              |       
  |    |  |:      :|  |    |        |    |              |       
  |    |  |:      :|  |    |        |    |              |       
  |    | .'        '. |    |        |    |              |       
  |   .'              '.   |        |----'--------------'-------
  |.'                    '.|__      |                           
.'                                .'                            

관련 도전 :

2013 년의이 과제 는 밀접한 관련이 있습니다. 그러나 출력 기준이 훨씬 느슨한 다른 승격 기준 (코드 도전)이 있으며 대화식 I / O가 필요합니다.


이것은 물론 블록 그래픽을 사용하지만 3D Monster Maze를 즉시 상기시켜줍니다.
Neil

9
당신의 도전은 너무 재미 있고 잘 작성되었습니다!
Oliver

Minecraft에서 솔루션을 기다리는 중 ...

다른 사람이 Windows 화면 보호기를 기억합니까? 내가 5 살이나 6 살 때 정말 재미있는 "게임"이었어.
Magic Octopus Urn

답변:


10

청소 (와 뭐 이따위 ), 800 785 670 644 바이트

460 402 바이트의 코드 + 360 242 바이트 문자열 리터럴
(UTF-8이 유효하지 않으므로 여기 및 TIO에서 이스케이프 처리됨)

여기 에서 리터럴의 길이를 확인할 수 있습니다 .

import StdEnv,Data.List,Data.Maybe,Codec.Compression.Snappy,Text
@a b|b<'~'=b=a
$m x y d=map(@' ')(foldl(\a b=[@u v\\u<-a&v<-b])['~~'..][join['
']k\\Just(Just 1)<-[mapMaybe(\e=e!?(x+[u,v,~u,~v]!!d))(m!?(y+[~v,u,v,~u]!!d))\\u<-[-2,2,-1,1,0,-1,1,0,-1,1,0,-1,1]&v<-[3,3,3,3,3,2,2,2,1,1,1,0,0]]&k<-nub[q\\w<-split"#"(snappy_uncompress"\211\6\44\41\41\41\55\56\40\41\40\174\72\5\4\60\55\47\40\41\41\41\43\41\41\41\176\56\55\r\1\24\56\40\41\176\174\40\r\1\4\174\72\72\r\0\0\47\r\46\35\72\25\1\31\103\0\41\25\24\35\113\176\25\0\31\133\11\224\r\152\20\56\40\40\40\41\21\217\10\40\47\56\31\14\4\40\174\126\14\0\4\56\47\21\74\0\47\1\74\1\340\r\220\25\242\11\1\25\250\25\360\11\1\25\253\376\30\0\21\30\25\333\11\1\24\47\41\41\43\137\137\11\154\20\41\40\40\174\47\r\344\1\157\5\341\1\11\5\336\172\11\0\34\56\47\41\137\137\174\56\47\1\347\20\43\176\176\40\137\132\1\0\4\40\41\75\211\76\1\0\1\356\5\150\116\1\0\376\35\0\376\35\0\126\35\0\132\347\0\20\137\174\41\43\47\101\337\51\74\41\133\122\4\0\10\56\47\40"),q<-let l=[[c\\c<-:rpad s 30'~']\\s<-split"!"w]in[l,map reverse l]]])

온라인으로 사용해보십시오!

Snappy 압축은 압축되는 문자열에 너무 많은 단일 문자 실행이 있기 때문에 속도 중심에도 불구하고 실제로이 경우에 꽤 잘 수행됩니다.

압축되지 않은 문자열 ( 명확성 #\n위해 대체 됨 )은 다음과 같습니다.

!!!-. ! |:! |:!-' !!!
!!!~.--------. !~|        |:!~|        |:!~'--------' !!!
!!!~~~~~~~~~~.--------.!~~~~~~~~~~|        |!~~~~~~~~~~|        |!~~~~~~~~~~'--------'!!!
!!-------.   !       | '.!       |  |!       |  |!       | .'!-------'   !!
!!~~~~~~~.--------------.!~~~~~~~|              |!~~~~~~~|              |!~~~~~~~|              |!~~~~~~~|              |!~~~~~~~'--------------'!!
__      !  |'.   !  |   '.!  |    |!  |    |!  |    |!  |    |!  |   .'!__|.'   !
~~ ________________________ !~~|                        |!~~|                        |!~~|                        |!~~|                        |!~~|                        |!~~|                        |!~~|                        |!~~|________________________|!
'. !  |!  |!  |!  |!  |!  |!  |!  |!.' 

이렇게하면 다른 화면 구성 요소의 왼쪽 버전을 줄 !바꾸기 ~대신 및 대신에 인코딩합니다. ?그 다음에 ~는 자신과 줄 반전이 조회 목록에 추가되기 전에 30 자로 채워집니다 .

나머지 코드는 범위를 벗어난 경우를 무시하고 좌표 조회를 처리합니다.


5

파이썬 2 , 864 854 848 826 810 바이트

L=[zip(*[iter(w)]*30)for w in zip(*[iter("eJzdllESgyAMRL+5Rf7yRQ7AZbhIDl9BwTqzSVtHrbKffR0Mm13HEM5SFHIoadpNI3snDyaS6NCknhU+JfZOvq8kLoIBU1oEI+RTbiePGzBa3QM0rf78TGl17+CZr5ZrUXBN+ECfY1GvGKEqtDsSI4s6xTn5jgqyqNcTTnUjTQO2FAEqTC0ngCrtpywenX5le6or1SsGi9ZLBKt0HuXtVEeUNGdzG6EsRNmo2EzLxuBbqFH8njmfwnqGcl+VY+s5+5ezSYXVel4dxaRK/6F15SatK1frvm//y4aoT4Ckj6XWfY2cbvz2fLSCPiiVvR+3ZuerzDwPSqeSvgAP9woa".decode('base64').decode('zip'))]*300)]
E=enumerate
def f(m,x,y,d):
 D=eval(`[[' ']*30]*10`);w,h=len(m[0]),len(m);a=[m,zip(*m)[::-1]][d%2];x,y=[x,y,w+~x,h+~y,y,w+~x,h+~y,x][d::4];X=sum([[0]*(x<2)+list(l)[x-2+(x<2):x+3]for l in[l*2for l in[a,[l[::-1]for l in a[::-1]]][d/2]*2][y:y+4]],[])
 for d,w in zip(L,'sropqmklhfgca'):
  for j,l in E(d):
   for i,q in E(l):
    if q*X[ord(w)%32]>=' ':D[j][i]=q
 for l in D:print''.join(l)

온라인으로 사용해보십시오!


4

, 500 332 바이트

F⁴≔⮌E§θ⁰⁺00⭆θ§μλθ≔E✂θ⊖ζ⁺⁶ζ¹✂ι⊖η⁺⁶η¹θFε≔⮌E§θ⁰⭆θ§μλθB³⁰χ F²«‖FΦ⪪⟦“ |0⟧P+N?⟧‹G”³¦⁰”{➙d⊟EX⍘k↧D({Vt⍘gRd◨ⅉ^δ#T;”³¦¹“ ¶↖+9G₂pF^c1e⌈¬;”³χω⁰χ”{➙∧⊟∧◨ηü∧↖z↨⁸\G'λI∧¡∕⪫θJoΣ³⊖I⊟ζ⊙”²¦⁰”{➙∧⊟∧◨ηü∨§·◧﹪d‹⟲ OzºκFⅉRï⎇”²¦⁷ω⁰χ”{➙∧⊟≔⊘⬤|↔3Zθ✂≔÷t⍘ε✂↨≔⧴×ld≕≡⌕m⟧6ψ=Z”⁰¦⁰”}∧80KυgCAêJm⟦↘/§‖Ck⮌C₂¡μ↗W”⁰¦²ω⁰χ”{⊟∨·◧¤∨¶⧴⬤2GL▷⁸ê5Gψ”⁰¦⁰⟧³I§⭆θ⭆³§μ⎇ι⊕ξ⁻⁵ξλ«J⁻⊟κײ⁹¬ι⊟κ⊟κ

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 다소 지루한 접근 방식은 두렵습니다. 압축 문자열 리터럴을 많이 인쇄합니다. 설명:

F⁴≔⮌E§θ⁰⁺00⭆θ§μλθ

0각 측면에 2 개의 여분의을 사용하여 어레이를 채 웁니다 .

≔E✂θ⊖ζ⁺⁶ζ¹✂ι⊖η⁺⁶η¹θ

7x7주어진 좌표를 중심으로 배열 의 하위 섹션을 슬라이스합니다 .

Fε≔⮌E§θ⁰⭆θ§μλθ

주어진 방향에 따라 배열을 회전시킵니다.

B³⁰χ 

(후미 공백 참고) 30×10출력이 항상 일정한 크기가되도록 빈 상자를 그립니다.

F²«‖

사이에 반영하여 각 절반을 개별적으로 그립니다.

FΦ⪪⟦...⟧³I§⭆θ⭆³§μ⎇ι⁻⁵ξ⊕ξλ«

벽 설명자 배열을 가져 와서 (문자열, y 좌표, x 좌표) 청크로 분할하고, 배열의 관련 절반에서 관련 위치에 벽이있는 청크를 필터링하고 벽을 반복합니다. 배열에서 12 개의 벽을 추출하고 청크 인덱스를 사용하여 벽을 직접 찾는 것보다 골퍼 인덱스를 사용하여 벽을 인덱싱하여 위치를 계산합니다.

J⁻⊟κײ⁹¬ι⊟κ⊟κ

벽의 좌표로 이동하여 인쇄하십시오. 을 Negate에게의 X 좌표 반영하는 것을 주 [0, 30)(-30, 0]하나에 그 캔버스를 통과 할 수 있도록하는 것이 효율적 왼쪽에 29 개 문자를 이동한다.


1
@Arnauld 사실, 나는 대칭의 이점을 전혀 사용하지 않으며, 각각 반을 따로 그려서 1/3을 줄일 수 있어야합니다.
Neil

1
168 바이트 골프 스트로크의 경우 +1 이것이 내가 본 것 중 가장 큰 싱글 골프라고 생각합니다.
ElPedro

2

루비 , 412 391 385 383 바이트

->a,x,y,d{b=Array.new(97){[" "]*10}
e=[-1,0,1,0]
14.times{|i|m=-i%3-1
w=[31,25,15,9][n=i>2?4-i/3:(m*=2;3)]
(a*3)[y+n*e[d]+m*c=e[d-3]][x+n*c-m*e[d]]&&[p=w*(m*2-1)/2,r=[12,7,4,3][n]*m*m.abs+m/3].min.upto([q=w*(m*2+1)/2,r].max){|j|t=" .'"*9
b[j+15]=(p<j&&j<q ?%w{-%2s- -%4s- _%7s_}[-n]%"":t[k=(j^j>>9)%(36/-~n)]+"   :|  |    |"[k%13]*(k/3*2)+t[-k]).center(10).chars}}
b[0,30].transpose}

온라인으로 사용해보십시오!

입력을 참 / 거짓 값의 배열로받습니다 ( 0루비에서는 nil참 이지만 거짓입니다).

문자 배열을 출력합니다.

설명

블록은 거리가 n감소하고 왼쪽, 오른쪽, 중간을 m순환하는 -1,1,0좌우 위치 로 앞뒤로 그려집니다 . 가장 먼 행의 중간 블록 E는 블록 A / B와 블록 C / D를 모두 확인해야하기 때문에 실제로 두 번 그려집니다. n,m및 배열을 검색하기 d위해 xy값을 수정하는 데 사용됩니다 a. 경우 x범위를 벗어난 nil범위 셀의 아웃 반환하고 오류가 발생하지 않지만 경우 y범위를 벗어 nil행 반환되며,이 셀을 검색 할 때 루비 유형의 오류가 발생합니다. 이를 피하기 위해 검색 전에 배열이 세로 방향으로 3 배가됩니다. 진실한 값을 찾으면 블록이 그려집니다.

출력은 출력 b의 열을 나타내는 10 요소 배열 의 배열 로 빌드되며 함수 끝에서 10 개의 행으로 바뀝니다. 모든 블록의 전면이 뷰포트에 표시되는지 여부에 관계없이 그려 지므로 범위를 벗어나는 오류를 피하기 위해 어레이에 추가 공간이 필요합니다. 범위 j뷰포트의 값은 인 -15+14의 범위 수득 배열에 저장하는 경우는 (15)에 의해 상쇄되어, 0행을 29. 각 블록에 그려진 세 가지 값이 계산된다 : pq는 각각 전방 벽의 좌우 모서리 용 및 r측벽 용 백. j열을 차례로 그리는이 세 값의 최소값에서 최대 값까지 반복됩니다.

가로 : 라인의 3 개 가지 유형 -또는 _수직 |또는 :반복적으로, 대각선 " .'"패턴. 여기서 p < j < q덮인 공간을 포함하는 열 -또는 _표면을 형성하도록 당겨진다. j이 범위를 벗어난 곳 에서는 공간을 포함 |하거나 열이 :기호로 표시 t=" .'"되어 모서리 및 / 또는 측면을 형성합니다. 이는 변수가 관리 k=j여기서 j양수 또는 k=-j-1여기서 j마이너스이다. 상단과 하단 대문자 사이의 문자 수는 k/3*2입니다. 올바르게 먼 블록의 바깥 쪽 가장자리 처리하기 위해 n=3, k모듈 9주의해야한다, 그러나이 작은 값을 수행하지 않아야n. k그러므로 촬영 모듈이며 36/-~n, -~n평가하여에이 n+1.

Ungolfed 코드

->a,x,y,d{
  b=Array.new(97){[" "]*10}                                        #Set up array for output, allow space for plotting outside viewport
  e=[-1,0,1,0]                                                     #Direction offsets from player position
  14.times{|i|                                                     #Iterate through all blocks including block E twice 
    m=-i%3-1                                                       #Cycle -1,1,0 = left, right, centre
    n=i>2?4-i/3:(m*=2;3)                                           #Distance n=4-i/3. But if i/3==0 n=3 and double m for blocks A,B 
    w=[31,25,15,9][n]                                              #Width of front face of block
    r=[12,7,4,3][n]*m*m.abs+m/3                                    #Value of j for back edge of block. m/3 offsets by -1 when m negative 
    (a*3)[y+n*e[d]+m*c=e[d-3]][x+n*c-m*e[d]]&&(                    #If a block is present at the location then
      [p=w*(m*2-1)/2,r].min.upto([q=w*(m*2+1)/2,r].max){|j|        #Calculate left and right edges of front of block p,q and iterate
        t=" .'"*9                                                  #t=character constant for diagonal lines 
        k=(j^j>>9)%(36/-~n)                                        #k=j for positive j=distance from centre. For negative j, k=-1-j by XOR with j>>9=-1. If n=3 take modulo 9 for correct output of outer side of block. 
        b[j+15]=(p<j&&j<q ?%w{-%2s- -%4s- _%7s_}[-n]%"":           #If j between p&q, draw horizontal lines separated by 2,4 or 7 spaces depending on value of n
        t[k]+"   :|  |    |"[k%13]*(k/3*2)+t[-k]).center(10).chars #else draw space or vertical line capped by diagonal markers
      }
    )
  }
b[0,30].transpose}                                                 #Truncate values outside viewport, transpose, and return value.

좋은 대답입니다! 대각선을 포함하여 모든 선이 프로그래밍 방식으로 생성되는 방식이 마음에 듭니다.
Arnauld
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.