Add MutablePlacement and rewire SearchBoard onto it #120

Closed
opened 2026-05-22 12:40:10 +00:00 by root · 7 comments
root commented 2026-05-22 12:40:10 +00:00 (Migrated from gitlab.core-project.space)

Imported from GitHub amaurycoudr/chess-project#120, opened by @amaurycoudr on 2026-05-22 12:40 UTC.
Closed on GitHub on 2026-05-23 06:28 UTC as completed.


Parent

#117

What to build

Add MutablePlacement — the mutable PieceReader implementation for the search hot path — and rewire SearchBoard onto it. Today SearchBoard holds two views of one record (#sets: PieceSets plus #board: Board aliasing it) and applies edits via a private #applyEdits. This slice replaces both fields with a single MutablePlacement that owns the sole applyEdits mutation primitive and maintains occupancy incrementally.

The two structurally-identical edit shapes — ApplyEdit (search-board.ts) and ZobristEdit (zobrist.ts) — collapse into one PieceEdit type owned by the placement module. snapshotBoard becomes Board.fromReader(mutablePlacement), copying out across the immutable boundary.

This is the heaviest slice; perft node counts being byte-identical is the correctness guard.

Acceptance criteria

  • MutablePlacement implements PieceReader, with applyEdits(edits: readonly PieceEdit[]) as the only mutation method
  • MutablePlacement maintains occupancy incrementally (no O(12) reduce per call); SquareSet instances stay immutable — only slot references and occupancy fields mutate
  • SearchBoard holds one MutablePlacement, replacing the #sets + #board pair; makeMove/unmakeMove go through applyEdits
  • SearchBoard.snapshotBoard() returns Board.fromReader(...)
  • ApplyEdit and ZobristEdit unified into a single PieceEdit; zobrist.updateZobristKey consumes it
  • applyEdits round-trip (apply then inverse) restores exact prior state; occupancy equals the recomputed union after any edit sequence — covered by tests
  • pnpm lint, pnpm typecheck, pnpm test, pnpm build all green; perft node counts byte-identical to before

Blocked by

> _Imported from GitHub [amaurycoudr/chess-project#120](https://github.com/amaurycoudr/chess-project/issues/120), opened by [@amaurycoudr](https://github.com/amaurycoudr) on 2026-05-22 12:40 UTC._ > _Closed on GitHub on 2026-05-23 06:28 UTC as completed._ <!-- github-issue:120 --> --- ## Parent #117 ## What to build Add `MutablePlacement` — the mutable `PieceReader` implementation for the search hot path — and rewire `SearchBoard` onto it. Today `SearchBoard` holds two views of one record (`#sets: PieceSets` plus `#board: Board` aliasing it) and applies edits via a private `#applyEdits`. This slice replaces both fields with a single `MutablePlacement` that owns the sole `applyEdits` mutation primitive and maintains occupancy incrementally. The two structurally-identical edit shapes — `ApplyEdit` (search-board.ts) and `ZobristEdit` (zobrist.ts) — collapse into one `PieceEdit` type owned by the placement module. `snapshotBoard` becomes `Board.fromReader(mutablePlacement)`, copying out across the immutable boundary. This is the heaviest slice; perft node counts being byte-identical is the correctness guard. ## Acceptance criteria - [ ] `MutablePlacement implements PieceReader`, with `applyEdits(edits: readonly PieceEdit[])` as the only mutation method - [ ] `MutablePlacement` maintains occupancy incrementally (no O(12) reduce per call); `SquareSet` instances stay immutable — only slot references and occupancy fields mutate - [ ] `SearchBoard` holds one `MutablePlacement`, replacing the `#sets` + `#board` pair; `makeMove`/`unmakeMove` go through `applyEdits` - [ ] `SearchBoard.snapshotBoard()` returns `Board.fromReader(...)` - [ ] `ApplyEdit` and `ZobristEdit` unified into a single `PieceEdit`; `zobrist.updateZobristKey` consumes it - [ ] `applyEdits` round-trip (apply then inverse) restores exact prior state; occupancy equals the recomputed union after any edit sequence — covered by tests - [ ] `pnpm lint`, `pnpm typecheck`, `pnpm test`, `pnpm build` all green; perft node counts byte-identical to before ## Blocked by - Blocked by #118, #119
root commented 2026-05-22 13:05:24 +00:00 (Migrated from gitlab.core-project.space)

Imported from a GitHub comment by @amaurycoudr on 2026-05-22 13:05 UTC.

Implemented by Sandcastle on branch sandcastle/sequential-reviewer/1779454410208 — awaiting review. SearchBoard now owns a single MutablePlacement (replacing the #sets + #board pair), with applyEdits as the sole mutation primitive and incrementally-maintained occupancy. ApplyEdit/ZobristEdit collapsed into a single PieceEdit owned by the placement module; snapshotBoard() copies out via Board.fromReader. All four gates green; perft node counts unchanged.

> _Imported from a [GitHub comment](https://github.com/amaurycoudr/chess-project/issues/120#issuecomment-4518904547) by [@amaurycoudr](https://github.com/amaurycoudr) on 2026-05-22 13:05 UTC._ <!-- github-comment:4518904547 --> Implemented by Sandcastle on branch `sandcastle/sequential-reviewer/1779454410208` — awaiting review. `SearchBoard` now owns a single `MutablePlacement` (replacing the `#sets` + `#board` pair), with `applyEdits` as the sole mutation primitive and incrementally-maintained occupancy. `ApplyEdit`/`ZobristEdit` collapsed into a single `PieceEdit` owned by the placement module; `snapshotBoard()` copies out via `Board.fromReader`. All four gates green; perft node counts unchanged.
root commented 2026-05-22 14:20:03 +00:00 (Migrated from gitlab.core-project.space)

Imported from a GitHub comment by @amaurycoudr on 2026-05-22 14:20 UTC.

Promoted to branch refactor/introduce-the-piecereader-read-port-118 (PR #122), not yet merged to main. A dependent slice should git fetch origin refactor/introduce-the-piecereader-read-port-118 and branch off it.

> _Imported from a [GitHub comment](https://github.com/amaurycoudr/chess-project/issues/120#issuecomment-4519525722) by [@amaurycoudr](https://github.com/amaurycoudr) on 2026-05-22 14:20 UTC._ <!-- github-comment:4519525722 --> Promoted to branch `refactor/introduce-the-piecereader-read-port-118` (PR #122), not yet merged to main. A dependent slice should `git fetch origin refactor/introduce-the-piecereader-read-port-118` and branch off it.
root (Migrated from gitlab.core-project.space) closed this issue 2026-05-23 06:28:33 +00:00
root commented 2026-10-13 08:38:44 +00:00 (Migrated from gitlab.core-project.space)

mentioned in issue #121

mentioned in issue #121
root commented 2026-10-13 10:18:45 +00:00 (Migrated from gitlab.core-project.space)

mentioned in commit f0389d7360

mentioned in commit f0389d73605048f5f5532cdc351a9266cf7f2a9d
root commented 2026-10-13 10:18:45 +00:00 (Migrated from gitlab.core-project.space)

mentioned in commit 81a871ba17

mentioned in commit 81a871ba176181e5cbb1c732a1b2cc39996b5794
root commented 2026-10-13 10:27:20 +00:00 (Migrated from gitlab.core-project.space)

mentioned in commit 6bd42d7f09

mentioned in commit 6bd42d7f0979d639f43fb1853627a0d9d8b15fc0
root commented 2026-10-13 10:27:20 +00:00 (Migrated from gitlab.core-project.space)

mentioned in commit a10f52db80

mentioned in commit a10f52db80364c88692e5f7fe5803c800569fd8d
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
amaurycoudr/chess-project#120
No description provided.