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:
- 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.
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
North wall set. The lower right corner (5,5) has its
East 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)
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
+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. :-)
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 \