Implements three high-impact improvements from NCS-43:
1. Incremental L1 accumulator — L1 pre-activations are maintained
per-ply on a stack and updated by column-add/subtract when pieces
move, reducing L1 cost from O(768×1536) to O(pieces×1536) for root
init and O(changed_pieces×1536) per node. Column-major weight
transposition (l1WeightsT) makes each update sequential in memory.
2. Eval cache — a 256 K direct-mapped cache keyed by Zobrist hash
skips the L2-L5 forward pass for positions seen during quiescence,
where the same position often recurs across capture sequences.
3. Dynamic time allocation — NNUEBot now grants 1 500 ms in complex
positions (> 30 legal moves) and 500 ms in nearly-terminal ones
(< 5 moves), instead of a fixed 1 000 ms budget.
Accumulator hooks (initAccumulator, pushAccumulator, copyAccumulator,
evaluateAccumulator) are added to the Evaluation trait with no-op
defaults, so ClassicalBot and HybridBot are unaffected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
## Summary
- Adds `docs/api-spec.yaml` — a full OpenAPI 3.0.3 specification for the NowChess REST API
- Endpoint paths follow the lichess `board/bot` split convention (`/api/board/game/...`)
to leave room for a future bot API under `/api/bot/game/...`
- Covers game lifecycle, move-making, draw handling, undo/redo,
legal move introspection, and FEN/PGN import/export
## Endpoints
- Game: POST /api/board/game, GET /{gameId}, GET /{gameId}/stream, POST /{gameId}/resign
- Move: POST /{gameId}/move/{uci}, GET /{gameId}/moves, POST /{gameId}/undo, POST /{gameId}/redo
- Draw: POST /{gameId}/draw/{action}
- Import: POST /import/fen, POST /import/pgn
- Export: GET /{gameId}/export/fen, GET /{gameId}/export/pgn
## Test plan
- [ ] Open docs/api-spec.yaml in Swagger Editor (https://editor.swagger.io) — zero validation errors expected
- [ ] Verify every endpoint maps to an existing GameEngine or RuleSet method
Co-authored-by: LQ63 <lkhermann@web.de>
Reviewed-on: #25
Reviewed-by: Janis <janis-e@gmx.de>
Co-authored-by: Leon Hermann <lq@blackhole.local>
Co-committed-by: Leon Hermann <lq@blackhole.local>
Summary
- Added fastparse_3:3.0.2 dependency to modules/io
- Implemented FenParserFastParse as a second alternative FEN parser using FastParse, with the same public API as
FenParser and FenParserCombinators
- Parsers are built bottom-up using (using P[Any]) Scala 3 syntax with NoWhitespace.* to prevent implicit whitespace
skipping; rank sum validation uses Pass/Fail inside .flatMap
- Added FenParserFastParseTest mirroring FenParserCombinatorsTest to prove behavioural equivalence across all three
implementations
Test plan
- All existing tests pass — FenParser, FenParserCombinators, and all other modules untouched
- FenParserFastParseTest covers all cases: valid FEN, invalid color, invalid castling, invalid board shapes, en
passant, rank overflow, round-trip via FenExporter
- All parser logic branches genuinely covered — known scoverage gap documented in docs/unresolved.md (FastParse inline
macro generates synthetic proxy methods that scoverage instruments but that never execute at runtime)
Co-authored-by: LQ63 <lkhermann@web.de>
Reviewed-on: #22
Reviewed-by: Janis <janis-e@gmx.de>
Co-authored-by: Leon Hermann <lq@blackhole.local>
Co-committed-by: Leon Hermann <lq@blackhole.local>