The dimming aid stops lying about boobytrap, glue, and safe

Three cards sat wrongly in the creation bucket of eligibleCellsFor,
so the targeting dim demanded sighted empty squares the engine never
asks for. Boobytrap tokens go anywhere on the board but solid stone —
no sight required; a trap you can see coming is a poor trap. Glue and
the safe were worse than restricted: inverted. Both seize a square
that HOLDS a loose object or treasure, exactly the squares the empty-
square rule dimmed out. Each now has its own branch mirroring the
engine's actual checks, pinned by tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-08-16 19:31:57 -04:00
co-authored by Claude Fable 5
parent 1275ac9287
commit ac53773fe4
2 changed files with 56 additions and 1 deletions
+24 -1
View File
@@ -185,7 +185,7 @@ export function sightedCellsFor(view: GameView): Set<string> {
const CREATION_CARD_IDS = new Set([
"fill-square-with-stone", "thornbush", "killer-ooze", "rosebush", "dust-cloud",
"fill-square-with-slime", "create-pit", "handful-of-tacks", "glue", "safe", "boobytrap",
"fill-square-with-slime", "create-pit", "handful-of-tacks",
]);
const SUMMON_CARD_IDS = new Set([
"troll", "skeleton", "wraith", "fire-imp", "democratic-monster", "shadow",
@@ -256,6 +256,29 @@ export function eligibleCellsFor(view: GameView, cardId: string): Set<string> |
return out;
}
if (cardId === "boobytrap") {
// Tokens go anywhere on the board except solid stone — no sight needed;
// a trap you can see coming is a poor trap.
return new Set(cells.filter((k) => view.squareContents[k]?.kind !== "stone"));
}
if (cardId === "glue" || cardId === "safe") {
// Both seize a square that HOLDS something — a loose object or an
// unclaimed treasure — within the caster's sight. The safe additionally
// needs the square clear of terrain to build around its prize.
const out = new Set<string>();
for (const k of cells) {
if (cardId === "safe" && view.squareContents[k]) continue;
const hasObject =
(view.groundObjects[k] ?? []).length > 0 ||
view.treasures.some((t) => t.position && !t.carriedBy && key(t.position.x, t.position.y) === k);
if (!hasObject) continue;
if (!sighted.has(k)) continue;
out.add(k);
}
return out;
}
if (cardId === "stone-to-water") {
return new Set(cells.filter((k) => view.squareContents[k]?.kind === "stone"));
}