macros: an edge the map graph cannot name stops being somewhere new once it is stood on
The rung-11 reading of row 54. Route 3's connections read north and west off the cartridge (`wCurMapConnections`, and it has no warps at all) while the geography table carries west and east, so the seven walkable tiles of its north edge had an unnameable destination -- and an unnameable destination counted as unvisited, which made them first-tier for `GO ROUTE` on every hold for ever, with `GO OBJECTIVE` off the pad beside them because nothing on that map leads to the objective. A warp's destination is a byte the cartridge publishes, so `None` there is the `LAST_MAP` case already handled. An edge's comes only from `geography::connected`, so `None` there means the table cannot name the map on the other side and never will, and the only record left is the adapter's own boundary ledger. It narrows: a genuinely new edge is still first-tier until the fly reaches it. Which map is north of Route 3 is not guessed at here. That is a survey -- walk the fly off the edge with real presses and read the map id back -- and it is recorded as a residual instead.
This commit is contained in:
parent
8ef5dc321d
commit
c42255e199
2 changed files with 48 additions and 3 deletions
|
|
@ -1298,9 +1298,23 @@ fn exit_tiers(state: &mut dyn MacroState, way: Way) -> Vec<Exit> {
|
|||
let known_visited = match exit.destination(here) {
|
||||
Some(map) => state.map_visited(map),
|
||||
// A front door nobody can name opens on the map the fly came in from, which is a map
|
||||
// this run has stood on by construction. Every other unnameable destination stays a
|
||||
// candidate.
|
||||
None => exit.way == Way::Exit,
|
||||
// this run has stood on by construction.
|
||||
None if exit.way == Way::Exit => true,
|
||||
// **An edge the geography table has no row for** (2026-09-22, the rung-11 reading of
|
||||
// row 54). A warp's destination is a byte the cartridge publishes, so `None` there is
|
||||
// the `LAST_MAP` case above; an edge's destination comes only from
|
||||
// [`geography::connected`], so `None` here means the table cannot name the map on the
|
||||
// other side and never will. Route 3 is the measured one: the cartridge reports its
|
||||
// connections as **north and west** while the table carries west and *east*, so its
|
||||
// seven walkable north-edge tiles answered "leads somewhere this run has not stood
|
||||
// on" on every hold for ever, and `GO ROUTE` aimed at them once per hold.
|
||||
//
|
||||
// The only record left is the adapter's own boundary ledger, which is what section
|
||||
// 9.2 replaced as the *general* test and which is still the honest answer for an exit
|
||||
// nothing else can say anything about: an edge the run has already stood on is not
|
||||
// somewhere new. It narrows, so a genuinely new edge is still first-tier until the
|
||||
// fly reaches it.
|
||||
None => state.exit_visited(exit.id),
|
||||
};
|
||||
if !known_visited {
|
||||
fresh.push(*exit);
|
||||
|
|
|
|||
|
|
@ -3970,6 +3970,37 @@ fn go_shop_and_go_heal_are_on_the_pad_while_their_errand_stands() {
|
|||
assert!(!on_the_pad(&mut pallet, MacroKind::GoHeal));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_edge_the_table_cannot_name_stops_being_somewhere_new_once_it_is_stood_on() {
|
||||
// The rung-11 reading of row 54 (`infra/docs/macros-traps.md`). The cartridge reports Route
|
||||
// 3's connections as north and west; `geography`'s row carries west and east, so the north
|
||||
// edge's destination is unnameable -- and an unnameable destination counted as *unvisited*,
|
||||
// which made those tiles first-tier for `GO ROUTE` on every hold for ever, with
|
||||
// `GO OBJECTIVE` off the pad beside them because nothing on this map leads to the objective.
|
||||
let mut world = World::room();
|
||||
world.map = maps::ROUTE_3;
|
||||
world.size = MapSize { width: 8, height: 8 };
|
||||
world.player = Tile::new(4, 4);
|
||||
world.connections = Connections { north: true, south: false, east: false, west: true };
|
||||
// West is Pewter City, which the table does name and the run has stood on.
|
||||
world.seen_maps.insert(maps::PEWTER_CITY);
|
||||
|
||||
let north: Vec<ExitId> = ways(&mut world, Way::Route).iter().map(|exit| exit.id).collect();
|
||||
assert!(
|
||||
north.iter().all(|id| *id == ExitId::Edge(Edge::North)),
|
||||
"the unnameable north edge is the only fresh way out: {north:?}"
|
||||
);
|
||||
|
||||
// Stood on, and it is no longer somewhere new -- so the walk falls to the tier that leads
|
||||
// toward the objective instead of aiming at the same edge once per hold for ever.
|
||||
world.visited.insert(ExitId::Edge(Edge::North));
|
||||
let left: Vec<ExitId> = ways(&mut world, Way::Route).iter().map(|exit| exit.id).collect();
|
||||
assert!(
|
||||
!left.contains(&ExitId::Edge(Edge::North)),
|
||||
"an edge nothing can name, already crossed, is not first-tier: {left:?}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_errand_does_not_settle_on_the_doormat_it_is_standing_on() {
|
||||
// Row 54 of `infra/docs/macros-traps.md`, and section 12.2's rule: "a macro that completes
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue