Warp sight honors "as though they were adjacent" — diagonals included
Playtesting caught the gap with a sticky wand: a target visible through the opening but one square off the corridor axis was refused. The colinear-only model was stricter than the rulebook, whose actual instruction is to treat the connected edges as adjacent boards with a straight center-to-center line — and a straight line through a one-cell opening may run diagonally, exactly as through a doorway. hasWarpLineOfSight now abuts the far side virtually at the mouth (rotating when the pairing turns a corner, as aisle warps do), finds where the center-to-center line crosses the rim, requires that crossing to fall strictly within the open mouth (corner-grazing stays blocked — the strict reading), and checks the two legs against real walls on each side of the seam. hasLineOfSight's core became a shared segmentClear to serve both legs. The colinear corridor cases remain as the special case they always were; a new test pins that off-axis squares are visible through mouths. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
53edf9734e
commit
8af8962330
@@ -236,3 +236,30 @@ describe("setup diagram pairings (rulebook Set-Up Diagram)", () => {
|
||||
expect(bent(r.state.board.warps).length).toBe(0); // "only opposite board edges connect"
|
||||
});
|
||||
});
|
||||
|
||||
describe("sight through warps treats the boards as adjacent", () => {
|
||||
const twoSector: SectorPlacement[] = [
|
||||
{ boardId: "board-a", origin: { x: 0, y: 0 }, rotation: 0 },
|
||||
{ boardId: "board-b", origin: { x: 0, y: 5 }, rotation: 0 },
|
||||
];
|
||||
|
||||
it("diagonal lines pass through the one-cell mouth like any doorway", () => {
|
||||
const board = assembleBoard(twoSector);
|
||||
// From SOME warp mouth, at least one square off the straight corridor
|
||||
// axis must be visible through the opening — the adjacency promise.
|
||||
let offAxis = 0;
|
||||
for (const w of board.warps) {
|
||||
const mouth = w.from.cell;
|
||||
const axisVertical = w.from.side === "N" || w.from.side === "S";
|
||||
for (const key of Object.keys(board.cells)) {
|
||||
const [x, y] = key.split(",").map(Number) as [number, number];
|
||||
const onAxis = axisVertical ? x === mouth.x : y === mouth.y;
|
||||
if (onAxis) continue;
|
||||
if (!hasLineOfSight(board, mouth, { x, y }) && sightBetween(board, mouth, { x, y })) {
|
||||
offAxis++;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect(offAxis).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user