sleep_provider deconflicts beds against other pawns' targets
L: SleepProvider.find_best_for filters bed candidates via the existing Job.is_target_taken_by_other mechanism that ConstructionProvider already uses. Sets j.target_node = best_bed on the proposed job so other pawns see the claim. Fixes the 2/3-pawns-floor-sleep symptom (memory.md 2026-05-11) caused by greedy nearest-neighbor convergence. The bed.claim() mechanism was already race-free; this just prevents simultaneous proposals on the same bed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cf43ef9a98
commit
2f76ae1639
1 changed files with 9 additions and 0 deletions
|
|
@ -52,6 +52,12 @@ func find_best_for(pawn) -> Job:
|
||||||
for bed in World.beds:
|
for bed in World.beds:
|
||||||
if not bed.is_available():
|
if not bed.is_available():
|
||||||
continue
|
continue
|
||||||
|
# Skip beds already targeted by another pawn's active job. This is the
|
||||||
|
# same deconfliction used by ConstructionProvider (Job.is_target_taken_by_other)
|
||||||
|
# and prevents all simultaneously-tired pawns from converging on the same
|
||||||
|
# nearest bed and then losing the race at claim time.
|
||||||
|
if Job.is_target_taken_by_other(bed, pawn):
|
||||||
|
continue
|
||||||
var d: int = abs(bed.tile.x - pawn.tile.x) + abs(bed.tile.y - pawn.tile.y)
|
var d: int = abs(bed.tile.x - pawn.tile.x) + abs(bed.tile.y - pawn.tile.y)
|
||||||
if d < best_dist:
|
if d < best_dist:
|
||||||
best_dist = d
|
best_dist = d
|
||||||
|
|
@ -73,6 +79,9 @@ func find_best_for(pawn) -> Job:
|
||||||
var j := Job.new()
|
var j := Job.new()
|
||||||
if best_bed != null:
|
if best_bed != null:
|
||||||
j.label = "Sleep at %s" % target_tile
|
j.label = "Sleep at %s" % target_tile
|
||||||
|
# Tag the job's target so other pawns see this bed as taken via
|
||||||
|
# Job.is_target_taken_by_other() before it is physically claimed.
|
||||||
|
j.target_node = best_bed
|
||||||
else:
|
else:
|
||||||
j.label = "Sleep on the floor at %s" % target_tile
|
j.label = "Sleep on the floor at %s" % target_tile
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue