Rastreador de mazmorras


40

Entrada

  • Una matriz binaria representa las paredes de una mazmorra.METRO
  • La posición del jugador dentro de la mazmorra.(X,y)
  • La dirección que el jugador está enfrentando actualmente (0 = Norte, 1 = Este, 2 = Sur, 3 = Oeste)re

Salida

Una representación pseudo-3D de las paredes que están en el campo de visión del jugador, como un arte ASCII de caracteres.30×10

A continuación hay varios marcos de salida posibles, junto con el mapa y la brújula correspondientes para ayudar a dominarlo (pero dibujar el mapa y la brújula no es parte del desafío).

animación

Especificación

Campo de visión

El jugador tiene paredes en su campo de visión, marcada de a . A continuación se muestran las posiciones de las paredes en relación con el jugador (en amarillo), en todas las direcciones posibles.13UNAMETRO

campo de visión

Dibujando las paredes

Se supone que los muros se dibujan de a en este orden exacto, dado que cualquier parte dibujada previamente puede sobrescribirse con muros más cercanos. Por supuesto, puede implementarlo de manera diferente siempre que el resultado final sea el mismo.UNAMETRO

Toda la producción se dibuja con 7 caracteres distintos: " ", "'", ".", "|", "-", "_"y ":".

Debido a que detallar las formas de las paredes en el cuerpo de este desafío lo haría demasiado largo, en su lugar se proporcionan en el siguiente enlace TIO:

Pruébalo en línea!

Los caracteres que no forman parte de un muro determinado están marcados con un "?"en estos diagramas. Deben tratarse como caracteres 'transparentes' que no se dibujan en absoluto. Por otro lado, todos los espacios dentro de una pared son 'sólidos' y deben sobrescribir cualquier otro personaje que haya sido dibujado previamente allí.

Reglas

Sobre la entrada

  • Usted puede tomar , , y en cualquier formato razonable.METROXyre
  • Puede usar coordenadas indexadas 0 o indexadas 1.
  • Puede usar 4 valores distintos de su elección para las direcciones.
  • Se garantiza que la matriz sea al menos .3×3
  • Puede suponer que siempre habrá paredes circundantes en los bordes.
  • Se garantiza que el jugador se ubicará en una casilla vacía.
  • La entrada está garantizada para ser válida.

Acerca de la salida

  • Las paredes deben dibujarse exactamente como se describe.
  • Sin embargo, el formato de salida también es flexible: cadena única, matriz de cadenas, matriz de caracteres, etc.
  • Los espacios en blanco iniciales y finales son aceptables siempre que sean consistentes.

Este es el .

Casos de prueba

Todos los casos de prueba utilizan la siguiente matriz:

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

