It’s a rough draft, but I think this is at the point where it could do with other eyes on it for feedback. The idea is that the game automatically produces a map showing visited rooms as you move. It wouldn’t be hard to make it also put links on the map that execute a GO TO.
Automap:
(map $Room at $Coords)
(now) ($Room has coordinates $Coords)
(exhaust) (spread coordinates from [$Room])
(spread coordinates from $List)
(nonempty $List)
(collect $Next)
*($This is one of $List)
*(from $This go $Dir to $Next)
~($Next has coordinates $)
($This has coordinates $ThisC)
($ThisC modified by $Dir becomes $NextC)
(now) ($Next has coordinates $NextC)
(into $NextGen)
(spread coordinates from $NextGen)
(spread coordinates from [])
([$X $Y $Z] modified by #north becomes [$X $Y1 $Z])
($Y minus 1 into $Y1)
([$X $Y $Z] modified by #south becomes [$X $Y1 $Z])
($Y plus 1 into $Y1)
([$X $Y $Z] modified by #west becomes [$X1 $Y $Z])
($X minus 1 into $X1)
([$X $Y $Z] modified by #east becomes [$X1 $Y $Z])
($X plus 1 into $X1)
([$X $Y $Z] modified by #northeast becomes [$X1 $Y1 $Z])
($X plus 1 into $X1)
($Y minus 1 into $Y1)
([$X $Y $Z] modified by #northwest becomes [$X1 $Y1 $Z])
($X minus 1 into $X1)
($Y minus 1 into $Y1)
([$X $Y $Z] modified by #southeast becomes [$X1 $Y1 $Z])
($X plus 1 into $X1)
($Y plus 1 into $Y1)
([$X $Y $Z] modified by #southwest becomes [$X1 $Y1 $Z])
($X minus 1 into $X1)
($Y plus 1 into $Y1)
([$X $Y $Z] modified by #up becomes [$X $Y $Z1])
($Z plus 1 into $Z1)
([$X $Y $Z] modified by #down becomes [$X $Y $Z1])
($Z minus 1 into $Z1)
(minimum of [$Head] is $Head)
(minimum of [$Head$Tail] is $Min)
(minimum of $Tail is $Other)
(if) ($Head < $Other) (then)
($Min = $Head)
(else)
($Min = $Other)
(endif)
(maximum of [$Head] is $Head)
(maximum of [$Head$Tail] is $Max)
(maximum of $Tail is $Other)
(if) ($Head > $Other) (then)
($Max = $Head)
(else)
($Max = $Other)
(endif)
(draw map of layer $Z)
(collect $Room)
*(room $Room)
($Room is visited)
($Room has coordinates [$ $ $Z])
(into $Rooms)
(collect $X)
*($Room is one of $Rooms)
($Room has coordinates [$X $ $])
(into $Xs)
(collect $Y)
*($Room is one of $Rooms)
($Room has coordinates [$ $Y $])
(into $Ys)
(maximum of $Xs is $XMax)
(minimum of $Xs is $XMin)
(maximum of $Ys is $YMax)
(minimum of $Ys is $YMin)
(draw header of layer $Z from $XMin to $XMax)
(draw map of layer $Z from $XMin to $XMax and $YMin to $YMax)
(draw footer of layer $Z from $XMin to $XMax)
(draw map of layer $Z from $XMin to $XMax and $Y to $YMax)
($Y > $YMax) %% Base case: no more recursion
(draw exit header of row $Y)
(draw exits above $Y of $Z from $XMin to $XMax) %% Just draw final row of exits
(draw map of layer $Z from $XMin to $XMax and $Y to $YMax)
(draw exit header of row $Y)
(draw exits above $Y of $Z from $XMin to $XMax)
(draw header of row $Y)
(draw row $Y of layer $Z from $XMin to $XMax)
(draw footer of row $Y)
($Y plus 1 into $YNext)
(draw map of layer $Z from $XMin to $XMax and $YNext to $YMax)
(draw row $Y of layer $Z from $X to $XMax)
($X > $XMax) %% Base case
($X minus 1 into $XM1)
(if) (exit #east from [$XM1 $Y $Z]) (then)

(else)
(space 1)
(endif)
(draw row $Y of layer $Z from $X to $XMax)
($X plus 1 into $XP1)
($X minus 1 into $XM1)
%% West exit
(if) (exit #west from [$X $Y $Z]) (or) (exit #east from [$XM1 $Y $Z]) (then)

(else)
(space 1)
(endif)
%% Room
(if) (room $Room at [$X $Y $Z] is visited) (then)
\( (no space) (room glyph $Room) (no space) \)
(else)
(space 3)
(endif)
(draw row $Y of layer $Z from $XP1 to $XMax)
(room glyph $Room)
(if) (current room $Room) (then)
\@
(else)
(space 1)
(endif)
(final exits above $X $Y $Z) %% Cutdown version of the below for the very right edge
($Y minus 1 into $YM1)
($X minus 1 into $XM1)
(if) (exit #southeast from [$XM1 $YM1 $Z]) (then)
($NorthWest = 1)
(else)
($NorthWest = 0)
(endif)
(if) (exit #northeast from [$XM1 $Y $Z]) (then)
($NorthEast = 1)
(else)
($NorthEast = 0)
(endif)
(if) ($NorthWest = 1) (then)
(if) ($NorthEast = 1) (then)
X
(else)
\\
(endif)
(else)
(if) ($NorthEast = 1) (then)
/
(else)
(space 1)
(endif)
(endif)
(draw exits above $Y of $Z from $X to $XMax)
($X > $XMax) %% Base case
(final exits above $X $Y $Z)
(line)
(draw exits above $Y of $Z from $X to $XMax)
($X plus 1 into $XP1)
($X minus 1 into $XM1)
($Y minus 1 into $YM1)
%% Northwest exit
(if) (exit #northwest from [$X $Y $Z]) (or) (exit #southeast from [$XM1 $YM1 $Z]) (then)
($NorthWest = 1)
(else)
($NorthWest = 0)
(endif)
%% Northeast exit
(if) (exit #northeast from [$XM1 $Y $Z]) (or) (exit #southwest from [$X $YM1 $Z]) (then)
($NorthEast = 1)
(else)
($NorthEast = 0)
(endif)
(if) ($NorthWest = 1) (then)
(if) ($NorthEast = 1) (then)
X
(else)
\\
(endif)
(else)
(if) ($NorthEast = 1) (then)
/
(else)
(space 1)
(endif)
(endif)
%% Up exit
(if) (exit #down from [$X $YM1 $Z]) (then)
(no space) d (no space)
(else)
(space 1)
(endif)
%% North exit
(if) (exit #north from [$X $Y $Z]) (or) (exit #south from [$X $YM1 $Z]) (then)
\
(else)
(space 1)
(endif)
(if) (exit #up from [$X $Y $Z]) (then)
(no space) u (no space)
(else)
(space 1)
(endif)
(draw exits above $Y of $Z from $XP1 to $XMax)
(draw exit header of row $)
(space 1)
(draw header of row $Y)
$Y (no space)
(draw footer of row $Y)
(no space) $Y (line)
(draw header of layer $Z from $XMin to $XMax)
$Z (space 1)
(draw legend from $XMin to $XMax)
(no space) $Z
(line)
(draw footer of layer $Z from $XMin to $XMax)
(draw header of layer $Z from $XMin to $XMax)
(draw legend from $XMin to $XMax)
($XMin > $XMax) %% Base case
(draw legend from $XMin to $XMax)
(space 1) $XMin (space 2)
($XMin plus 1 into $XMin1)
(draw legend from $XMin1 to $XMax)
(room $Room at $Coords is visited)
*(room $Room)
($Room has coordinates $Coords)
($Room is visited)
(exit $Dir from $Coords)
(room $Room at $Coords is visited)
(from $Room go $Dir to $Other)
(room $Other)
And a test scenario:
(from #alpha go #east to #beta)
(from #beta go #west to #alpha)
(from #alpha go #south to #gamma)
(from #gamma go #north to #alpha)
(from #beta go #south to #delta)
(from #delta go #north to #beta)
(from #gamma go #east to #delta)
(from #delta go #west to #gamma)
(from #alpha go #southeast to #delta)
(from #delta go #northwest to #alpha)
(from #beta go #southwest to #gamma)
(from #gamma go #northeast to #beta)
(from #beta go #southeast to #epsilon)
(from #epsilon go #northwest to #beta)
(from #epsilon go #south to #zeta)
(from #zeta go #north to #epsilon)
(from #beta go #up to #eta)
(from #eta go #down to #beta)
(room #alpha/#beta/#gamma/#delta/#epsilon/#zeta/#eta)
(#player is #in #alpha)
(current player #player)
(intro)
(map #alpha at [1 1 1])
(perform [look])
(perform [look])
(current room $Room)
($Room has coordinates [$ $ $Z])
(div @map) (draw map of layer $Z)
(style class @map)
fontfamily: monospace;
Test with dgdebug test_automap.dg automap.dg stdlib.dg
.
Potential next steps:
 Links!
 Unicode instead of ASCII
 Some way of resizing the status line to support it?