A test walks a wizard into a slime with a spell waiting in it
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
c09bcc481d
commit
16fac5e6ca
@@ -3,7 +3,7 @@ import { applyCommand, activePlayer, boardView, createGame, gameLos, type GameSt
|
|||||||
import { cellKey, edgeKey, neighbor, opposite, SIDES, stepTarget, type Cell, type Side } from "../src/board";
|
import { cellKey, edgeKey, neighbor, opposite, SIDES, stepTarget, type Cell, type Side } from "../src/board";
|
||||||
import type { CardInstance } from "../src/cards";
|
import type { CardInstance } from "../src/cards";
|
||||||
import { eligibleCellsFor, sightedCellsFor, viewFor } from "../src/view";
|
import { eligibleCellsFor, sightedCellsFor, viewFor } from "../src/view";
|
||||||
import { newExpansionGame as newGame, must, giveCard, emptyNeighborCell, plainRimWall } from "./helpers";
|
import { newExpansionGame as newGame, must, giveCard, emptyNeighborCell, plainRimWall, toRound2 } from "./helpers";
|
||||||
|
|
||||||
/** The sides a walker may leave a pit by, having entered it heading `entry`. */
|
/** The sides a walker may leave a pit by, having entered it heading `entry`. */
|
||||||
function rimExits(state: GameState, pit: Cell, entry: Side): Side[] {
|
function rimExits(state: GameState, pit: Cell, entry: Side): Side[] {
|
||||||
@@ -675,3 +675,34 @@ describe("a wave names its victims before it pushes (LK97)", () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("spells cast at a slime wait in the gel", () => {
|
||||||
|
it("a lightning blast lodges in the slime and goes off on the next wizard in, once", () => {
|
||||||
|
let { state } = newGame(42);
|
||||||
|
state = toRound2(state);
|
||||||
|
const caster = activePlayer(state);
|
||||||
|
const victim = state.players.find((p) => p.id !== caster.id)!;
|
||||||
|
const spot = emptyNeighborCell(state, caster.position);
|
||||||
|
state.squareContents[cellKey(spot.cell)] = { kind: "slime", damage: 0, createdBy: caster.id };
|
||||||
|
const bolt = giveCard(state, caster.id, "lightning-blast");
|
||||||
|
const cast = applyCommand(state, caster.id, { type: "cast", instanceId: bolt.instanceId, target: { kind: "cell", cell: spot.cell } });
|
||||||
|
expect(cast.ok).toBe(true);
|
||||||
|
if (!cast.ok) return;
|
||||||
|
expect(cast.events.some((e) => e.type === "spellTrapped")).toBe(true);
|
||||||
|
expect(cast.state.slimeTraps[cellKey(spot.cell)]?.length).toBe(1);
|
||||||
|
// Nobody is hurt yet; the victim walks in on their own turn.
|
||||||
|
state = must(cast.state, caster.id, { type: "endTurn", draw: 2 });
|
||||||
|
victim.position = { ...caster.position };
|
||||||
|
const v = state.players.find((p) => p.id === victim.id)!;
|
||||||
|
v.position = { ...caster.position };
|
||||||
|
const walk = applyCommand(state, victim.id, { type: "move", direction: spot.side });
|
||||||
|
expect(walk.ok).toBe(true);
|
||||||
|
if (!walk.ok) return;
|
||||||
|
expect(walk.events.some((e) => e.type === "slimeTrapSprung")).toBe(true);
|
||||||
|
expect(walk.state.stack?.defenderId).toBe(victim.id);
|
||||||
|
expect(walk.state.stack?.trapped).toBe(true);
|
||||||
|
const hit = must(walk.state, victim.id, { type: "pass" });
|
||||||
|
expect(hit.players.find((p) => p.id === victim.id)!.life).toBeLessThan(15);
|
||||||
|
expect(hit.slimeTraps[cellKey(spot.cell)]).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user