Echecs
A high-performance Chess Engine implemented in pure Elixir.
Echecs is a robust chess library designed for speed and correctness. It leverages advanced optimization techniques available on the BEAM virtual machine (Bitboards, Magic Bitboards, Integer packing, etc), making it suitable for high-throughput analysis and scalable applications.
Features
- High Performance: Process over 4,000 games per second (benchmarked on M1 Pro).
- Pure Elixir: No NIFs or external dependencies (C/Rust) required for core logic.
- Advanced Engine Architecture:
- Bitboards: 64-bit integer representation for O(1) board operations.
- Magic Bitboards: Fast sliding piece attack generation.
- Integer Move Encoding: Zero-allocation move generation using packed 20-bit integers to minimize Garbage Collection.
- Zobrist Hashing: Efficient game state hashing for repetition detection.
- Standard Compliance:
- FEN: Full Forsyth-Edwards Notation parsing and generation.
- PGN: Parsing and replay support for standard chess games.
- Complete Rule Implementation: Castling, En Passant, Promotion, 50-move rule, and 3-fold repetition.
Installation
Add echecs to your list of dependencies in mix.exs:
def deps do
[
{:echecs, "~> 0.1.4"}
]
endQuick Start
Basic Game Loop
game = Echecs.new_game()
moves = Echecs.legal_moves(game)
from = Echecs.Board.to_index("e2")
to = Echecs.Board.to_index("e4")
{:ok, game} = Echecs.make_move(game, from, to)
Echecs.status(game)
Squares are 0-indexed from a8 = 0 through h1 = 63.
FEN Manipulation
game = Echecs.new_game("rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2")
Echecs.FEN.to_string(game)PGN Parsing
pgn = "1. e4 e5 2. Nf3 Nc6 3. Bb5"
moves = Echecs.PGN.parse_moves(pgn)
final_game = Echecs.PGN.replay(Echecs.new_game(), moves)Advanced Usage
Performance Considerations
Echecs is designed to be extremely memory-efficient. The Echecs.MoveGen.legal_moves_int/1 function returns moves as packed integers instead of structs, which is ideal for tight loops or search algorithms (e.g. Minimax) where struct allocation overhead is significant.
Internal Board Representation
The board is represented internally as a Tuple of integers (Bitboards) for maximum access speed on the BEAM. This allows the engine to query piece locations and attack maps in constant time.
Testing & Benchmarks
The engine is verified against large-scale replay validation from the Lichess database to ensure correctness and stability.
Run Unit Tests
mix testRun Integration Benchmark
To verify large-scale replay correctness on your machine:
LICHESS_DB_PATH=path/to/file.pgn.zst mix test --include integration test/integration/lichess_db_test.exsRun Engine Benchmarks
mix echecs.benchmarkRegenerate the Magic Cache
elixir scripts/generate_magic_cache.exsDocker Support
Deploy or test in a consistent environment using the provided Docker image. The image automatically pre-generates the magic bitboard cache for faster startup.
docker build -t echecs .
docker run -it --rm echecs
iex> Echecs.new_game()