Dungeon Crawler


40

Ingresso

  • Una matrice binaria rappresenta le pareti di un sotterraneo.M
  • La posizione del giocatore all'interno del sotterraneo.(X,y)
  • La direzione che il giocatore sta attualmente affrontando (0 = Nord, 1 = Est, 2 = Sud, 3 = Ovest)d

Produzione

Una rappresentazione pseudo-3D delle pareti che si trovano nel campo visivo del giocatore, come un'arte ASCII di caratteri.30×10

Di seguito sono riportati alcuni possibili frame di output, insieme alla mappa e alla bussola corrispondenti per aiutarti a capire come funziona (ma disegnare la mappa e la bussola non fa parte della sfida).

animazione

specificazione

Campo visivo

Il giocatore ha muri nel suo campo visivo, etichettati dalla alla . Di seguito sono riportate le posizioni delle pareti rispetto al giocatore (in giallo), in tutte le direzioni possibili.13UNM

campo visivo

Disegnare le pareti

Le pareti dovrebbero essere disegnate da a in questo preciso ordine, dato che qualsiasi parte disegnata in precedenza può essere sovrascritta da pareti più vicine. Ovviamente puoi implementarlo in modo diverso purché il risultato finale sia lo stesso.UNM

L'intera produzione è disegnato con 7 caratteri distinti: " ", "'", ".", "|", "-", "_"e ":".

Poiché dettagliare le forme delle pareti nel corpo di questa sfida la renderebbe troppo lunga, sono invece fornite nel seguente link TIO:

Provalo online!

I personaggi che non fanno parte di un determinato muro sono contrassegnati con a "?"in questi diagrammi. Devono essere trattati come caratteri 'trasparenti' che non vengono affatto disegnati. D'altra parte, tutti gli spazi all'interno di un muro sono "solidi" e devono sovrascrivere qualsiasi altro personaggio che potrebbe essere stato precedentemente disegnato lì.

Regole

Informazioni sull'input

  • Puoi prendere , , e in qualsiasi formato ragionevole.MXyd
  • È possibile utilizzare coordinate 0-indicizzate o 1-indicizzate.
  • È possibile utilizzare 4 valori distinti a scelta per le indicazioni.
  • La matrice è garantita per essere almeno .3×3
  • Si può presumere che ci saranno sempre muri circostanti sui bordi.
  • Il giocatore è garantito per essere posizionato su un quadrato vuoto.
  • L'input è garantito per essere valido.

Informazioni sull'output

  • Le pareti devono essere disegnate esattamente come descritto.
  • Tuttavia, anche il formato di output è flessibile: stringa singola, matrice di stringhe, matrice di caratteri, ecc.
  • Gli spazi bianchi iniziali e finali sono accettabili purché siano coerenti.

Questo è .

Casi test

Tutti i casi di test utilizzano la seguente matrice:

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

Uscite attese:

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

Sfida correlata:

Questa sfida del 2013 è strettamente correlata. Ma ha un diverso criterio vincente (code-challenge), una specifica molto più libera dell'output e richiede I / O interattivi.


Questo mi ha immediatamente ricordato 3D Monster Maze, anche se ovviamente utilizza grafica a blocchi.
Neil,

9
Le tue sfide sono così divertenti e ben scritte!
Oliver,

In attesa di una soluzione in Minecraft ...

Qualcun altro ricorda il salvaschermo di Windows? È stato un divertente "gioco" quando avevo 5 o 6 ...
Magia Octopus Urna

Risposte:


10

Pulito (con Snappy ), 800 785 670 644 byte

460 402 byte di codice + 360 stringa di 242 byte letterale
(scappato qui e su TIO perché non è valido UTF-8)

Puoi verificare la lunghezza del valore letterale qui.

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

Provalo online!

La compressione scattante in realtà funziona piuttosto bene in questo caso, nonostante sia focalizzata sulla velocità, perché ci sono così tante corse a carattere singolo nella stringa che viene compressa.

La stringa non compressa ( #sostituita con \nper chiarezza) è:

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

Questo codifica le versioni sul lato sinistro dei diversi componenti dello schermo con !anziché le nuove righe e ~invece di ?, che vengono quindi riempite a destra con un massimo ~di 30 caratteri prima di avere se stessi e i loro rovesciamenti di riga aggiunti a un elenco di ricerca.

Il resto del codice gestisce semplicemente la ricerca delle coordinate con i casi fuori limite ignorati.


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)

