v0.4.8 — the Limits bound the whole district, the nine spots really are nine, and an action points at its square
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YQAJ4dND7enLj54eLyiF2C
This commit is contained in:
@@ -313,5 +313,35 @@ function placementCandidates(s: GameState, player: PlayerIndex): GridCoord[] {
|
||||
out.push(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* THE NINE-SPOT MODIFIER NEIGHBOURHOOD (§9), which the four-square walk above cannot reach.
|
||||
*
|
||||
* A Modifier goes "adjacent to a Facility, on any of the nine nearby spots" — diagonals included —
|
||||
* and `check` has always accepted all eight. It was the CANDIDATES that were orthogonal-only, so a
|
||||
* diagonal square with no orthogonal neighbour was legal and never offered: reported by Jesse as
|
||||
* being unable to place a Modifier to the south-east of his industry.
|
||||
*
|
||||
* Only around a Facility, and only in a second pass. Track has to JOIN, and a diagonal shares no
|
||||
* edge, so a Modifier is the only card these squares can ever take — generating diagonals around
|
||||
* every card instead costs 54% more simulation time for candidates `check` then rejects. Appending
|
||||
* rather than interleaving leaves the existing order untouched, which matters because the bot
|
||||
* breaks ties by first-best: measured over 200 seeded games, 0 played differently.
|
||||
*/
|
||||
for (const [key, card] of area.grid) {
|
||||
if (!card.facility) continue;
|
||||
const [row, col] = key.split(',').map(Number);
|
||||
for (const c of [
|
||||
{ row: row! + 1, col: col! + 1 },
|
||||
{ row: row! + 1, col: col! - 1 },
|
||||
{ row: row! - 1, col: col! + 1 },
|
||||
{ row: row! - 1, col: col! - 1 },
|
||||
]) {
|
||||
const k = `${c.row},${c.col}`;
|
||||
if (seen.has(k) || area.grid.has(k)) continue;
|
||||
seen.add(k);
|
||||
out.push(c);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user