Donjon Crawler

40

Contribution

  • Une matrice binaire représentant les murs d'un cachot.M
  • La position du joueur dans le donjon.(X,y)
  • La direction laquelle le joueur est actuellement confronté (0 = Nord, 1 = Est, 2 = Sud, 3 = Ouest)

Sortie

Une représentation pseudo-3D des murs qui se trouvent dans le champ de vision du lecteur, sous forme d'art ASCII de caractères.30×dix

Vous trouverez ci-dessous plusieurs cadres de sortie possibles, ainsi que la carte et la boussole correspondantes pour vous aider à bien les comprendre (mais dessiner la carte et la boussole ne fait pas partie du défi).

animation

spécification

Champ de vision

Le joueur a murs dans son champ de vision, étiquetés de à . Ci-dessous sont les positions des murs par rapport au joueur (en jaune), dans toutes les directions possibles.13UNEM

champ de vision

Dessiner les murs

Les murs sont supposés être dessinés de à dans cet ordre exact, étant donné que toute partie dessinée précédemment peut être remplacée par des murs plus proches. Vous pouvez bien sûr l'implémenter différemment tant que le résultat final est le même.UNEM

La production totale est tracé avec 7 caractères distincts: " ", "'", ".", "|", "-", "_"et ":".

Parce que détailler les formes des murs dans le corps de ce défi le rendrait trop long, ils sont plutôt fournis dans le lien TIO suivant:

Essayez-le en ligne!

Les caractères qui ne font pas partie d'un mur donné sont marqués d'un a "?"dans ces diagrammes. Ils doivent être traités comme des caractères «transparents» qui ne sont pas du tout dessinés. D'autre part, tous les espaces d'un mur sont "pleins" et doivent écraser tous les autres caractères qui ont été dessinés auparavant.

Règles

A propos de l'entrée

  • Vous pouvez prendre , , et dans n’importe quel format raisonnable.MXy
  • Vous pouvez utiliser des coordonnées indexées 0 ou 1.
  • Vous pouvez utiliser 4 valeurs distinctes de votre choix pour les directions.
  • La matrice est garantie d’être au moins .3×3
  • Vous pouvez supposer qu'il y aura toujours des murs d'enceinte sur les bords.
  • Le joueur est assuré d'être situé sur une case vide.
  • L'entrée est garantie pour être valide.

A propos de la sortie

  • Les murs doivent être dessinés exactement comme décrit.
  • Toutefois, le format de sortie est également flexible: chaîne unique, tableau de chaînes, matrice de caractères, etc.
  • Les espaces de début et de fin sont acceptables tant qu'ils sont cohérents.

C'est du .

Cas de test

Tous les cas de test utilisent la matrice suivante:

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

Résultats attendus:

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

Défi connexe:

Ce défi de 2013 est étroitement lié. Mais il a un critère de gain différent (code-challenge), une spécification beaucoup plus souple de la sortie et nécessite des E / S interactives.

Arnauld
la source
Cela m'a rappelé instantanément 3D Monster Maze, bien que cela utilise des graphiques en blocs bien sûr.
Neil
9
Vos défis sont tellement amusants et bien écrits!
Oliver
En attente d'une solution dans Minecraft ...
Est-ce que quelqu'un d'autre se souvient de l'économiseur d'écran Windows? C'était un "jeu" amusant quand j'avais 5 ou 6 ans ...
Octopus Magique Urn

Réponses:

10

Nettoyer (avec Snappy ), 800 785 670 644 octets

