Crawler Penjara Bawah Tanah

40

Memasukkan

  • Matriks biner M mewakili dinding sebuah ruang bawah tanah.
  • Posisi (x,y) pemain di dalam ruang bawah tanah.
  • Arah d yang sedang dihadapi pemain (0 = Utara, 1 = Timur, 2 = Selatan, 3 = Barat)

Keluaran

Representasi pseudo-3D dari dinding yang ada di bidang pandangan pemain, sebagai seni ASCII 30×10 karakter.

Berikut adalah beberapa kerangka keluaran yang memungkinkan, bersama dengan peta dan kompas yang sesuai untuk membantu memahami (tetapi menggambar peta dan kompas bukan bagian dari tantangan).

animasi

Spesifikasi

Bidang pandang

Pemain memiliki 13 dinding di bidang pandangnya, berlabel dari A ke M . Di bawah ini adalah posisi dinding relatif terhadap pemain (berwarna kuning), di semua arah yang mungkin.

bidang pandang

Menggambar dinding

Dinding seharusnya ditarik dari A ke M dalam urutan yang tepat ini, mengingat bahwa setiap bagian yang diambil sebelumnya dapat ditimpa oleh dinding yang lebih dekat. Anda tentu saja dapat menerapkannya secara berbeda selama hasil akhirnya sama.

Seluruh output digambar dengan 7 karakter yang berbeda: " ", "'", ".", "|", "-", "_"dan ":".

Karena merinci bentuk dinding di tubuh tantangan ini akan membuatnya terlalu panjang, mereka diberikan dalam tautan TIO berikut:

Cobalah online!

Karakter yang bukan bagian dari dinding yang diberikan ditandai dengan "?"dalam diagram ini. Mereka harus diperlakukan sebagai karakter 'transparan' yang tidak digambar sama sekali. Di sisi lain, semua ruang di dalam dinding 'padat' dan harus menimpa karakter lain yang mungkin telah ditarik sebelumnya.

Aturan

Tentang input

  • Mxyd
  • Anda dapat menggunakan koordinat 0-diindeks atau 1-diindeks.
  • Anda dapat menggunakan 4 nilai berbeda dari pilihan Anda untuk arahan.
  • 3×3
  • Anda mungkin berasumsi bahwa akan selalu ada dinding di sekelilingnya.
  • Pemain dijamin berada di kotak kosong.
  • Masukan dijamin valid.

Tentang output

  • Dinding harus digambar persis seperti yang dijelaskan.
  • Namun, format output juga fleksibel: string tunggal, array string, matriks karakter, dll.
  • Memimpin dan mengikuti spasi dapat diterima asalkan konsisten.

Ini adalah .

Uji kasus

Semua uji menggunakan matriks berikut:

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

Output yang diharapkan:

------------------------------    ------------------------------
 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:
------------------------------    ------------------------------
'.                          __    '.                            
  |'.                    .'|        |                           
  |   '.              .'   |        |----.--------------.-------
  |    | '.        .' |    |        |    |              |       
  |    |  |:      :|  |    |        |    |              |       
  |    |  |:      :|  |    |        |    |              |       
  |    | .'        '. |    |        |    |              |       
  |   .'              '.   |        |----'--------------'-------
  |.'                    '.|__      |                           
.'                                .'                            

Tantangan terkait:

Tantangan dari tahun 2013 ini terkait erat. Tetapi memiliki kriteria kemenangan yang berbeda (code-challenge), spesifikasi keluaran yang jauh lebih longgar, dan membutuhkan I / O interaktif.

Arnauld
sumber
Ini langsung mengingatkan saya pada 3D Monster Maze, walaupun itu tentu saja menggunakan grafik blok.
Neil
9
Tantangan Anda sangat menyenangkan dan ditulis dengan baik!
Oliver
Menunggu solusi di Minecraft ...
Apakah ada orang lain yang ingat screen saver windows? Sungguh "permainan" yang menyenangkan ketika saya berusia 5 atau 6 ...
Magic Octopus Mm

Jawaban:

10

Bersihkan (dengan Snappy ), 800 785 670 644 byte

460 402 byte kode + 360 242-byte string literal
(lolos di sini dan di TIO karena tidak valid UTF-8)

Anda dapat memverifikasi panjang literal di sini.

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

Cobalah online!

Kompresi tajam sebenarnya cukup baik dalam hal ini, meskipun berfokus pada kecepatan, karena ada begitu banyak karakter tunggal yang dijalankan dalam string yang dikompresi.

String yang tidak dikompresi (dengan #diganti dengan \nuntuk kejelasan) adalah:

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

Ini mengkodekan versi sisi kiri dari komponen layar yang berbeda dengan !bukannya baris baru, dan ~bukannya ?, yang kemudian diisi dengan ~hingga 30 karakter sebelum memiliki mereka sendiri dan pembalikan garis mereka ditambahkan ke daftar pencarian.

Sisa kode hanya menangani pencarian terkoordinasi dengan kasus di luar batas yang diabaikan.

Suram
sumber
5

Python 2 , 864 854 848 826 810 byte

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)

