pgn2 1.4.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +34 -3
- data/.github/workflows/native.yml +32 -0
- data/.github/workflows/publish.yml +44 -2
- data/.github/workflows/release-gems.yml +40 -0
- data/.github/workflows/release.yml +52 -5
- data/.gitignore +9 -1
- data/.rubocop.yml +46 -6
- data/CHANGELOG.md +183 -1
- data/Gemfile +3 -0
- data/NOTICE.md +21 -0
- data/README.md +107 -5
- data/Rakefile +35 -10
- data/TODO.md +102 -31
- data/bench/baseline_moves.txt +38 -4
- data/bench/baseline_parse.txt +4 -4
- data/bench/cross_check.rb +61 -0
- data/bench/legal_moves.rb +38 -0
- data/bench/perft.rb +32 -0
- data/bench/profile_moves.rb +93 -0
- data/docs/superpowers/plans/2026-08-13-attack-masks-plan.md +51 -0
- data/docs/superpowers/plans/2026-08-13-perf-internals-plan.md +883 -0
- data/docs/superpowers/plans/2026-08-13-rust-bitboard-perft-plan.md +2442 -0
- data/docs/superpowers/plans/2026-08-14-chessie-migration.md +722 -0
- data/docs/superpowers/plans/2026-08-14-rust-integration-plan.md +444 -0
- data/docs/superpowers/specs/2026-08-13-attack-masks-design.md +57 -0
- data/docs/superpowers/specs/2026-08-13-perf-internals-design.md +111 -0
- data/docs/superpowers/specs/2026-08-13-rust-bitboard-perft-design.md +270 -0
- data/docs/superpowers/specs/2026-08-14-rust-integration-design.md +217 -0
- data/ext/pgn2_native/Cargo.lock +321 -0
- data/ext/pgn2_native/Cargo.toml +19 -0
- data/ext/pgn2_native/extconf.rb +8 -0
- data/ext/pgn2_native/pgn2-bitboard/Cargo.toml +10 -0
- data/ext/pgn2_native/pgn2-bitboard/src/board.rs +32 -0
- data/ext/pgn2_native/pgn2-bitboard/src/lib.rs +12 -0
- data/ext/pgn2_native/pgn2-bitboard/src/moves.rs +121 -0
- data/ext/pgn2_native/pgn2-bitboard/src/perft.rs +81 -0
- data/ext/pgn2_native/pgn2_native/Cargo.toml +11 -0
- data/ext/pgn2_native/pgn2_native/src/lib.rs +54 -0
- data/lib/pgn/bitboard.rb +13 -0
- data/lib/pgn/board.rb +103 -10
- data/lib/pgn/fen.rb +35 -46
- data/lib/pgn/game.rb +22 -13
- data/lib/pgn/lexer.rb +9 -6
- data/lib/pgn/move.rb +19 -15
- data/lib/pgn/move_calculator.rb +46 -20
- data/lib/pgn/notation.rb +24 -29
- data/lib/pgn/position.rb +60 -19
- data/lib/pgn/serializer.rb +13 -18
- data/lib/pgn/version.rb +1 -1
- data/lib/pgn/zobrist.rb +53 -0
- data/lib/pgn.rb +2 -0
- data/pgn2.gemspec +17 -10
- data/spec/bitboard_spec.rb +54 -0
- data/spec/board_spec.rb +53 -0
- data/spec/fen_spec.rb +65 -65
- data/spec/game_spec.rb +52 -15
- data/spec/lexer_spec.rb +5 -5
- data/spec/notation_spec.rb +5 -0
- data/spec/parser_spec.rb +8 -1
- data/spec/position_spec.rb +128 -27
- data/spec/serializer_spec.rb +4 -4
- data/spec/zobrist_spec.rb +46 -0
- metadata +101 -36
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Attack Masks + Retention Benchmark — Plan
|
|
2
|
+
|
|
3
|
+
TDD, inline execution. Commit per task. Honest benchmark reporting.
|
|
4
|
+
|
|
5
|
+
## Task 1 — `PGN::Board` attack-mask tables (TDD)
|
|
6
|
+
|
|
7
|
+
Add `KNIGHT_ATTACKS` / `KING_ATTACKS` frozen 128-entry Arrays to `Board`,
|
|
8
|
+
entry `idx` = frozen `Array` of on-board 0x88 targets from `idx`. Build
|
|
9
|
+
from `Notation::KNIGHT_OFFS`/`KING_OFFS`, filtering `(t & 0x88).zero?`.
|
|
10
|
+
|
|
11
|
+
Spec (`spec/board_spec.rb`): mask entries equal the on-board squares the
|
|
12
|
+
offsets reach; corner squares have 2 knight / 3 king targets; centre e4
|
|
13
|
+
(0x54) has 8 knight / 8 king. E.g. `KNIGHT_ATTACKS[0] == [33, 18]`,
|
|
14
|
+
`KING_ATTACKS[0] == [1, 16, 17]`, `KNIGHT_ATTACKS[0x54].length == 8`.
|
|
15
|
+
|
|
16
|
+
## Task 2 — `Notation` uses the masks
|
|
17
|
+
|
|
18
|
+
`reaches?` N/K → `Board::KNIGHT_ATTACKS[from].include?(to)` /
|
|
19
|
+
`KING_ATTACKS`. `knight_attacked?`/`king_attacked?` → iterate the mask.
|
|
20
|
+
`leaper_moves?` N/K → iterate the mask (pass mask instead of `OFFS`).
|
|
21
|
+
|
|
22
|
+
Spec: existing `notation_spec` + round-trip stay green (byte-identical
|
|
23
|
+
SAN). Add a focused test: a knight on e4 reaches d6/f6/etc.; a king on e1
|
|
24
|
+
reaches d1/d2/e2/f2/f1.
|
|
25
|
+
|
|
26
|
+
## Task 3 — `MoveCalculator` K/N origins via the mask
|
|
27
|
+
|
|
28
|
+
Add `leaper_origins(mask)` iterating pre-filtered on-board targets;
|
|
29
|
+
`compute_origin` K/N branch calls
|
|
30
|
+
`leaper_origins(Board::KNIGHT_ATTACKS[dest_idx] ...)`; pawn path keeps
|
|
31
|
+
`move_origins(offsets)`.
|
|
32
|
+
|
|
33
|
+
Spec: existing `move_calculator_spec` + full round-trip stay green.
|
|
34
|
+
|
|
35
|
+
## Task 4 — SAN-generation benchmark section
|
|
36
|
+
|
|
37
|
+
Add `bench/profile_moves.rb` section 8: reconstruct `Notation.san` for
|
|
38
|
+
every move of the immortal game from coordinate from/to (precomputed
|
|
39
|
+
once), allocation + throughput. Regenerate baseline; report whether the
|
|
40
|
+
mask change moved the SAN and replay (section 1/4) needles.
|
|
41
|
+
|
|
42
|
+
## Task 5 — Retained-memory benchmark section
|
|
43
|
+
|
|
44
|
+
Add section 9: `MemoryProfiler` **retained** objects/memsize for
|
|
45
|
+
last-position-only, lazy (`each_position`) vs eager (`positions`). Fresh
|
|
46
|
+
`PGN::Game` per path. Regenerate baseline.
|
|
47
|
+
|
|
48
|
+
## Task 6 — Final verification + CHANGELOG/README
|
|
49
|
+
|
|
50
|
+
Full suite, RuboCop (no new offenses on touched files), `rake bench`,
|
|
51
|
+
CHANGELOG + README update.
|