Slow Death's draw is one blow, countered against its total (table ruling)
Two cards drawn is a two-point blow: ABSORB soaks up to three of the total, BLUNT halves it rounding up (so it finally earns a place — 2 becomes 1), counters may chain, declining takes the rest. The client labels each counter with the exact points it leaves; the bots weigh the total against their floor. Amends rev 13 minutes after it shipped; every production ledger still replays clean. 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
92613d7386
commit
8cfd911a3e
@@ -147,7 +147,7 @@ describe("slow death", () => {
|
||||
expect(sustainedOn(state, defender, "slow-death").length).toBe(1);
|
||||
});
|
||||
|
||||
it("an absorb in hand pauses the bites; each soaks one point (rev 13)", () => {
|
||||
it("the draw's bites land as one blow: an absorb soaks up to three (rev 13)", () => {
|
||||
let { state } = newGame();
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
@@ -159,31 +159,50 @@ describe("slow death", () => {
|
||||
state = must(state, defender, { type: "discard", instanceIds: toDiscard });
|
||||
giveCard(state, defender, "absorb", "AB", 0);
|
||||
state = must(state, defender, { type: "endTurn", draw: 2 });
|
||||
// Two bites hang; nobody else may act.
|
||||
// Two bites hang as one blow; nobody else may act.
|
||||
expect(state.slowDeathPending).toEqual({ playerId: defender, points: 2 });
|
||||
expect(applyCommand(state, attacker, { type: "endTurn", draw: 0 }).ok).toBe(false);
|
||||
// One absorb soaks one point; the other lands.
|
||||
state = must(state, defender, { type: "slowDeathChoice", absorbInstanceId: "absorb#AB" });
|
||||
// One absorb soaks the whole total (up to three).
|
||||
state = must(state, defender, { type: "slowDeathChoice", counterInstanceId: "absorb#AB" });
|
||||
expect(state.slowDeathPending).toBeNull();
|
||||
expect(state.players.find((p) => p.id === defender)!.life).toBe(14);
|
||||
expect(state.players.find((p) => p.id === defender)!.life).toBe(15);
|
||||
expect(state.players.find((p) => p.id === defender)!.hand.some((c) => c.cardId === "absorb")).toBe(false);
|
||||
});
|
||||
|
||||
it("without an absorb the bites land instantly, as in older decks", () => {
|
||||
let { state } = createGame({ playerIds: ["alice", "bob"], seed: 42, sets: ["basic"], deckRev: 12 });
|
||||
it("a blunt halves the blow's total, rounding up (rev 13)", () => {
|
||||
let { state } = newGame();
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const sd = giveCard(state, attacker, "slow-death");
|
||||
state = castAt(state, attacker, defender, sd);
|
||||
state = must(state, attacker, { type: "endTurn", draw: 0 });
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
giveCard(state, defender, "absorb", "AB", 0);
|
||||
const toDiscard = d.hand.filter((c) => c.cardId !== "absorb").slice(0, 2).map((c) => c.instanceId);
|
||||
const toDiscard = d.hand.slice(0, 2).map((c) => c.instanceId);
|
||||
state = must(state, defender, { type: "discard", instanceIds: toDiscard });
|
||||
giveCard(state, defender, "blunt", "BL", 0);
|
||||
state = must(state, defender, { type: "endTurn", draw: 2 });
|
||||
// Rev 12: even with an absorb in hand, the old decks bite instantly.
|
||||
expect(state.slowDeathPending ?? null).toBeNull();
|
||||
expect(state.slowDeathPending).toEqual({ playerId: defender, points: 2 });
|
||||
state = must(state, defender, { type: "slowDeathChoice", counterInstanceId: "blunt#BL" });
|
||||
// ceil(2 / 2) = 1 lands.
|
||||
expect(state.slowDeathPending).toBeNull();
|
||||
expect(state.players.find((p) => p.id === defender)!.life).toBe(14);
|
||||
});
|
||||
|
||||
it("declining the window takes the whole total", () => {
|
||||
let { state } = newGame();
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const sd = giveCard(state, attacker, "slow-death");
|
||||
state = castAt(state, attacker, defender, sd);
|
||||
state = must(state, attacker, { type: "endTurn", draw: 0 });
|
||||
const d = state.players.find((p) => p.id === defender)!;
|
||||
const toDiscard = d.hand.slice(0, 2).map((c) => c.instanceId);
|
||||
state = must(state, defender, { type: "discard", instanceIds: toDiscard });
|
||||
giveCard(state, defender, "absorb", "AB", 0);
|
||||
state = must(state, defender, { type: "endTurn", draw: 2 });
|
||||
state = must(state, defender, { type: "slowDeathChoice" });
|
||||
expect(state.players.find((p) => p.id === defender)!.life).toBe(13);
|
||||
expect(state.players.find((p) => p.id === defender)!.hand.some((c) => c.cardId === "absorb")).toBe(true);
|
||||
});
|
||||
|
||||
it("a reverse at the casting turns the curse: a point gained per draw (rev 11)", () => {
|
||||
|
||||
Reference in New Issue
Block a user