This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
make install # Build with native CPU opts + install (default target)
make build # Release build only
make dev # Fast dev build (unoptimized)
make test # Run all tests (cargo test)
make bench # Run benchmarks (cargo bench)
make lint # cargo fmt --check + cargo clippy -- -D warnings
make pre-commit # lint + testRun a single test: cargo test alpha_beta_searcher::tests::test_alpha_beta_finds_winning_move
Run a test module: cargo test board::tests::
Run with output: cargo test -- --nocapture
Build with instrumentation: cargo build --release --features instrumentation
Three-layer design separating generic search from chess-specific logic:
-
alpha_beta_searcher/β Game-agnostic alpha-beta search with iterative deepening, aspiration windows, quiescence search, transposition table (DashMap-backed with depth-preferred replacement), and killer moves (thread-local). Pruning: null move pruning, reverse futility pruning, futility pruning, late move reductions (logarithmic). Extensions: check extensions. Defines traits intraits.rs:GameState,GameMove,MoveGenerator,Evaluator,MoveOrderer. Tests use a Nim game implementation to validate the algorithm independently of chess. -
chess_search/β Implements the generic search traits for chess.implementation.rsbridges the search algorithm to chess types.move_orderer.rshandles PV moves, MVV-LVA capture ordering, killer moves, history heuristic, and incremental move selection (pick-best). -
board/+move_generator/β Board state with bitboard representation,StateStackfor undo (apply/undo pattern avoids cloning during search), and magic bitboard move generation.chess_move/has an enum with variants: Standard, Castle, EnPassant, PawnPromotion, each implementingChessMoveEffect.
precompile/β Build script (build = "precompile/src/main.rs") generates Zobrist hash tables, magic bitboard lookup tables, and opening book at compile timecommon/βBitboard(u64 wrapper) andSquare(u8 newtype) shared between engine and precompilergame/β Game loop withInputSource/GameRenderertrait abstractions for I/O modularityuci/β UCI protocol state machine for GUI integrationtui/β ratatui-based terminal UI, colors customizable viatui_colors.tomlevaluate/β Tapered evaluation with material, piece-square tables (separate MG/EG for all piece types), pawn structure (passed/doubled/isolated/backward/connected), piece activity (bishop pair, knight outposts, rook on open files/7th rank), king safety (pawn shield, open file penalty, knight attack units), and piece mobility (knights + bishops via magic bitboards). UsesLazyLock<Targets>singleton for standalone eval; during search, sharesMoveGenerator::targets()to avoid duplicate allocation.cli/β StructOpt subcommands (play, watch, pvp, uci, calculate-best-move, count-positions, benchmark-alpha-beta, determine-stockfish-elo, solve-puzzles)
- Parallel search at root level only, using Rayon. Conditional cloning (only when parallelizing with 10+ moves).
SmallVec<[ChessMove; 32]>for move lists to avoid heap allocation in typical positions.chess_position!macro for creating board state from ASCII art in tests.prelude.rsre-exports common types:Board,Color,Piece,ChessMove,Bitboard,Square.
- Import order (enforced by pre-commit hook): std β external crates β
crate::βsuper::/self::, separated by blank lines, alphabetically sorted within groups - Module structure:
mod.rsfiles contain only declarations/re-exports, no implementation - Module docstrings:
//!comment required at top of all module and implementation files - Max line width: 100 characters
- Edition: 2018
- Pre-commit hook runs
cargo fmt -- --checkandcargo clippy -- -D warnings
Always use release builds for performance measurement. Quick feedback loop:
cargo test && chess count-positions --depth 5 | tail -n 1Use depth 4-5 for iteration; depth 6+ for final validation only. Position counts must match exactly after optimization changes (correctness check).
Puzzle solve rates measure eval quality (not latency):
chess solve-puzzles # all tiers
chess solve-puzzles --tier 1 # tactical only (depth 6, fast)
chess solve-puzzles --tier 2 # BK strategic (depth 10)
chess solve-puzzles --tier 3 # deep positional (depth 12, slow)