mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Adv 2.0 D&D Phase 11 D10: ASCII !zone map renderer
Replace the flat numbered list in !zone map with a horizontal ASCII layout — room glyphs joined by ── on top, status markers (✓/▶/·) underneath, plus a one-line legend. Closes the "ASCII !map renderer" sub-item of D6 polish from gogobee_dungeon_zones.md §8. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -286,18 +286,56 @@ func (p *AdventurePlugin) zoneCmdMap(ctx MessageContext) error {
|
|||||||
}
|
}
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
b.WriteString(fmt.Sprintf("**%s — Map**\n```\n", zone.Display))
|
b.WriteString(fmt.Sprintf("**%s — Map**\n```\n", zone.Display))
|
||||||
for i, rt := range run.RoomSeq {
|
b.WriteString(renderZoneMap(run.RoomSeq, run.CurrentRoom, cleared))
|
||||||
marker := " "
|
b.WriteString("\n```\n")
|
||||||
|
b.WriteString("_E=Entry ?=Exploration T=Trap ★=Elite ☠=Boss · ✓ cleared ▶ here · pending_")
|
||||||
|
return p.SendDM(ctx.Sender, b.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// renderZoneMap produces a horizontal ASCII layout: a row of room glyphs
|
||||||
|
// connected with `──`, with a status row underneath showing cleared/here/
|
||||||
|
// pending markers per room. Glyphs match the legend printed alongside the
|
||||||
|
// map. roomSeq is the run's room order; current is the 0-based index of
|
||||||
|
// the player's location; cleared maps room index → true for finished rooms.
|
||||||
|
func renderZoneMap(roomSeq []RoomType, current int, cleared map[int]bool) string {
|
||||||
|
if len(roomSeq) == 0 {
|
||||||
|
return "(no rooms)"
|
||||||
|
}
|
||||||
|
var top, bot strings.Builder
|
||||||
|
for i, rt := range roomSeq {
|
||||||
|
if i > 0 {
|
||||||
|
top.WriteString("──")
|
||||||
|
bot.WriteString(" ")
|
||||||
|
}
|
||||||
|
top.WriteString(roomGlyph(rt))
|
||||||
switch {
|
switch {
|
||||||
case cleared[i]:
|
case cleared[i]:
|
||||||
marker = "✓ "
|
bot.WriteString("✓")
|
||||||
case i == run.CurrentRoom:
|
case i == current:
|
||||||
marker = "▶ "
|
bot.WriteString("▶")
|
||||||
|
default:
|
||||||
|
bot.WriteString("·")
|
||||||
}
|
}
|
||||||
b.WriteString(fmt.Sprintf("%s[%d] %s\n", marker, i+1, prettyRoomType(rt)))
|
|
||||||
}
|
}
|
||||||
b.WriteString("```")
|
return top.String() + "\n" + bot.String()
|
||||||
return p.SendDM(ctx.Sender, b.String())
|
}
|
||||||
|
|
||||||
|
// roomGlyph returns the single-character ASCII map glyph for a RoomType.
|
||||||
|
func roomGlyph(rt RoomType) string {
|
||||||
|
switch rt {
|
||||||
|
case RoomEntry:
|
||||||
|
return "E"
|
||||||
|
case RoomExploration:
|
||||||
|
return "?"
|
||||||
|
case RoomTrap:
|
||||||
|
return "T"
|
||||||
|
case RoomElite:
|
||||||
|
return "★"
|
||||||
|
case RoomBoss:
|
||||||
|
return "☠"
|
||||||
|
default:
|
||||||
|
return "·"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── advance ─────────────────────────────────────────────────────────────────
|
// ── advance ─────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -375,3 +375,19 @@ func TestTauntComplimentResponseLines_Deterministic(t *testing.T) {
|
|||||||
t.Errorf("taunt and compliment shouldn't collide on same key: %q", t1)
|
t.Errorf("taunt and compliment shouldn't collide on same key: %q", t1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRenderZoneMap_LayoutAndMarkers(t *testing.T) {
|
||||||
|
seq := []RoomType{RoomEntry, RoomExploration, RoomTrap, RoomElite, RoomBoss}
|
||||||
|
cleared := map[int]bool{0: true, 1: true}
|
||||||
|
got := renderZoneMap(seq, 2, cleared)
|
||||||
|
want := "E──?──T──★──☠\n✓ ✓ ▶ · ·"
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("renderZoneMap mismatch:\n got: %q\nwant: %q", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRenderZoneMap_Empty(t *testing.T) {
|
||||||
|
if got := renderZoneMap(nil, 0, nil); got != "(no rooms)" {
|
||||||
|
t.Errorf("empty seq: got %q", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user