19
6
When I was a kid, I played the Intellivision game Advanced Dungeons and Dragons: Treasure of Tarmin. The 3-D graphics put you in a first-person-perspective point of view with shocking realism:
But then I got a C-64. And I was able to draw on the 40x25 character grid by cursoring around the screen, setting the color with the Ctrl key and a digit, and putting symbols anywhere I wanted (why doesn't bash
let me do that?). The character set had triangular components and solid block components. So I was able to reason through how one might generate a rendering of one's perspective in a grid through that medium.
I found the nearly-three-decades-old spec, in spiral-bound notebook paper, about "Dungeon Construction Set" this week:
(UPDATE: Careful readers will notice that this doesn't quite hold together on the slanted parts. Corrected numbers are provided below.)
Though Treasure of Tarmin was played on a grid, the walls existed only on the edges of grid squares. Having learned what bytes were, I realized that if I made the map out of bytes...then each square on the map could have four possible states for each of its edges:
- Unobstructed
- Wall
- Door
- Something Else?
I never did get around to writing it (until last night). I thought it might be fun for others to try.
So your task is to implement a character-mode-based maze renderer that implements my (corrected!!) spec...but using the technologies of 2013.
Input
Because the spec doesn't define rendering for doors, we'll just assume the only options are wall-and-not-wall. For simplicity, your input is a map composed of lines of strings that look like this:
WN.. .N.. .N.. .N.. .N.E
W... .... .... ..S. ...E
W... .N.E W... .N.. ...E
W... .... .... .... ...E
W.S. ..S. ..S. ..S. ..SE
That would be a 5x5 map. The upper left corner (1,1) has its W
est and N
orth wall set. The lower right corner (5,5) has its S
outh and E
ast wall set.
This is considerably less fun with no map navigation. So at minimum, put your player at (1,1) facing north and offer them:
[F]orward, [B]ackward, turn [L]eft, turn [R]ight or [Q]uit?
At each step, output a 16x15 display of the first-person perspective, as defined by the notebook paper spec. To keep you from having to count, the size of flat walls at the three distances are:
14x13 (directly in front of you; e.g. wall is in same cell)
8x7 (one step away)
6x5 (two steps away)
The bounding sizes of the slanted walls are:
1x15 (your direct left or right; e.g. wall is in same cell)
3x13 (one step away)
1x7 (two steps away)
Clarifications
Adjacent cells may disagree about shared walls. So the south edge on a square might be a wall, while the north edge on the square to the south of it would be unobstructed. In the original design I considered this a feature: it permits interesting ideas like one-way doors...or invisible walls that only appear after you passed through them. For this simplification, follow the same rule: for navigation and rendering, pay attention only to the edge status on the cell closest to you in the direction you are facing.
The view is a lot better with "shading". So for your full blocks, alternate either Unicode 2593 ▓ and 2591 ░, or use
X
and+
if your implementation is ASCII.Unicode triangle characters (25E2 ◢, 25E3 ◣, 25E4 ◤, 25E5 ◥) are a bit lame for drawing this. Besides not having any shaded variants, they often stretch only the width of the character and not the full height...even in fixed width fonts. You can draw full blocks or slash characters or something of your choosing in the places I wanted diagonals. Interesting creative solutions that incorporate color and use these characters instead of shading appreciated.
You may assume the outermost walls are set to bound the playing area, so you don't have to worry about rendering anything outside of the maze. Any walls farther away from you than the spec are ignored and just leave empty space.
The shading of the wall you see directly in front of you if facing North at (1,1) should be DARK. Alternate shading on adjacent walls in the map, such that if all walls were present then a light wall would never abut a dark wall.
A C-64 implementation that actually does what I originally intended...with the diagonal characters and all...will trump any other entry criterion. :-)
Examples
For the sample map given above...
At (1,3) facing south:
/
/+
/X+
/XX+
/XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
\XXX+
\XX+
\X+
\+
\
At (3,2) facing south:
/* blank line */
X /
X /+
X /++
X +++
X +++
X +++
X +++
X +++
X +++
X +++
X \++
X \+
X \
/* blank line */
At (3,2) facing east:
/* blank line */
/
/X
/XX
XXX
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
+++++XXXXXX+XXX+
XXX
\XX
\X
\
/* blank line */
At (2,3) facing north:
/
++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
X++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
++++++++++++++X
\
1I suggest making this a [tag:code-challenge] - a golf would be way too unreadable and hard :P – Doorknob – 2013-12-15T14:46:29.550
1@Doorknob Don't let it fool you...it's actually not all that hard. There's a pretty good hint with the lists of 3 bounding sizes. And what is a golf but a challenge that is solved and then pared down? :-) But I'll let people pick how they want to solve it... NP – HostileFork says dont trust SE – 2013-12-15T14:50:48.370
Could you please explain the two columns of
X
s in your view of3, 2
facing south? – jazzpi – 2013-12-21T10:32:51.883Especially the one on the right hand side. I see why the left one is there. But the right one seems to violate Clarification #1. – jazzpi – 2013-12-21T12:37:54.223
@jazzpi Oops, you're right, the map I put up does need to obey clarification 1! Well done. Fixed. (I'd put the missing south wall in on my own version at some point apparently...but good to have a test case in the sample...so let's leave the south wall out!) – HostileFork says dont trust SE – 2013-12-22T08:46:06.877