Fix explain_unresolved() not excluding toleranced bearings like solve_location() does
Latent inconsistency flagged during the ocr.py refactor: solve_location()
already excludes a compass-word bearing (bearing_tolerance_deg set) from
its own bearings list before triangulating, since a toleranced bearing
names a sector, not a precise ray, and shouldn't be treated as if it
were one. explain_unresolved()'s bearings list didn't have the same
exclusion, so a toleranced-only bearing plus a distance clue could get
described as inconsistent geometry ('the bearing from X never crosses
the Ykm circle...') when the real reason nothing resolved is just that
the bearing was never usable for that math in the first place. Locked
in with a new test.
This commit is contained in:
parent
ddb7867a88
commit
21c6553784
@ -294,7 +294,15 @@ def explain_unresolved(location: Location, board: Board) -> str | None:
|
||||
return "waiting on " + ", ".join(unresolved_refs) + " to have a known position first"
|
||||
|
||||
resolved = [(clue, pt) for clue in location.clues if (pt := _entity_point(board, clue.reference)) is not None]
|
||||
bearings = [(c, p) for c, p in resolved if c.bearing_deg is not None and c.distance_km is None]
|
||||
# A toleranced bearing (compass word, not a precise degree reading)
|
||||
# is never used to triangulate in solve_location() either (see its
|
||||
# own comment above), excluded here too so this explanation doesn't
|
||||
# claim a toleranced-only bearing could resolve something when it
|
||||
# never actually could.
|
||||
bearings = [
|
||||
(c, p) for c, p in resolved
|
||||
if c.bearing_deg is not None and c.distance_km is None and c.bearing_tolerance_deg is None
|
||||
]
|
||||
distances = [(c, p) for c, p in resolved if c.distance_km is not None and c.bearing_deg is None]
|
||||
|
||||
if bearings and distances:
|
||||
|
||||
@ -76,6 +76,23 @@ def test_toleranced_bearing_is_never_used_to_triangulate():
|
||||
assert not target.location.potential_coords
|
||||
|
||||
|
||||
def test_explain_unresolved_ignores_a_toleranced_bearing_too():
|
||||
"""A real inconsistency: solve_location() already excluded a
|
||||
toleranced bearing from triangulation, but explain_unresolved()'s
|
||||
own bearings list didn't, so it could describe a toleranced-only
|
||||
bearing as if it were usable geometry. Only a distance clue is left
|
||||
once the toleranced bearing is (correctly) excluded, one clue alone
|
||||
is never inconsistent with itself, so there's nothing to explain."""
|
||||
board = _board_with_spotters(Coord("J", 5, 0, 0), Coord("L", 4, 3, 0))
|
||||
target = board.add_target(TargetType.HOSTILE_TANK, id_="1")
|
||||
target.location = Location.from_desc("x", [
|
||||
Clue(reference="Spotter#1", distance_km=3.0),
|
||||
Clue(reference="Spotter#2", bearing_deg=270.0, bearing_tolerance_deg=11.25),
|
||||
])
|
||||
solver.resolve_board(board)
|
||||
assert solver.explain_unresolved(target.location, board) is None
|
||||
|
||||
|
||||
def test_manual_coord_override_clears_a_stale_note():
|
||||
board = _board_with_spotters(Coord("J", 5, 0, 0), Coord("J", 5, 1, 0))
|
||||
target = board.add_target(TargetType.HOSTILE_TANK, id_="1")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user