The client's eye learns the VISIONSTONE
The engine always honored the stone — its bearer casts through exactly one wall or door — but the targeting shadow never did: sightedCellsFor kept every square behind a wall dimmed, so the aid told the bearer the stone wasn't working. The sighted set now retries each unseen square with a single edge removed, mirroring casterLos; the automaton shares the function, so bots see through their stones too. Two tests pin the engine ruling and the client parity. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
This commit is contained in:
co-authored by
Claude Fable 5
parent
b16bbe82a6
commit
7adf4b6cd6
@@ -200,6 +200,26 @@ export function sightedCellsFor(view: GameView): Set<string> {
|
||||
const [x, y] = key.split(",").map(Number) as [number, number];
|
||||
if (sightBetween(board, me.position, { x, y }, blockers)) out.add(key);
|
||||
}
|
||||
// VISIONSTONE lets its bearer see through exactly one wall or door —
|
||||
// any one — so a square is also sighted if removing a single edge
|
||||
// reveals it, mirroring the engine's casterLos.
|
||||
if (me.displayed.some((c) => c.cardId === "visionstone")) {
|
||||
const unseen = Object.keys(board.cells).filter((k) => !out.has(k));
|
||||
for (const edgeK of Object.keys(board.edges)) {
|
||||
if (unseen.length === 0) break;
|
||||
if ((board.edges[edgeK] ?? "open") === "open") continue;
|
||||
const edges = { ...board.edges };
|
||||
delete edges[edgeK];
|
||||
const opened = { ...board, edges };
|
||||
for (let i = unseen.length - 1; i >= 0; i--) {
|
||||
const [x, y] = unseen[i]!.split(",").map(Number) as [number, number];
|
||||
if (sightBetween(opened, me.position, { x, y }, blockers)) {
|
||||
out.add(unseen[i]!);
|
||||
unseen.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user