Quando eu era criança, joguei o jogo Intellivision Advanced Dungeons and Dragons: Treasure of Tarmin . Os gráficos 3D colocam você em uma perspectiva em primeira pessoa com um realismo chocante:
Mas então eu tenho um C-64. E pude desenhar na grade de 40x25 caracteres, percorrendo a tela, definindo a cor com a tecla Ctrl e um dígito e colocando os símbolos em qualquer lugar que eu quisesse (por que não bash
me permite fazer isso?) . O conjunto de caracteres tinha componentes triangulares e componentes de bloco sólido. Então, eu pude argumentar sobre como alguém pode gerar uma renderização de sua perspectiva em uma grade através desse meio.
Encontrei a especificação de quase três décadas de idade, em papel de caderno encadernado em espiral, sobre "Dungeon Construction Set" esta semana:
( ATUALIZAÇÃO : Leitores cuidadosos perceberão que isso não se sustenta nas partes inclinadas. Os números corrigidos são fornecidos abaixo.)
Embora Treasure of Tarmin tenha sido jogado em uma grade, as paredes existiam apenas nas bordas dos quadrados da grade. Tendo aprendido o que eram bytes, percebi que se eu fizesse o mapa com bytes ... cada quadrado no mapa poderia ter quatro estados possíveis para cada uma de suas bordas:
- Desobstruído
- parede
- Porta
- Algo mais?
Eu nunca escrevi (até a noite passada). Eu pensei que poderia ser divertido para os outros tentarem.
Portanto, sua tarefa é implementar um renderizador de labirinto baseado no modo de personagem que implemente meu (corrigido !!) especificações ... mas usando as tecnologias de 2013.
Entrada
Como a especificação não define a renderização para portas, apenas assumiremos que as únicas opções são parede e não parede. Por uma questão de simplicidade, sua entrada é um mapa composto por linhas de seqüências de caracteres que se parecem com isso:
WN.. .N.. .N.. .N.. .N.E
W... .... .... ..S. ...E
W... .N.E W... .N.. ...E
W... .... .... .... ...E
W.S. ..S. ..S. ..S. ..SE
Isso seria um mapa 5x5. O canto superior esquerdo (1,1) tem sua parede W
est e N
ortogonal. O canto inferior direito (5,5) tem sua parede S
externa e E
externa.
Isso é consideravelmente menos divertido sem navegação no mapa. Então, no mínimo, coloque seu jogador em (1,1) voltado para o norte e ofereça a ele:
[F]orward, [B]ackward, turn [L]eft, turn [R]ight or [Q]uit?
Em cada etapa, produza uma exibição de 16x15 da perspectiva em primeira pessoa, conforme definido pelas especificações do papel para notebook. Para evitar que você precise contar, o tamanho das paredes planas nas três distâncias são:
14x13 (directly in front of you; e.g. wall is in same cell)
8x7 (one step away)
6x5 (two steps away)
Os tamanhos delimitadores das paredes inclinadas são:
1x15 (your direct left or right; e.g. wall is in same cell)
3x13 (one step away)
1x7 (two steps away)
Esclarecimentos
As células adjacentes podem discordar sobre paredes compartilhadas. Portanto, a borda sul de um quadrado pode ser uma parede, enquanto a borda norte da praça ao sul dela seria desobstruída. No design original, considerei isso um recurso: permite idéias interessantes como portas de mão única ... ou paredes invisíveis que só aparecem depois que você passa por elas. Para essa simplificação, siga a mesma regra: para navegação e renderização, preste atenção apenas ao status da borda na célula mais próxima de você na direção em que está voltada .
A vista é muito melhor com "sombreamento". Portanto, para seus blocos completos, alterne o Unicode 2593 ▓ e 2591 ░ ou use
X
e+
se sua implementação for ASCII.Caracteres de triângulo Unicode (25E2 ◢, 25E3 ◣, 25E4 ◤, 25E5 ◥) são um pouco ruins para desenhar isso. Além de não ter variantes sombreadas, elas geralmente aumentam apenas a largura do caractere e não a altura total ... mesmo em fontes de largura fixa. Você pode desenhar blocos completos ou caracteres de barra ou algo de sua escolha nos locais que eu queria diagonais. Soluções criativas interessantes que incorporam cores e usam esses caracteres em vez de sombreado são apreciadas.
Você pode assumir que as paredes mais externas estão definidas para limitar a área de jogo, para que você não precise se preocupar em renderizar nada fora do labirinto. Quaisquer paredes mais afastadas de você do que as especificações são ignoradas e apenas deixam espaço vazio.
O sombreamento da parede que você vê diretamente à sua frente se estiver voltado para o norte em (1,1) deve ser ESCURO. Sombreamento alternativo nas paredes adjacentes no mapa, de modo que, se todas as paredes estivessem presentes, uma parede clara nunca encostaria em uma parede escura.
Uma implementação C-64 que realmente faz o que eu originalmente pretendia ... com os caracteres diagonais e tudo ... superará qualquer outro critério de entrada. :-)
Exemplos
Para o mapa de amostra fornecido acima ...
Em (1,3), virado a sul:
/
/+
/X+
/XX+
/XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
\XXX+
\XX+
\X+
\+
\
Na (3,2) virada a sul:
/* blank line */
X /
X /+
X /++
X +++
X +++
X +++
X +++
X +++
X +++
X +++
X \++
X \+
X \
/* blank line */
Em (3,2), de frente para o leste:
/* blank line */
/
/X
/XX
XXX
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
XXX
\XX
\X
\
/* blank line */
Em (2,3), voltado para o norte:
/
++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
\
X
s na sua opinião, 3, 2
voltadas para o sul?