Rev 21: collapsing walls crush anyone — monsters included

DESTROY WALL's "anyone in either square next to the wall takes 4
points" swept only wizards; a troll leaned on the falling masonry
untouched. The expansion sheet is explicit — "if a card specifies
'Opponent' or 'Anyone' as a target, this includes Monsters" — so the
collapse now crushes creatures in both squares, at the rim breach's
far side too. Earlier ledgers keep their charmed monsters.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-08-17 17:47:14 -04:00
co-authored by Claude Fable 5
parent 6380fae134
commit 7df58d29fa
4 changed files with 61 additions and 2 deletions
+43
View File
@@ -640,3 +640,46 @@ describe("a mid-round democratic monster claws on the next turn (rules rev 18)",
expect(r.state.stack?.creatureId ?? null).toBe(fresh.id);
});
});
describe("collapsing walls crush monsters too (rules rev 21)", () => {
function wallRig(deckRev: number) {
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic", "expansion1"], deckRev });
state = toRound2(state);
const view = boardView(state);
for (const [key, edge] of Object.entries(view.edges)) {
if (edge !== "wall") continue;
const [kind, coords] = key.split(":") as [string, string];
const [x, y] = coords.split(",").map(Number) as [number, number];
const side = kind === "V" ? ("E" as Side) : ("S" as Side);
const other = { x: x + (side === "E" ? 1 : 0), y: y + (side === "S" ? 1 : 0) };
if (!view.cells[cellKey(other)]) continue;
const caster = activePlayer(state);
caster.position = { x, y };
state.creatures.push({
id: "tr1", kind: "troll", controllerId: caster.id,
position: { ...other }, damage: 0, maxDamage: 6, movesPerTurn: 3,
movementUsed: 0, attackUsed: false, justCreated: false,
wallPassesPerTurn: 0, wallPassUsed: 0, scorchedThisTurn: [],
});
const dw = giveCard(state, caster.id, "destroy-wall");
const r = applyCommand(state, caster.id, {
type: "cast", instanceId: dw.instanceId, target: { kind: "edge", cell: { x, y }, side },
});
if (!r.ok) throw new Error(r.error);
return r.state;
}
throw new Error("setup: no interior wall found");
}
it("rev 21: the adjacent troll takes the four points", () => {
const state = wallRig(21);
const troll = state.creatures.find((c) => c.id === "tr1");
// Four points on a six-point troll: hurt but standing (or regenerating).
expect(troll?.damage).toBe(4);
});
it("earlier revisions leave the troll dusty but unharmed", () => {
const state = wallRig(20);
expect(state.creatures.find((c) => c.id === "tr1")!.damage).toBe(0);
});
});