mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-16 17:02:42 +00:00
Long expeditions D1-c: T3 zones to new 22-26 room band
Both T3 zones follow the D1-a/b pattern: extend the graph so the longest entry→boss walk lands in band, keep the zone's authored topology intact. manor_blackspire (T3): 11 → 35 nodes, longest 23 (band 22-26) underforge (T3): 10 → 31 nodes, longest 23 (band 22-26) Topology preserved per zone: - Manor: two-stacked-3-way forks identity + full lock-kind coverage (LockNone, LockPerception, LockStatCheck, LockLevelMin). Adds the missing Trap anchor (Cursed Threshold). All six spokes are 3 mid-nodes so route choice is loot/encounter character, not shortcut economics. - Underforge: one-way-descent gauntlet identity preserved — 17-node linear preamble through the existing Cooling River (TRAP) and Magma Chamber (ELITE), single 3-way antechamber fork before boss. All three antechamber spokes are 4 mid-nodes. MinRooms/MaxRooms re-pitched 7-9 → 22-26 so the dice fallback also lands in band for any future graphless variant.
This commit is contained in:
@@ -10,8 +10,10 @@ func TestManorBlackspireGraph_Registered(t *testing.T) {
|
||||
if g.Entry != "manor_blackspire.entry" {
|
||||
t.Errorf("entry node = %q", g.Entry)
|
||||
}
|
||||
if len(g.Nodes) != 11 {
|
||||
t.Errorf("nodes = %d, want 11", len(g.Nodes))
|
||||
// Long-expedition D1-c widened this zone from 11 → 35 nodes so the
|
||||
// longest entry→boss walk lands in the T3 [22,26] traversal band.
|
||||
if len(g.Nodes) != 35 {
|
||||
t.Errorf("nodes = %d, want 35", len(g.Nodes))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,12 +35,14 @@ func TestManorBlackspireGraph_TwoStackedThreeWayForks(t *testing.T) {
|
||||
func TestManorBlackspireGraph_AllSpokesReachBoss(t *testing.T) {
|
||||
g := zoneManorBlackspireGraph()
|
||||
for _, leaf := range []string{
|
||||
"manor_blackspire.master_bedroom",
|
||||
"manor_blackspire.tower_observatory",
|
||||
"manor_blackspire.hidden_oratory",
|
||||
// great_hall spokes (entry of each 3-node branch).
|
||||
"manor_blackspire.portrait_gallery",
|
||||
"manor_blackspire.study",
|
||||
"manor_blackspire.library",
|
||||
"manor_blackspire.locked_study",
|
||||
"manor_blackspire.forbidden_library",
|
||||
// upper_hall spokes.
|
||||
"manor_blackspire.master_bedroom",
|
||||
"manor_blackspire.hidden_oratory",
|
||||
"manor_blackspire.tower_observatory",
|
||||
} {
|
||||
if !reachable(g, leaf, "manor_blackspire.boss") {
|
||||
t.Errorf("%s unreachable to boss", leaf)
|
||||
@@ -46,9 +50,9 @@ func TestManorBlackspireGraph_AllSpokesReachBoss(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestManorBlackspireGraph_LockLevelMinFirstUse verifies this zone is
|
||||
// the first to author LockLevelMin, completing lock-kind coverage
|
||||
// (Perception, StatCheck, LevelMin, LockNone) by G8d.
|
||||
// TestManorBlackspireGraph_LockLevelMinFirstUse verifies the tower spoke
|
||||
// still carries the LockLevelMin gate so all four lock kinds (None,
|
||||
// Perception, StatCheck, LevelMin) remain authored within this zone.
|
||||
func TestManorBlackspireGraph_LockLevelMinFirstUse(t *testing.T) {
|
||||
g := zoneManorBlackspireGraph()
|
||||
var levelMinEdge *ZoneEdge
|
||||
@@ -69,3 +73,29 @@ func TestManorBlackspireGraph_LockLevelMinFirstUse(t *testing.T) {
|
||||
t.Error("level-gated edge missing hint")
|
||||
}
|
||||
}
|
||||
|
||||
// TestManorBlackspireGraph_SymmetricBranches locks in the D1-c design
|
||||
// intent: all six fork spokes are 3 mid-nodes long so any route walks
|
||||
// the same 23-room length — the choice is loot/encounter, not shortcut.
|
||||
func TestManorBlackspireGraph_SymmetricBranches(t *testing.T) {
|
||||
g := zoneManorBlackspireGraph()
|
||||
checks := []struct {
|
||||
from, to, via string
|
||||
want int
|
||||
}{
|
||||
// great_hall → second_floor_landing, hops via each spoke.
|
||||
{"manor_blackspire.great_hall", "manor_blackspire.second_floor_landing", "manor_blackspire.portrait_gallery", 4},
|
||||
{"manor_blackspire.great_hall", "manor_blackspire.second_floor_landing", "manor_blackspire.locked_study", 4},
|
||||
{"manor_blackspire.great_hall", "manor_blackspire.second_floor_landing", "manor_blackspire.forbidden_library", 4},
|
||||
// upper_hall → spire_corridor, hops via each spoke.
|
||||
{"manor_blackspire.upper_hall", "manor_blackspire.spire_corridor", "manor_blackspire.master_bedroom", 4},
|
||||
{"manor_blackspire.upper_hall", "manor_blackspire.spire_corridor", "manor_blackspire.hidden_oratory", 4},
|
||||
{"manor_blackspire.upper_hall", "manor_blackspire.spire_corridor", "manor_blackspire.tower_observatory", 4},
|
||||
}
|
||||
for _, c := range checks {
|
||||
got := bfsHops(g, c.from, c.to, c.via)
|
||||
if got != c.want {
|
||||
t.Errorf("hops %s → %s via %s = %d, want %d", c.from, c.to, c.via, got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user