mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-16 08:52:42 +00:00
Branching zones G7: collapse empty columns in !zone map
The graph-mode map renderer iterated 0..maxX, emitting a blank slot for columns whose only inhabitant was a hidden secret node. In Matrix code blocks the dark background painted that gap as a phantom cell with no status mark — read in playtest as "a box missing a dot." Collapse columns with no visible nodes before laying out rows; secret columns reappear once the player visits them.
This commit is contained in:
@@ -57,9 +57,19 @@ func renderZoneGraphMap(g ZoneGraph, run *DungeonRun) string {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Drop columns that have no visible nodes (e.g. when the only
|
||||||
|
// entry was a hidden secret). Otherwise the render leaves a blank
|
||||||
|
// slot mid-row that reads as a missing status mark.
|
||||||
|
visibleX := make([]int, 0, maxX+1)
|
||||||
|
for x := 0; x <= maxX; x++ {
|
||||||
|
if len(cols[x]) > 0 {
|
||||||
|
visibleX = append(visibleX, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Find max stack height per column for vertical alignment.
|
// Find max stack height per column for vertical alignment.
|
||||||
maxRows := 0
|
maxRows := 0
|
||||||
for x := 0; x <= maxX; x++ {
|
for _, x := range visibleX {
|
||||||
if len(cols[x]) > maxRows {
|
if len(cols[x]) > maxRows {
|
||||||
maxRows = len(cols[x])
|
maxRows = len(cols[x])
|
||||||
}
|
}
|
||||||
@@ -73,9 +83,9 @@ func renderZoneGraphMap(g ZoneGraph, run *DungeonRun) string {
|
|||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
for row := 0; row < maxRows; row++ {
|
for row := 0; row < maxRows; row++ {
|
||||||
var top, bot strings.Builder
|
var top, bot strings.Builder
|
||||||
for x := 0; x <= maxX; x++ {
|
for i, x := range visibleX {
|
||||||
if x > 0 {
|
if i > 0 {
|
||||||
connector, statusGap := graphConnector(g, cols[x-1], cols[x], row, visited)
|
connector, statusGap := graphConnector(g, cols[visibleX[i-1]], cols[x], row, visited)
|
||||||
top.WriteString(connector)
|
top.WriteString(connector)
|
||||||
bot.WriteString(statusGap)
|
bot.WriteString(statusGap)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,43 @@ func TestRenderZoneGraphMap_HidesUnvisitedSecrets(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestRenderZoneGraphMap_CollapsesEmptyColumns confirms columns whose
|
||||||
|
// only inhabitant is a hidden secret don't leave a phantom blank slot
|
||||||
|
// in the glyph/status rows. Prior to G7 the renderer iterated 0..maxX
|
||||||
|
// and emitted a space for empty columns, which read as a "missing dot".
|
||||||
|
func TestRenderZoneGraphMap_CollapsesEmptyColumns(t *testing.T) {
|
||||||
|
nodes := []ZoneNode{
|
||||||
|
{NodeID: "z.entry", Kind: NodeKindEntry, IsEntry: true, PosX: 0},
|
||||||
|
{NodeID: "z.mid", Kind: NodeKindExploration, PosX: 1},
|
||||||
|
// Secret sits alone in column 2 — hidden until visited.
|
||||||
|
{NodeID: "z.secret", Kind: NodeKindSecret, PosX: 2, PosY: 1},
|
||||||
|
{NodeID: "z.boss", Kind: NodeKindBoss, IsBoss: true, PosX: 3},
|
||||||
|
}
|
||||||
|
edges := []ZoneEdge{
|
||||||
|
{From: "z.entry", To: "z.mid"},
|
||||||
|
{From: "z.mid", To: "z.secret", Lock: LockPerception, LockData: map[string]any{"dc": 12}},
|
||||||
|
{From: "z.mid", To: "z.boss"},
|
||||||
|
{From: "z.secret", To: "z.boss"},
|
||||||
|
}
|
||||||
|
g := BuildGraph("test_zone_collapse", nodes, edges)
|
||||||
|
got := renderZoneGraphMap(g, &DungeonRun{
|
||||||
|
CurrentNode: "z.entry",
|
||||||
|
VisitedNodes: []string{"z.entry"},
|
||||||
|
})
|
||||||
|
// With col 2 collapsed, the top row should be a contiguous chain
|
||||||
|
// E──?──☠ with no double-gap.
|
||||||
|
if !strings.Contains(got, "E──?──☠") {
|
||||||
|
t.Errorf("expected collapsed top row 'E──?──☠', got:\n%s", got)
|
||||||
|
}
|
||||||
|
// And no run of 3+ spaces between glyphs (would indicate a phantom column).
|
||||||
|
for _, line := range strings.Split(got, "\n") {
|
||||||
|
trimmed := strings.TrimSpace(line)
|
||||||
|
if strings.Contains(trimmed, " ") {
|
||||||
|
t.Errorf("phantom empty column detected in line %q (full output:\n%s)", line, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestRenderZoneGraphMap_LockedEdgeRenderedAsCross verifies locked-only
|
// TestRenderZoneGraphMap_LockedEdgeRenderedAsCross verifies locked-only
|
||||||
// approaches show ╳ instead of ──.
|
// approaches show ╳ instead of ──.
|
||||||
func TestRenderZoneGraphMap_LockedEdgeRenderedAsCross(t *testing.T) {
|
func TestRenderZoneGraphMap_LockedEdgeRenderedAsCross(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user