# rust-chess
[](https://github.com/RumenDamyanov/rust-chess/actions/workflows/ci.yml)
[](https://github.com/RumenDamyanov/rust-chess/actions/workflows/github-code-scanning/codeql)
[](https://github.com/RumenDamyanov/rust-chess/actions/workflows/dependabot/dependabot-updates)
[](https://codecov.io/gh/RumenDamyanov/rust-chess)
[](https://github.com/RumenDamyanov/rust-chess/blob/master/LICENSE.md)
> ๐ **Documentation**: [๐ Complete Wiki](https://github.com/RumenDamyanov/rust-chess/wiki) ยท [๐ Quick Start](#quick-start) ยท [๐ API Reference](#api-endpoints) ยท [๐๏ธ Architecture](#architecture)
**rust-chess** is a high-performance chess engine and API server written in Rust. It provides a complete chess implementation with magic-bitboard move generation, AI opponent with alpha-beta pruning, and a RESTful API โ all compiled to a single static binary under 3 MB.
**What makes rust-chess special:**
โก **Blazing Performance**: Magic bitboards, zero-copy serialization, sub-microsecond move validation โ compiled to a single static binary with no runtime dependencies.
๐ฆ **Rust Safety Guarantees**: Memory safety without garbage collection, fearless concurrency with Tokio, type-safe API with comprehensive error handling.
๐ค **AI Engine**: Negamax with alpha-beta pruning, MVV-LVA move ordering, piece-square tables, 6 difficulty levels from random to depth-8 search.
๐ณ **Tiny Docker Image**: Multi-stage build producing a `scratch`-based image at **~3 MB** with built-in health checks.
Part of the **chess platform family** alongside [go-chess](https://github.com/RumenDamyanov/go-chess) and [npm-chess](https://github.com/RumenDamyanov/npm-chess), sharing a unified API design.
## โจ Key Features
### Core Chess Engine
- **Magic Bitboard Representation**: 64-bit bitboards with runtime-computed magic numbers for sliding piece attacks
- **Complete Rule Implementation**: All chess rules including castling, en passant, pawn promotion (all 4 piece types)
- **Legal Move Generation**: Pseudo-legal generation with legality filtering, pin detection, check evasion
- **Zobrist Hashing**: Incremental position hashing for threefold repetition detection
- **FEN & PGN Support**: Full Forsyth-Edwards Notation import/export and Portable Game Notation export
- **SAN Notation**: Standard Algebraic Notation generation and parsing with full disambiguation
- **Draw Detection**: 50-move rule, threefold repetition, insufficient material (KvK, KBvK, KNvK, KBvKB same color)
- **Game State Management**: Undo/redo with full position restoration, move history tracking
### ๐ค AI Engine
- **Negamax Search**: With alpha-beta pruning for exponential search reduction
- **MVV-LVA Move Ordering**: Most Valuable Victim โ Least Valuable Attacker for better pruning
- **Piece-Square Tables**: Positional evaluation beyond material counting
- **Bishop Pair Bonus**: 30 centipawn bonus for the bishop pair advantage
- **Time Budget Control**: Check every 4096 nodes to respect time limits
- **6 Difficulty Levels**: Harmless (random), Easy (depth 1), Medium (depth 3), Hard (depth 5), Expert (depth 6), Godlike (depth 8)
### ๐ REST API
- **14 Endpoints**: Complete game lifecycle โ create, move, undo, AI, analysis, hints, PGN, FEN
- **JSON API**: Consistent request/response format with structured error handling
- **Board Representation**: 8ร8 array (rank 8 โ rank 1), uppercase = White, lowercase = Black, null = empty
- **CORS Support**: Pre-configured for cross-origin requests (any origin/method/header)
- **Structured Logging**: `tracing`-based request/response logging with configurable levels
### ๏ฟฝ WebSocket Real-Time Events
- **Live Game Streaming**: `GET /ws/games/{id}` โ connect to receive real-time game events
- **8 Event Types**: `subscribed`, `move_made`, `ai_thinking`, `ai_move_complete`, `game_state`, `game_over`, `error`, `pong`
- **Client Commands**: `subscribe`, `unsubscribe`, `ping` โ JSON command protocol
- **Multi-Client Support**: Multiple WebSocket clients per game with isolated broadcasts
- **Automatic Cleanup**: Stale connections detected and removed on failed sends
### ๐ ๏ธ Technical Excellence
- **341 Tests**: 312 unit tests + 17 perft integration + 12 WebSocket integration, ~89% code coverage
- **Zero Warnings**: Clean `cargo clippy -D warnings` and `cargo fmt --check`
- **CI/CD Pipeline**: GitHub Actions with fmt โ clippy โ test โ perft โ coverage โ audit โ Docker
- **2.93 MB Docker Image**: `scratch`-based with built-in `--health-check` flag (no curl needed)
- **Zero Runtime Dependencies**: Static binary with musl libc
## Quick Start
### Prerequisites
- [Rust](https://rustup.rs/) 1.82+ (stable, edition 2024)
### Build & Run
```bash
# Clone the repository
git clone https://github.com/RumenDamyanov/rust-chess.git
cd rust-chess
# Build and run
cargo run
# Or using Make
make run
```
The server starts on `http://localhost:8082` by default.
### Verify
```bash
curl http://localhost:8082/health
```
```json
{
"status": "ok",
"version": "0.1.0",
"language": "rust",
"engine": "rust-chess",
"uptime": 5
}
```
### Play a Quick Game
```bash
# Create a game
GAME=$(curl -s -X POST http://localhost:8082/api/games \
-H "Content-Type: application/json" \
-d '{"whitePlayer":"Alice","blackPlayer":"Bob"}')
# Make a move (e2 to e4)
curl -s -X POST "http://localhost:8082/api/games/$ID/moves" \
-H "Content-Type: application/json" \
# Ask the AI to respond
curl -s -X POST "http://localhost:8082/api/games/$ID/ai-move" \
-H "Content-Type: application/json" \
# Get analysis
# Export PGN
curl -s "http://localhost:8082/api/games/$ID/pgn"
```
## Configuration
Environment variables:
| `PORT` | `8082` | Server port |
| `HOST` | `0.0.0.0` | Bind address |
| `CHESS_AI_TIMEOUT` | `5000` | AI move timeout in milliseconds |
| `CHESS_AI_DEFAULT_DIFFICULTY` | `medium` | Default AI difficulty |
| `CHESS_LLM_ENABLED` | `false` | Enable LLM chat features |
| `CHESS_LLM_PROVIDER` | `openai` | Default LLM provider |
| `OPENAI_API_KEY` | โ | OpenAI API key |
| `ANTHROPIC_API_KEY` | โ | Anthropic API key |
| `GEMINI_API_KEY` | โ | Google Gemini API key |
| `XAI_API_KEY` | โ | xAI (Grok) API key |
| `DEEPSEEK_API_KEY` | โ | DeepSeek API key |
```bash
PORT=9000 CHESS_AI_DEFAULT_DIFFICULTY=hard cargo run
# Enable LLM chat with OpenAI
CHESS_LLM_ENABLED=true OPENAI_API_KEY=sk-... cargo run
```
## API Endpoints
| `GET` | `/health` | Server health check with uptime and version |
| `POST` | `/api/games` | Create a new game |
| `GET` | `/api/games` | List all games (pagination, status filter) |
| `GET` | `/api/games/{id}` | Get game state (board, moves, status) |
| `DELETE` | `/api/games/{id}` | Delete a game |
| `POST` | `/api/games/{id}/moves` | Make a move (from/to or SAN) |
| `GET` | `/api/games/{id}/moves` | Get move history |
| `POST` | `/api/games/{id}/undo` | Undo last move |
| `POST` | `/api/games/{id}/ai-move` | AI makes a move |
| `POST` | `/api/games/{id}/ai-hint` | Get AI hint (doesn't modify game) |
| `GET` | `/api/games/{id}/legal-moves` | Get legal moves (optional `?from=e2` filter) |
| `POST` | `/api/games/{id}/fen` | Load position from FEN |
| `GET` | `/api/games/{id}/pgn` | Export game as PGN (text/plain) |
| `GET` | `/api/games/{id}/analysis` | Position analysis (eval, best move, depth) |
| `POST` | `/api/games/{id}/chat` | Chat with AI about a game (LLM) |
| `POST` | `/api/games/{id}/react` | AI reaction to a move (LLM) |
| `POST` | `/api/chat` | General chess chat, no game context (LLM) |
| `GET` | `/api/chat/status` | Check LLM chat availability |
| `GET` | `/ws/games/{id}` | WebSocket โ real-time game events |
### WebSocket Usage
Connect to `ws://localhost:8082/ws/games/{id}` to receive real-time events for a game. On connect, the server sends a `subscribed` event with the current game state.
**Server โ Client events:**
```jsonc
// Sent on connect
{"type":"subscribed","gameId":"...","fen":"...","status":"active","currentPlayer":"white","moveCount":0,"check":false}
// After a player move
{"type":"move_made","gameId":"...","san":"e4","from":"e2","to":"e4","player":"white","fen":"...","status":"active","moveCount":1,"check":false}
// When AI starts thinking
{"type":"ai_thinking","gameId":"...","difficulty":"medium"}
// When AI finishes
{"type":"ai_move_complete","gameId":"...","san":"e5","from":"e7","to":"e5","fen":"...","status":"active","thinkingTimeMs":42,"moveCount":2,"check":false}
// On checkmate/stalemate/draw
{"type":"game_over","gameId":"...","result":"checkmate","fen":"..."}
```
**Client โ Server commands:**
```jsonc
{"type":"ping"} // Server replies with {"type":"pong","timestamp":...}
{"type":"subscribe","game_id":"..."} // Re-subscribe / get current state
{"type":"unsubscribe","game_id":"..."} // Unsubscribe from a game
```
### Error Response Format
All errors return structured JSON:
```json
{
"error": {
"code": "INVALID_MOVE",
"message": "Move e2e5 is not legal in the current position"
}
}
```
Error codes: `GAME_NOT_FOUND`, `INVALID_MOVE`, `INVALID_FEN`, `GAME_OVER`, `NOTHING_TO_UNDO`, `INVALID_SQUARE`, `INTERNAL_ERROR`.
## Development
### Common Commands
```bash
make build # Debug build
make release # Optimized release build
make test # Run all tests
make test-verbose # Run tests with output
make lint # Run clippy linter
make fmt # Format code
make check # fmt + lint + test (pre-commit)
make coverage # Generate coverage report (needs cargo-tarpaulin)
make audit # Security audit (needs cargo-audit)
make clean # Clean build artifacts
```
### Docker
```bash
make docker # Build Docker image (~3 MB)
make docker-run # Run in container
make docker-size # Check image size
```
```bash
# Or manually
docker build -t rust-chess .
docker run -p 8082:8082 rust-chess
# With custom port
docker run -e PORT=9000 -p 9000:9000 rust-chess
```
The `scratch`-based image includes a built-in health check via `--health-check` flag (no curl/wget needed).
## Architecture
```
src/
โโโ main.rs # Entry point: CLI flags, tracing, server startup
โโโ lib.rs # Crate root: module declarations
โโโ config.rs # Environment variable configuration
โโโ engine/
โ โโโ mod.rs # Module re-exports
โ โโโ types.rs # Core types: Color, PieceType, Square, Bitboard, Move, etc.
โ โโโ zobrist.rs # Zobrist hashing (deterministic PRNG, OnceLock singleton)
โ โโโ board.rs # Position: bitboard arrays, make/undo move, FEN, attack detection
โ โโโ attacks.rs # Magic bitboard attack tables (runtime-computed magics)
โ โโโ movegen.rs # Legal move generation (pseudo-legal + legality filter)
โ โโโ game.rs # Game controller: history, undo, status detection, draw rules
โ โโโ san.rs # SAN generation & parsing with disambiguation
โ โโโ pgn.rs # PGN export with Seven Tag Roster
โโโ ai/
โ โโโ mod.rs # Module re-exports
โ โโโ evaluation.rs # Material + PST + bishop pair evaluation
โ โโโ engine.rs # AiEngine trait, RandomAi, MinimaxAi (negamax + alpha-beta)
โโโ api/
โโโ mod.rs # Module declarations
โโโ router.rs # Axum router with all routes and middleware
โโโ handlers.rs # 14 request handler functions
โโโ models.rs # Request/response JSON models + conversion helpers
โโโ errors.rs # Structured API error handling with HTTP status mapping
โโโ state.rs # Shared application state (Arc<RwLock<HashMap<String, Game>>>)
```
### Design Principles
- **Magic Bitboards**: Runtime-computed magic numbers for O(1) sliding piece attack lookups
- **LERF Mapping**: Little-Endian Rank-File (a1=0, h8=63) for cache-friendly bitboard operations
- **Incremental Zobrist**: Position hash updated via XOR on every make/undo for O(1) repetition detection
- **Type-safe moves**: Moves validated at the type level with `MoveFlags` (capture/castle/ep/promo)
- **Shared API design**: Endpoint paths and JSON schemas align with go-chess and npm-chess
- **Error propagation**: `thiserror` derives with automatic HTTP status mapping
### Performance Notes
- **Move generation**: Magic bitboards provide O(1) attack lookups for bishops, rooks, and queens
- **AI search**: Alpha-beta with MVV-LVA ordering typically prunes ~90% of nodes at depth 5
- **Memory**: Each `Position` is ~200 bytes (12 bitboards + metadata), fully stack-allocated
- **Binary size**: Release build with LTO + strip produces a ~2.5 MB static binary
## Project Phases
| 1 | Project Scaffolding | โ
Complete |
| 2 | Core Types & Board Representation | โ
Complete |
| 3 | Move Generation (Magic Bitboards) | โ
Complete |
| 4 | Game Logic (SAN, PGN, Draw Detection) | โ
Complete |
| 5 | AI Engine (Minimax + Alpha-Beta) | โ
Complete |
| 6 | REST API (14 Endpoints) | โ
Complete |
| 7 | Docker, CI & Polish | โ
Complete |
## License
This project is licensed under the MIT License โ see the [LICENSE.md](LICENSE.md) file for details.
## Related Projects
- [go-chess](https://github.com/RumenDamyanov/go-chess) โ Go chess engine & API (port 8080)
- [npm-chess](https://github.com/RumenDamyanov/npm-chess) โ TypeScript chess library (port 8081)
- [js-chess](https://github.com/RumenDamyanov/js-chess) โ JavaScript chess frontend
- [react-chess](https://github.com/RumenDamyanov/react-chess) โ React chess UI