'It will relock behind you' means at your back (rules rev 4)
Both PICK LOCK and MASTER KEY promise the door relocks behind the walker — not that it stands unlocked for the turn. Passing through any door unlocked this turn now shuts it at once at the walker's back, unless a hand holds it open; the pick-and-peek stays (an unpassed door keeps its opening until turn's end), and holding via a targeted cast works as ever, displayed key included. The displayed key's own walk-through likewise leaves no lingering opening for bystanders — their peek needs a held door. Frozen behind rev 4 so stored games keep their turn-long openings. 18 ledgers verified; 277 tests. 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
64e4e243dc
commit
beb4947ad8
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { applyCommand, activePlayer, boardView, createGame, sustainedOn, type GameState } from "../src/game";
|
||||
import { cellKey, edgeKey, neighbor, type Side } from "../src/board";
|
||||
import { cellKey, edgeKey, neighbor, opposite, type Side } from "../src/board";
|
||||
import type { CardInstance } from "../src/cards";
|
||||
import { newGame, must, giveCard, toRound2, faceOff, castAt } from "./helpers";
|
||||
|
||||
@@ -111,7 +111,7 @@ describe("doors", () => {
|
||||
throw new Error("no door on this board");
|
||||
}
|
||||
|
||||
it("pick lock opens an adjacent door until end of turn", () => {
|
||||
it("pick lock opens an adjacent door — and it relocks behind the walker", () => {
|
||||
let { state } = newGame();
|
||||
const me = activePlayer(state);
|
||||
const door = findDoor(state);
|
||||
@@ -130,9 +130,8 @@ describe("doors", () => {
|
||||
state = must(state, me.id, { type: "move", direction: dir });
|
||||
expect(cellKey(activePlayer(state).position)).toBe(cellKey(other));
|
||||
|
||||
// Relocks when the turn ends.
|
||||
state = must(state, me.id, { type: "endTurn", draw: 0 });
|
||||
state = must(state, activePlayer(state).id, { type: "endTurn", draw: 0 });
|
||||
// "It will relock behind you": shut at the walker's back at once —
|
||||
// the way back is barred without another pick.
|
||||
expect(state.openDoorEdges.length).toBe(0);
|
||||
expect(applyCommand(state, me.id, { type: "move", direction: dir === "E" ? "W" : "N" }).ok).toBe(false);
|
||||
});
|
||||
@@ -539,7 +538,7 @@ describe("the displayed MASTER KEY", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("its bearer walks through locked doors, which relock behind them", () => {
|
||||
it("its bearer walks through locked doors, which relock at their back", () => {
|
||||
const { state, cell, side, key, keeper } = keyRig();
|
||||
const mk = giveCard(state, keeper.id, "master-key", "MK");
|
||||
keeper.displayed.push(mk.instanceId);
|
||||
@@ -548,9 +547,12 @@ describe("the displayed MASTER KEY", () => {
|
||||
if (r.ok) {
|
||||
const after = r.state.players.find((p) => p.id === keeper.id)!;
|
||||
expect(cellKey(after.position)).toBe(cellKey(neighbor(cell, side)));
|
||||
// Unlocked for the turn — the relock rides the usual end-of-turn sweep.
|
||||
expect(r.state.openDoorEdges).toContain(key);
|
||||
// "Door relocks behind you": no lingering opening for bystanders.
|
||||
expect(r.state.openDoorEdges).not.toContain(key);
|
||||
expect(r.events.some((e) => e.type === "doorUnlocked")).toBe(true);
|
||||
// The key turns again on the way back.
|
||||
const back = applyCommand(r.state, keeper.id, { type: "move", direction: opposite(side) });
|
||||
expect(back.ok).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user