ダンジョンクローラー


40

入力

  • ダンジョンの壁を表すバイナリマトリックスM
  • ダンジョン内のプレイヤーの位置(x,y)
  • プレイヤーが現在向いている方向d(0 =北、1 =東、2 =南、3 =西)

出力

プレイヤーの視野内にある壁の擬似3D表現30×10文字のASCIIアートとして。

以下は、いくつかの可能な出力フレームと、それに対応するための対応するマップとコンパスです(ただし、マップとコンパスの描画は課題の一部ではありません)。

アニメーション

仕様

視野

プレーヤーには、AからMのラベルが付いた13壁が視野にあります。以下は、プレーヤーに対する壁の位置(黄色)であり、考えられるすべての方向です。AM

視野

壁を描く

以前に描画された部分が近い壁によって上書きされる可能性があるため、壁はこの正確な順序でAからMに描画されることになっています。もちろん、最終結果が同じである限り、異なる方法で実装できます。

:全体の出力は、7つの異なる文字で描かれている" ""'"".""|""-""_"および":"

この課題の本体の壁の形状を詳細に説明すると長すぎるため、代わりに次のTIOリンクで提供されます。

オンラインでお試しください!

特定の壁の一部ではないキャラクターは"?"、これらの図ではa でマークされています。それらは、まったく描画されない「透明な」文字として扱われなければなりません。一方、壁内のすべてのスペースは「ソリッド」であり、以前にそこに描かれた可能性のある他の文字を上書きする必要があります。

ルール

入力について

  • Mxyd
  • 0インデックスまたは1インデックスの座標を使用できます。
  • 方向には、選択した4つの異なる値を使用できます。
  • 3×3
  • あなたは常に縁に周囲の壁があると仮定するかもしれません。
  • プレーヤーは空の広場にいることが保証されています。
  • 入力は有効であることが保証されています。

出力について

  • 説明したとおりに壁を描く必要があります。
  • ただし、出力形式も柔軟です。単一の文字列、文字列の配列、文字のマトリックスなどです。
  • 前後の空白は、一貫している限り許容されます。

これはです。

テストケース

すべてのテストケースは、次のマトリックスを使用しています。

[ [ 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)

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を即座に思い出させましたが、もちろんブロックグラフィックスを使用しています。
ニール

9
あなたの課題はとても楽しく、よく書かれています!
オリバー

... Minecraftの溶液を待っている

Windowsスクリーンセーバーを覚えている人はいますか?私が5歳か6歳のときはとても楽しい「ゲーム」だった...
マジックタコop

回答:


10

CleanSnappyを使用)、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

Pythonの2864の 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つの余分なsを追加します。

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

スライスa 7x7指定された座標を中心に配列のサブセクションをます。

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

与えられた方向に応じて配列を回転させます。

B³⁰χ 

(末尾のスペースに注意してください)空を描画します 30×10出力が常に一定のサイズになるようにボックスを。

F²«‖

間を反映して、各半分を個別に描画します。

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

壁記述子の配列を取得し、(文字列、y座標、x座標)のチャンクに分割し、配列の関連する半分の関連する位置に壁があるチャンクをフィルター処理し、壁をループします。配列から12の壁を抽出し、チャンクインデックスを使用して壁にインデックスを付けることで位置が計算されます。これは、チャンクインデックスを使用して壁を直接見つけるよりもゴルファーです。

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

壁の座標にジャンプして印刷します。リフレクションは[0, 30)to からX座標を無効にする(-30, 0]ので、1回のパスでキャンバスは29文字左に効果的にシフトされることに注意してください。


1
@Arnauld確かに、私は対称性の利点をまったく利用していません。各半分を個別に描画することで3分の1をカットできるはずです。
ニール

1
168バイトのゴルフストロークの場合は+1。私がここで見た最大のシングルゴルフだと思います。
エルペドロ

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}

オンラインでお試しください!

入力を真実/偽の値の配列として受け取ります(0Rubyでは注意は真実nilですが、偽です)。

文字の配列を出力します。

説明

ブロックは、距離が短くなるように前後に描画され、左右のn位置m-1,1,0左、右、中央を循環します。ブロックA / BとブロックC / Dの両方をチェックする必要があるため、最も遠い行の中央のブロックEが実際に2回描画されます。n,mおよびdを使用してxy配列を検索するためにと値を変更しますa。範囲外のセルに対してx範囲外の場合はnilエラーがスローされませんがy、範囲外の場合はnil行に対して返され、セルを検索しようとするとRubyはタイプエラーをスローします。これを回避するために、検索の前に配列が垂直方向に3回複製されます。真実の値が見つかった場合、ブロックが描かれます。

出力はb、出力の列を表す10要素配列の配列で構築され、関数の最後で10行に転置されます。すべてのブロックの前面全体が(ビューポートに表示されるかどうかに関係なく)描画されるため、範囲外のエラーを回避するには、配列に追加のスペースが必要です。範囲jビューポート内の値からなる-15まで+14の範囲与えるためにアレイに保存するとき、これは15だけオフセットされ、0への29。ブロック毎に描画された3つの値が計算されるpq、それぞれ前壁の左右の角のため、およびr側壁の背面のため。jこれら3つの値の最小値から最大値まで順に反復して、列を描画します。

水平:ラインの3種類があり-、又は_、垂直|又は:反復と、斜め" .'"パターン。前面を形成するために、またはでp < j < qキャップされたスペースを含む列が描画される場所。この範囲外の場所、スペースを含む列、または記号でキャップされて描画され、エッジおよび/または側面を形成します。これは、変数where が正またはwhere が負で管理されます。上部と下部のキャップの間の文字数はです。最も遠いブロックの外側のエッジを正しく処理するために、をモジュロ9でとる必要がありますが、-_j|:t=" .'"k=jjk=-j-1jk/3*2n=3knkしたがって、モジュロはに評価されます。36/-~n、はを-~nn+1

未ゴルフコード

->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.

いい答えだ!対角線も含め、すべての行がプログラムで生成される方法が気に入っています。
アルノー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.