460 402 octets de code + 360 littéraux de chaîne de 242 octets
(échappés ici et sur TIO car ce n'est pas valide UTF-8)

Vous pouvez vérifier la longueur du littéral ici.

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

Essayez-le en ligne!

La compression Snappy fonctionne plutôt bien dans ce cas, malgré la vitesse, car il y a tellement de passages à un caractère dans la chaîne en cours de compression.

La chaîne non compressée ( #remplacée par \npour plus de clarté) est la suivante:

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

Cela code les versions de gauche des différents composants d’écran avec !au lieu de nouvelles lignes et ~au lieu de ?, lesquelles sont ensuite ~complétées à droite avec 30 caractères avant d’être ajoutées et leurs inversions de ligne ajoutées à une liste de recherche.

Le reste du code gère simplement la recherche de coordonnées avec les cas hors limites ignorés.

Οurous
la source
5

Python 2 , 864 854 848 826 810 octets

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)

Essayez-le en ligne!

TFeld
la source
4

Charbon de bois , 500 332 octets

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

Essayez-le en ligne! Le lien est vers la version verbeuse du code. Une approche quelque peu ennuyeuse, j'en ai peur; beaucoup d'impression de littéraux de chaîne compressés. Explication:

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

Tapez le tableau avec deux points supplémentaires 0de chaque côté.

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

Tranche une 7x7sous - section du tableau centré sur les coordonnées données.

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

Faites pivoter la matrice en fonction de la direction donnée.

B³⁰χ 

(espace de fin de note) Dessinez une zone vide 30×10de sorte que la sortie ait toujours une taille cohérente.

F²«‖

Dessinez chaque moitié séparément, en réfléchissant entre les deux.

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

Prenez un tableau de descripteurs de mur, scindé en morceaux de (chaîne, coordonnée y, coordonnée x), filtrez les morceaux qui ont un mur à la position appropriée dans la moitié correspondante du tableau et passez en boucle sur les murs. La position est calculée en extrayant 12 murs du tableau et en les indexant à l'aide de l'indice de bloc car il est plus facile que de localiser le mur directement à l'aide de l'indice de bloc.

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

Sautez aux coordonnées du mur et imprimez-le. Notez que la réflexion annule les coordonnées X de [0, 30)à, de (-30, 0]sorte qu'en une seule opération, la trame est effectivement décalée de 29 caractères vers la gauche.

Neil
la source
1
@Arnauld En effet, je ne tire aucun avantage de la symétrie, je devrais pouvoir en couper un tiers en dessinant chaque moitié séparément.
Neil
1
+1 pour un coup de golf de 168 octets. Je pense que c'est le plus gros golf individuel que j'ai vu ici.
ElPedro
2

Ruby , 412 391 385 383 octets

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

Essayez-le en ligne!

Prend les entrées comme un tableau de valeurs de vérité / fausseté (la note 0est la vérité en Ruby, mais nilest faussée.)

Sort un tableau de caractères.

Explication

Les blocs sont dessinés d'avant en arrière avec une distance ndécroissante et une position latérale passant d'un côté à l'autre mà -1,1,0gauche, à droite et au milieu. Le bloc du milieu E dans la rangée la plus éloignée est en fait dessiné deux fois, car nous devons vérifier les blocs A / B et les blocs C / D. n,met dsont utilisés pour modifier les valeurs xand ydans le tableau de recherche a. If xis out of range nilest renvoyé pour une cellule out of range et aucune erreur n'est générée, mais if yis out of range nilsera renvoyé pour la ligne et Ruby générera une erreur de type lorsqu'il tentera de rechercher la cellule. Pour éviter cela, la matrice est triplée dans la direction verticale avant la recherche. Si une valeur de vérité est trouvée, un bloc est tracé.

La sortie est construite dans un tableau bde tableaux de 10 éléments représentant les colonnes de la sortie et est transposée en 10 lignes à la fin de la fonction. La face avant complète de tous les blocs est dessinée (qu'elle apparaisse dans la fenêtre ou non), de sorte que de l'espace supplémentaire est nécessaire dans le tableau pour éviter les erreurs hors de portée. La plage de jvaleurs dans la fenêtre d'affichage va de -15à +14, elle est décalée de 15 lors de l'enregistrement dans le tableau pour donner une plage de 0à 29. Pour chaque bloc dessiné, trois valeurs sont calculées: pet qpour les coins gauche et droit du mur avant, respectivement, et rpour l'arrière du mur latéral. jest itéré du minimum au maximum de ces trois valeurs en dessinant les colonnes tour à tour.

Il existe 3 types de lignes: horizontal -ou _, verticaux |ou :, en diagonale et avec une répétition " .'"motif. Où les p < j < qcolonnes contenant des espaces coiffés -ou _dessinés pour former la face avant. Où jest en dehors de cette plage, les colonnes contenant un espace, |ou :sont dessinées coiffées de symboles à partir de t=" .'"pour former les bords et / ou la face latérale. Elle est gérée par la variable k=jjest positif ou k=-j-1jest négatif. Le nombre de caractères entre les majuscules supérieure et inférieure est k/3*2. Afin de manipuler correctement les bords extérieurs des blocs les plus éloignés n=3, kil faut prendre le modulo 9, mais cela ne doit pas être fait pour des valeurs plus petites den. kest donc pris modulo 36/-~n, où -~névalue à n+1.

Code non-liquéfié

->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
la source
Bonne réponse! J'aime la façon dont toutes les lignes sont générées par programme, y compris les diagonales.
Arnauld