Cobalah online!

TFeld
sumber
4

Arang , 500 332 byte

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⁻⊟κײ⁹¬ι⊟κ⊟κ

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Pendekatan yang agak membosankan, saya khawatir; banyak pencetakan literal string terkompresi. Penjelasan:

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

Pad array dengan dua 0s ekstra di setiap sisi.

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

Iris 7x7subbagian dari array yang berpusat pada koordinat yang diberikan.

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

Putar array yang sesuai untuk arah yang diberikan.

B³⁰χ 

(note trailing space) Gambar 30×10kotak kosong sehingga output selalu ukuran yang konsisten.

F²«‖

Gambarlah masing-masing secara terpisah, yang mencerminkan di antaranya.

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

Ambil array deskriptor dinding, pisahkan menjadi beberapa bagian (string, koordinat y, koordinat x), filter pada potongan yang memiliki dinding pada posisi yang relevan di bagian array yang relevan, dan lilitkan melewati dinding. Posisi dihitung dengan mengekstraksi 12 dinding dari array dan mengindeksnya menggunakan chunk index karena ini lebih golf daripada mencari dinding secara langsung menggunakan chunk index.

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

Lompat ke koordinat dinding dan cetak. Perhatikan bahwa mencerminkan meniadakan X-koordinat dari [0, 30)ke (-30, 0]sehingga pada satu lulus kanvas secara efektif bergeser 29 karakter ke kiri.

Neil
sumber
1
@Arnauld Memang, saya tidak mengambil keuntungan dari simetri sama sekali, saya harus dapat memotong yang ketiga dengan menggambar masing-masing setengah secara terpisah.
Neil
1
+1 untuk pukulan golf 168 byte. Saya pikir itu adalah golf tunggal terbesar yang pernah saya lihat di sini.
ElPedro
2

Ruby , 412 391 385 383 byte

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

Cobalah online!

Mengambil input sebagai array nilai kebenaran / kepalsuan (catatan 0itu benar di Ruby, tetapi nilsalah.)

Menghasilkan array karakter.

Penjelasan

Blok ditarik dari depan ke belakang dengan jarak yang nberkurang dan posisi sisi ke sisi mberputar melalui -1,1,0kiri, kanan, tengah. Blok tengah E pada baris terjauh sebenarnya digambar dua kali karena kita perlu memeriksa kedua blok A / B dan blok C / D. n,mdan ddigunakan untuk memodifikasi nilai x- ynilai dan untuk array pencarian a. Jika di xluar rentang nildikembalikan untuk sel di luar rentang dan tidak ada kesalahan yang dilemparkan, tetapi jika yberada di luar rentang nilakan dikembalikan untuk baris dan Ruby akan melempar kesalahan ketik ketika mencoba mencari sel. Untuk menghindari hal ini, array rangkap tiga dalam arah vertikal sebelum pencarian. Jika nilai kebenaran ditemukan, sebuah blok digambar.

Output dibangun dalam array array b10 elemen yang mewakili kolom output, dan ditransformasikan ke dalam 10 baris di akhir fungsi. Wajah depan penuh dari semua blok digambar (apakah itu muncul di viewport atau tidak) sehingga diperlukan ruang tambahan dalam array untuk menghindari kesalahan di luar jangkauan. Kisaran jnilai dalam viewport adalah dari -15ke +14, ini diimbangi oleh 15 saat menyimpan ke array untuk memberikan kisaran 0ke 29. Untuk setiap blok digambar tiga nilai dihitung: pdan qmasing-masing runtuk sudut kiri dan kanan dinding depan, dan untuk bagian belakang dinding samping. jdiulang dari minimum ke maksimum dari tiga nilai ini menggambar kolom pada gilirannya.

Ada 3 jenis garis: horizontal -atau _, vertikal |atau :, dan diagonal dengan " .'"pola berulang . Di mana p < j < qkolom yang berisi spasi ditutup dengan -atau _ditarik untuk membentuk wajah depan. Di mana jberada di luar rentang ini, kolom yang berisi ruang, |atau :digambar dengan simbol dari t=" .'"untuk membentuk tepi dan / atau sisi muka. Ini dikelola oleh variabel k=jmana jpositif atau k=-j-1di mana jnegatif. Jumlah karakter antara topi atas dan bawah adalah k/3*2. Untuk benar menangani tepi luar blok terjauh di mana n=3, kharus diambil modulo 9, tetapi ini tidak boleh dilakukan untuk nilai yang lebih kecil darin. kOleh karena itu diambil modulo 36/-~n, di mana -~ndievaluasi untuk n+1.

Kode tidak dikunci

->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.
Level River St
sumber
Jawaban bagus! Saya suka cara semua garis dihasilkan secara pemrograman, termasuk yang diagonal.
Arnauld