Credibility pass: the illusion tests roll both ways, and the seams from the last batch are sanded
Scope: 66b5c06..HEAD. - The rev-27 illusion tests search seeds for a believed and a doubted roll and assert fixed life totals; seed 42 alone never believed, so the BLUNT pricing went unchecked. - Three docblocks stranded above newly inserted functions are back on their own (openCreatureStack, resolvedBlow, castTrace). - POWER ATTACK's life trade is one helper instead of three copies; the goat's charge distance is one helper for its validator, its ram and its pricing. - The family list loads once into a shared store; the lobby and gallery share one talk filter; Board uses the engine's neighbor(). - A creature's blow shows the card that summoned it by the creature's kind, not by matching the blow's display name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
e97deb8d6f
commit
3a6b0ff43e
@@ -931,8 +931,8 @@ describe("the imp's fire is a spell (rev 8)", () => {
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
state = r.state;
|
||||
if (!state.stack) state = must(state, "imp-owner", { type: "endTurn", draw: 0 });
|
||||
// The scorch rides the stack now: a counteraction window, spell-kind,
|
||||
// named for the imp so the counter is played against the scorch, never a punch.
|
||||
// The scorch rides the stack as a spell-kind counteraction window,
|
||||
// named for the imp: the counter is played against the scorch.
|
||||
expect(state.stack?.creatureId).toBeTruthy();
|
||||
expect(state.stack?.kind).toBe("spell");
|
||||
expect(state.stack?.sourceName).toBe("fire imp's scorch");
|
||||
|
||||
@@ -942,8 +942,8 @@ describe("the goat's ram is a physical blow like any other (rev 26)", () => {
|
||||
|
||||
describe("an illusion is priced as the spell it fakes (rev 27)", () => {
|
||||
/** A faked FIREBALL met by the given counteraction, then both wizards pass. */
|
||||
function fakedFireball(counter: string | null, deckRev?: number) {
|
||||
let { state } = createGame({ playerIds: ["liar", "mark"], seed: 42, sets: ["basic", "expansion1"], ...(deckRev ? { deckRev } : {}) });
|
||||
function fakedFireball(counter: string | null, deckRev?: number, seed = 42) {
|
||||
let { state } = createGame({ playerIds: ["liar", "mark"], seed, sets: ["basic", "expansion1"], ...(deckRev ? { deckRev } : {}) });
|
||||
state = toRound2(state);
|
||||
const { attacker, defender } = faceOff(state);
|
||||
const ill = giveCard(state, attacker, "illusionary-attack");
|
||||
@@ -965,11 +965,22 @@ describe("an illusion is priced as the spell it fakes (rev 27)", () => {
|
||||
return { events: done.events, believed, life: done.state.players.find((p) => p.id === defender)!.life };
|
||||
}
|
||||
|
||||
/** The first seed whose die comes up each way: one believed, one disbelieved. */
|
||||
function bothWays(counter: string | null, deckRev?: number) {
|
||||
const found: Partial<Record<"believed" | "doubted", ReturnType<typeof fakedFireball>>> = {};
|
||||
for (let seed = 1; seed <= 40 && !(found.believed && found.doubted); seed++) {
|
||||
const r = fakedFireball(counter, deckRev, seed);
|
||||
expect(r.believed).not.toBeNull();
|
||||
found[r.believed ? "believed" : "doubted"] ??= r;
|
||||
}
|
||||
return { believed: found.believed!, doubted: found.doubted! };
|
||||
}
|
||||
|
||||
it("BLUNT halves a believed fake fireball to three, and disbelief costs nothing", () => {
|
||||
const { events, believed, life } = fakedFireball("blunt");
|
||||
expect(believed).not.toBeNull();
|
||||
expect(events).toContainEqual(expect.objectContaining({ type: "attackResolved", incoming: 5 }));
|
||||
expect(life).toBe(believed ? 12 : 15);
|
||||
const { believed, doubted } = bothWays("blunt");
|
||||
expect(believed.events).toContainEqual(expect.objectContaining({ type: "attackResolved", incoming: 5 }));
|
||||
expect(believed.life).toBe(12);
|
||||
expect(doubted.life).toBe(15);
|
||||
});
|
||||
|
||||
it("FULL SHIELD stops the fake outright: nothing to believe in, no die rolled", () => {
|
||||
@@ -980,14 +991,10 @@ describe("an illusion is priced as the spell it fakes (rev 27)", () => {
|
||||
});
|
||||
|
||||
it("uncountered, a believed fake fireball still does its five", () => {
|
||||
const { believed, life } = fakedFireball(null);
|
||||
expect(believed).not.toBeNull();
|
||||
expect(life).toBe(believed ? 10 : 15);
|
||||
expect(bothWays(null).believed.life).toBe(10);
|
||||
});
|
||||
|
||||
it("older games dealt a believed illusion's full points past a BLUNT", () => {
|
||||
const { believed, life } = fakedFireball("blunt", 26);
|
||||
expect(believed).not.toBeNull();
|
||||
expect(life).toBe(believed ? 10 : 15);
|
||||
expect(bothWays("blunt", 26).believed.life).toBe(10);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user