The fallen drop what they carry, however they fall (rev 30)

A wizard eliminated by treasuresLost took any carried treasure into the
void with them — the killed path drops it, but checkVictory's branch
never did. At rev 30 the treasure lands where they stood, with the
usual treasureDropped event (onHomeOf included, so a capture completed
by the falling is honored in the same breath). Stored games replay the
vanishing unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0138A8CjeQRpvzKxuMfz1Bqc
This commit is contained in:
Eric Wagoner
2026-08-19 12:25:41 -04:00
co-authored by Claude Fable 5
parent f1743e6fe5
commit 62c4680d1f
4 changed files with 56 additions and 2 deletions
+38
View File
@@ -224,3 +224,41 @@ describe("treasures and victory", () => {
expect(result.ok).toBe(false);
});
});
describe("elimination by lost treasures drops what the fallen carried (rev 30)", () => {
it("the carried treasure lands where the wizard stood", () => {
let { state } = createGame({ playerIds: ["a", "b", "c"], seed: 42, sets: ["basic"], deckRev: 30 });
const A = state.players.find((p) => p.id === "a")!;
const B = state.players.find((p) => p.id === "b")!;
const C = state.players.find((p) => p.id === "c")!;
// C's first treasure already sits captured on B's home...
const c1 = state.treasures.filter((t) => t.owner === "c")[0]!;
c1.position = { ...B.home };
// ...C carries one of B's treasures...
const bt = state.treasures.filter((t) => t.owner === "b")[0]!;
bt.position = null;
bt.carriedBy = "c";
C.carriedTreasureId = bt.id;
// ...and A, standing on their own home, drops C's second treasure there.
const c2 = state.treasures.filter((t) => t.owner === "c")[1]!;
c2.position = null;
c2.carriedBy = "a";
A.carriedTreasureId = c2.id;
A.position = { ...A.home };
while (state.players[state.turn.activeIndex]!.id !== "a") {
const r = applyCommand(state, state.players[state.turn.activeIndex]!.id, { type: "endTurn", draw: 0 });
if (!r.ok) throw new Error(r.error);
state = r.state;
}
const r = applyCommand(state, "a", { type: "dropTreasure" });
if (!r.ok) throw new Error(r.error);
state = r.state;
// C is eliminated by lost treasures — and B's treasure lies where C stood.
const cAfter = state.players.find((p) => p.id === "c")!;
expect(cAfter.alive).toBe(false);
expect(cAfter.carriedTreasureId).toBeNull();
const btAfter = state.treasures.find((t) => t.id === bt.id)!;
expect(btAfter.carriedBy).toBeNull();
expect(btAfter.position).toEqual(cAfter.position);
});
});