Rev 16: BUTT-HEAD's charge is measured as far as its legs reach (K4T3)
Reuben, a goat with a 5 played and eight legs, aimed at a wizard eight corridor steps away and was told he had no wings. The charge measures the walk through real corridors, as rev 10 made it, but the walk was searched only six steps deep and anything past that came back as unreachable. From rev 16 the search runs as far as the legs do; older games keep the six-step reading. A test charges seven or eight steps under both revisions. 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
0911312f98
commit
3b52a92cdc
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { applyCommand, activePlayer, boardView, createGame, gameLos, sustainedOn } from "../src/game";
|
||||
import { cellKey, edgeKey, stepTarget } from "../src/board";
|
||||
import { applyCommand, activePlayer, boardView, createGame, gameLos, sustainedOn, walkingDistance, type GameState } from "../src/game";
|
||||
import { cellKey, edgeKey, stepTarget, type Cell } from "../src/board";
|
||||
import type { CardInstance } from "../src/cards";
|
||||
import { newExpansionGame as newGame, must, drain, giveCard, toRound2, faceOff, castAt } from "./helpers";
|
||||
|
||||
@@ -812,3 +812,34 @@ describe("the goat charges on legs, not wings (rev 10)", () => {
|
||||
expect(rams).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("butt-head's charge reaches as far as its legs (K4T3)", () => {
|
||||
/** Two empty cells seven or eight corridor steps apart on the seed-42 board. */
|
||||
function longRun(state: GameState): { from: Cell; to: Cell; steps: number } {
|
||||
const view = boardView(state);
|
||||
const cells = Object.keys(view.cells).map((k) => { const [x, y] = k.split(",").map(Number) as [number, number]; return { x, y }; })
|
||||
.filter((c) => !state.squareContents[cellKey(c)] && !view.homes.some((h) => cellKey(h) === cellKey(c)));
|
||||
for (const from of cells) for (const to of cells) {
|
||||
const d = walkingDistance(state, from, to, 12);
|
||||
if (d === 7 || d === 8) return { from, to, steps: d };
|
||||
}
|
||||
throw new Error("no seven-step corridor on this board");
|
||||
}
|
||||
for (const [deckRev, ok] of [[16, true], [15, false]] as const) {
|
||||
it(`a goat with eight legs and a target seven or eight corridor steps off: rev ${deckRev} ${ok ? "charges" : "refuses"}`, () => {
|
||||
let { state } = createGame({ playerIds: ["goat", "mark"], seed: 42, sets: ["basic", "expansion1"], deckRev });
|
||||
state = toRound2(state);
|
||||
const goat = activePlayer(state);
|
||||
const mark = state.players.find((p) => p.id !== goat.id)!;
|
||||
const run = longRun(state);
|
||||
goat.position = { ...run.from };
|
||||
mark.position = { ...run.to };
|
||||
state.turn.movementAllowance = 8;
|
||||
state.turn.movementUsed = 0;
|
||||
const card = giveCard(state, goat.id, "butt-head");
|
||||
const r = applyCommand(state, goat.id, { type: "cast", instanceId: card.instanceId, target: { kind: "player", playerId: mark.id } });
|
||||
expect(r.ok).toBe(ok);
|
||||
if (!r.ok) expect(r.error).toMatch(/legs, not wings/);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user