Provalo online!


4

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Ho un approccio un po 'noioso, temo; molta stampa di letterali di stringhe compresse. Spiegazione:

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

Riempi l'array con due 0s in più su ciascun lato.

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

Taglia una 7x7sottosezione dell'array centrata sulle coordinate indicate.

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

Ruota l'array nel modo appropriato per la direzione indicata.

B³⁰χ 

(nota spazio finale) Disegna una 30×10casella vuota in modo che l'output abbia sempre dimensioni coerenti.

F²«‖

Disegna ogni metà separatamente, riflettendo nel mezzo.

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

Prendi una serie di descrittori di pareti, dividi in blocchi di (stringa, coordinata y, coordinata x), filtra su quei blocchi che hanno un muro nella posizione pertinente nella metà pertinente della matrice e avvolgi i muri. La posizione viene calcolata estraendo 12 muri dall'array e indicizzandoli utilizzando l'indice del blocco poiché questo è più golfoso che individuare il muro direttamente utilizzando l'indice del blocco.

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

Vai alle coordinate del muro e stampalo. Si noti che il riflesso nega le coordinate X da [0, 30)a in (-30, 0]modo che su un passaggio la tela venga effettivamente spostata di 29 caratteri a sinistra.


1
@Arnauld In effetti, non sto sfruttando affatto la simmetria, dovrei essere in grado di tagliare un terzo tracciando ogni metà separatamente.
Neil,

1
+1 per un colpo di golf da 168 byte. Penso che sia il più grande singolo golf che abbia mai visto qui.
ElPedro,

2

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

Provalo online!

Accetta input come una matrice di valori di verità / falsità (la nota 0è verità in Ruby, ma nilè falsa).

Emette una matrice di caratteri.

Spiegazione

I blocchi vengono disegnati da davanti a dietro con la distanza ndecrescente e la posizione da un lato all'altro mscorrendo a -1,1,0sinistra, a destra, al centro. Il blocco centrale E nella riga più lontana viene effettivamente disegnato due volte perché è necessario controllare sia i blocchi A / B che i blocchi C / D. n,me dsono usati per modificare i valori xe yper cercare l'array a. Se xè fuori intervallo nilviene restituito per una cella fuori intervallo e non viene generato alcun errore, ma se yè fuori intervallo nilverrà restituito per la riga e Ruby genererà un errore di tipo quando tenta di cercare la cella. Per evitare ciò, l'array viene triplicato nella direzione verticale prima della ricerca. Se viene trovato un valore di verità viene disegnato un blocco.

L'output è creato in una matrice bdi matrici di 10 elementi che rappresentano le colonne dell'output e viene trasposto in 10 righe alla fine della funzione. Viene disegnata la faccia frontale completa di tutti i blocchi (che appaia o meno nella finestra), quindi è necessario spazio aggiuntivo nell'array per evitare errori fuori portata. L'intervallo di jvalori nella finestra è da -15a +14, questo viene spostato di 15 quando si salva sull'array per fornire un intervallo di 0a 29. Per ciascun blocco vengono calcolati tre valori: pe rispettivamente qper gli angoli sinistro e destro della parete anteriore e rper la parte posteriore della parete laterale. jviene ripetuto dal minimo al massimo di questi tre valori disegnando le colonne a turno.

Esistono 3 tipi di linee: orizzontale -o _verticale |o :diagonale con un " .'"motivo ripetuto . Dove p < j < qcolonne contenenti spazi chiusi -o _disegnati per formare la faccia anteriore. Dove si jtrova al di fuori di questo intervallo, le colonne che contengono spazio |o :sono disegnate coperte da simboli t=" .'"per formare i bordi e / o la faccia laterale. Questo è gestito da una variabile k=jdove jè positivo o k=-j-1dove jè negativo. Il numero di caratteri tra il limite superiore e inferiore è k/3*2. Per gestire correttamente i bordi esterni dei blocchi più lontani dove n=3, kdeve essere preso il modulo 9, ma ciò non deve essere fatto per valori inferiori din. kè quindi preso modulo 36/-~n, dove -~nvaluta n+1.

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

Bella risposta! Mi piace il modo in cui tutte le linee sono generate a livello di codice, comprese quelle diagonali.
Arnauld
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.