Las siguientes entradas están utilizando coordenadas indexadas 0, con apuntando a la esquina superior izquierda.(0 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

Resultados esperados:

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

Desafío relacionado:

Este desafío de 2013 está estrechamente relacionado. Pero tiene un criterio ganador diferente (desafío de código), una especificación mucho más flexible de la salida y requiere E / S interactiva.


Esto me recordó instantáneamente a 3D Monster Maze, aunque eso usa gráficos de bloque, por supuesto.
Neil

9
¡Tus desafíos son muy divertidos y bien escritos!
Oliver

Esperando una solución en Minecraft ...

¿Alguien más recuerda el protector de pantalla de Windows? Fue un "juego" tan divertido cuando tenía 5 o 6 años ...
Urna de pulpo mágico el

Respuestas:


10

Limpias (con Snappy ), 800 785 670 644 bytes

460 402 bytes de código + 360 literal de cadena de 242 bytes
(escapado aquí y en TIO porque no es válido UTF-8)

Puede verificar la longitud del literal aquí.

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

Pruébalo en línea!

La compresión rápida en realidad funciona bastante bien en este caso, a pesar de estar centrada en la velocidad, porque hay muchas ejecuciones de un solo carácter en la cadena que se está comprimiendo.

La cadena sin comprimir (con #reemplazado \npor claridad) es:

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

Esto codifica las versiones del lado izquierdo de los diferentes componentes de la pantalla con en !lugar de líneas nuevas, y en ~lugar de ?, que luego se rellenan a la derecha con ~hasta 30 caracteres antes de que se agreguen ellos mismos y sus inversiones de línea a una lista de búsqueda.

El resto del código simplemente maneja la búsqueda de coordenadas con casos fuera de los límites ignorados.


5

Python 2 , 864 854 848 826 810 bytes

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)

Pruébalo en línea!


4

Carbón de leña , 500 332 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Enfoque algo aburrido, me temo; mucha impresión de literales de cadena comprimidos. Explicación:

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

Rellene la matriz con dos 0s adicionales en cada lado.

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

Corte una 7x7subsección de la matriz centrada en las coordenadas dadas.

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

Gire la matriz según corresponda para la dirección dada.

B³⁰χ 

(observe el espacio final) Dibuje un 30×10cuadro vacío para que la salida sea siempre de un tamaño consistente.

F²«‖

Dibuja cada mitad por separado, reflexionando en el medio.

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

Tome un conjunto de descriptores de muro, divídalos en trozos de (cadena, coordenada y, coordenada x), filtre esos trozos que tienen un muro en la posición relevante en la mitad relevante del conjunto y realice un bucle sobre los muros. La posición se calcula extrayendo 12 muros de la matriz e indexándolos usando el índice de fragmentos, ya que esto es más atractivo que ubicar el muro directamente usando el índice de fragmentos.

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

Salta a las coordenadas de la pared e imprímelo. Tenga en cuenta que el reflejo niega las coordenadas X de [0, 30)a (-30, 0]para que, en una pasada, el lienzo se desplace 29 caracteres a la izquierda.


1
@Arnauld De hecho, no estoy aprovechando la simetría en absoluto, debería poder cortar un tercio dibujando cada mitad por separado.
Neil

1
+1 para un golpe de golf de 168 bytes. Creo que es el golf individual más grande que he visto aquí.
ElPedro

2

Rubí , 412 391 385 383 bytes

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

Pruébalo en línea!

Toma datos como una matriz de valores de verdad / falsedad (la nota 0es verdadera en Ruby, pero niles falsa).

Emite una matriz de caracteres.

Explicación

Los bloques se dibujan de adelante hacia atrás con la distancia ndisminuyendo y la posición de lado a lado mdesplazándose a la -1,1,0izquierda, derecha, centro. El bloque central E en la fila más alejada se dibuja dos veces porque necesitamos verificar ambos bloques A / B y bloques C / D. n,my dse utilizan para modificar los valores xy ypara buscar la matriz a. Si xestá fuera de rango nilse devuelve para una celda fuera de rango y no se produce ningún error, pero si yestá fuera de rango nilse devolverá para la fila y Ruby arrojará un error de tipo cuando intente buscar la celda. Para evitar esto, la matriz se triplica en la dirección vertical antes de la búsqueda. Si se encuentra un valor verdadero, se dibuja un bloque.

La salida se construye en una matriz bde matrices de 10 elementos que representan las columnas de la salida, y se transpone en 10 filas al final de la función. Se dibuja la cara frontal completa de todos los bloques (ya sea que aparezca en la ventana gráfica o no), por lo que se necesita espacio adicional en la matriz para evitar errores fuera de rango. El rango de jvalores en la ventana gráfica es de -15a +14, esto se compensa con 15 cuando se guarda en la matriz para dar un rango de 0a 29. Para cada bloque dibujado se calculan tres valores: py qpara las esquinas izquierda y derecha de la pared frontal, respectivamente, y rpara la parte posterior de la pared lateral. jse itera del mínimo al máximo de estos tres valores dibujando las columnas a su vez.

Hay 3 tipos de líneas: horizontal -o _vertical |o :diagonal y diagonal con un " .'"patrón repetitivo . Donde las p < j < qcolumnas que contienen espacios cubiertos con -o _se dibujan para formar la cara frontal. Donde jestá fuera de este rango, las columnas que contienen espacio, |o :se dibujan con símbolos t=" .'"para formar los bordes y / o la cara lateral. Esto se gestiona mediante la variable k=jdonde jes positivo o k=-j-1donde jes negativo. El número de caracteres entre las mayúsculas y las minúsculas es k/3*2. Para manejar correctamente los bordes exteriores de los bloques más lejanos donde n=3, kdebe tomarse el módulo 9, pero esto no debe hacerse para valores más pequeños den. kPor lo tanto, se toma módulo 36/-~n, donde se -~nevalúa como n+1.

Código sin golf

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

¡Buena respuesta! Me gusta la forma en que todas las líneas se generan mediante programación, incluidas las diagonales.
Arnauld
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.