Cuando era niño, jugué al juego Intellivision Advanced Dungeons and Dragons: Treasure of Tarmin . Los gráficos en 3-D lo colocan en un punto de vista en primera persona con un realismo impactante:
Pero luego obtuve un C-64. Y pude dibujar en la cuadrícula de 40x25 caracteres al pasar el cursor por la pantalla, establecer el color con la tecla Ctrl y un dígito, y poner símbolos en cualquier lugar que quisiera (¿por qué no me bash
dejas hacer eso?) . El conjunto de caracteres tenía componentes triangulares y componentes de bloque sólido. Así que pude razonar cómo se puede generar una representación de la perspectiva de uno en una cuadrícula a través de ese medio.
Encontré la especificación de casi tres décadas de antigüedad, en papel de cuaderno encuadernado en espiral, sobre "Dungeon Construction Set" esta semana:
( ACTUALIZACIÓN : los lectores cuidadosos notarán que esto no se mantiene bien en las partes inclinadas. Los números corregidos se proporcionan a continuación).
Aunque Treasure of Tarmin se jugó en una cuadrícula, las paredes solo existían en los bordes de los cuadrados de la cuadrícula. Después de saber qué bytes eran, me di cuenta de que si hacía el mapa con bytes ... entonces cada cuadrado en el mapa podría tener cuatro estados posibles para cada uno de sus bordes:
- Sin obstáculos
- pared
- Puerta
- ¿Algo más?
Nunca pude escribirlo (hasta anoche). Pensé que sería divertido para otros intentarlo.
Entonces, su tarea es implementar un renderizador de laberintos basado en modo de personaje que implemente mi (¡corregido!) Especificación ... pero usando las tecnologías de 2013.
Entrada
Debido a que la especificación no define el renderizado para puertas, asumiremos que las únicas opciones son wall-and-not-wall. Para simplificar, su entrada es un mapa compuesto por líneas de cadenas que se ven así:
WN.. .N.. .N.. .N.. .N.E
W... .... .... ..S. ...E
W... .N.E W... .N.. ...E
W... .... .... .... ...E
W.S. ..S. ..S. ..S. ..SE
Eso sería un mapa de 5x5. La esquina superior izquierda (1,1) tiene su conjunto de pared W
est y N
orth. La esquina inferior derecha (5,5) tiene su conjunto de pared S
exterior y exterior E
.
Esto es considerablemente menos divertido sin navegación por el mapa. Entonces, como mínimo, coloque su jugador en (1,1) hacia el norte y ofrézcales:
[F]orward, [B]ackward, turn [L]eft, turn [R]ight or [Q]uit?
En cada paso, imprima una pantalla de 16x15 de la perspectiva en primera persona, tal como se define en las especificaciones del papel del cuaderno. Para evitar que tenga que contar, el tamaño de las paredes planas en las tres distancias son:
14x13 (directly in front of you; e.g. wall is in same cell)
8x7 (one step away)
6x5 (two steps away)
Los tamaños límite de las paredes inclinadas son:
1x15 (your direct left or right; e.g. wall is in same cell)
3x13 (one step away)
1x7 (two steps away)
Aclaraciones
Las celdas adyacentes pueden estar en desacuerdo sobre las paredes compartidas. Por lo tanto, el borde sur de un cuadrado podría ser una pared, mientras que el borde norte de la plaza al sur no estaría obstruido. En el diseño original, consideraba esto como una característica: permite ideas interesantes como puertas unidireccionales ... o paredes invisibles que solo aparecen después de pasar por ellas. Para esta simplificación, siga la misma regla: para la navegación y el renderizado, preste atención solo al estado del borde en la celda más cercana a usted en la dirección que está mirando .
La vista es mucho mejor con "sombreado". Entonces, para sus bloques completos, alterne Unicode 2593 ▓ y 2591 °, o use
X
y+
si su implementación es ASCII.Los caracteres de triángulo Unicode (25E2 ◢, 25E3 ◣, 25E4 ◤, 25E5 ◥) son un poco aburridos para dibujar esto. Además de no tener variantes sombreadas, a menudo estiran solo el ancho del carácter y no la altura completa ... incluso en fuentes de ancho fijo. Puede dibujar bloques completos o caracteres de barra diagonal o algo de su elección en los lugares que quería diagonales. Se aprecian soluciones creativas interesantes que incorporan color y usan estos caracteres en lugar de sombrear.
Puede suponer que las paredes más externas están configuradas para delimitar el área de juego, por lo que no tiene que preocuparse por renderizar nada fuera del laberinto. Cualquier muro más alejado de ti que la especificación se ignora y simplemente deja un espacio vacío.
El sombreado de la pared que ve directamente frente a usted si mira hacia el norte en (1,1) debe ser OSCURO. Sombreado alternativo en las paredes adyacentes en el mapa, de modo que si todas las paredes estuvieran presentes, una pared clara nunca colindaría con una pared oscura.
Una implementación C-64 que realmente hace lo que originalmente pretendía ... con los caracteres diagonales y todo ... prevalecerá sobre cualquier otro criterio de entrada. :-)
Ejemplos
Para el mapa de muestra dado anteriormente ...
En (1,3) hacia el sur:
/
/+
/X+
/XX+
/XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
\XXX+
\XX+
\X+
\+
\
En (3,2) hacia el sur:
/* blank line */
X /
X /+
X /++
X +++
X +++
X +++
X +++
X +++
X +++
X +++
X \++
X \+
X \
/* blank line */
En (3,2) hacia el este:
/* blank line */
/
/X
/XX
XXX
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
XXX
\XX
\X
\
/* blank line */
En (2,3) hacia el norte:
/
++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
\
X
s en su vista 3, 2
hacia el sur?