Fastest Python draughts / checkers library (import: draughts). Bitboard move generation ~200x faster than pydraughts. PDN/FEN, alpha-beta engine, HUB protocol, web UI. 8 variants: International, American, Frisian, Russian, Brazilian, Antidraughts, Breakthrough, Frysk!
Project description
py-draughts — fastest Python draughts & checkers library
py-draughts (import name: draughts) is a fast, modern Python library for draughts (also known as checkers). Bitboard-backed move generation, PDN/FEN parsing, a built-in alpha-beta engine, HUB protocol bridge for external engines like Scan and Kingsrow, an interactive web UI, and tensor exports for RL / ML — all in one package.
[!IMPORTANT] The fastest pure-Python draughts library: ~200x faster legal-move generation than pydraughts, with 8 supported variants and 260+ tests.
py-draughts vs pydraughts
| py-draughts | pydraughts | |
|---|---|---|
| Legal moves generation | 21.4 µs | 5.18 ms (243x slower) |
| Make move | 1.2 µs | 552.50 µs (460x slower) |
| Board init | 3.3 µs | 579.45 µs (176x slower) |
| FEN parse | 27.4 µs | 295.10 µs (11x slower) |
| Variants | 8 (Standard, American, Frisian, Russian, Brazilian, Antidraughts, Breakthrough, Frysk!) | 6 |
| Built-in AI engine | ✅ Alpha-beta + transposition tables | ❌ External only |
| Engine benchmarking suite | ✅ | ❌ |
| Web UI | ✅ FastAPI + interactive board | ❌ |
| SVG rendering | ✅ | ❌ |
| ML/RL helpers (tensors, masks) | ✅ | ❌ |
| Test suite | 260+ tests, real Lidraughts PDN replays | Limited |
| HUB protocol (Scan, Kingsrow) | ✅ | ✅ |
| Implementation | Bitboards (NumPy uint64) | Object lists |
Features: 8 variants • Built-in AI engine • External engines via HUB protocol (Scan, Kingsrow) • RL/ML ready (tensors, masks) • SVG rendering • Web UI
Installation
pip install py-draughts
Core
>>> import draughts
>>> board = draughts.Board()
>>> board.legal_moves
[Move: 31->27, Move: 31->26, Move: 32->28, ...]
>>> board.push_uci("31-27")
>>> board.push_uci("18-22")
>>> board.push_uci("27x18")
>>> board.push_uci("12x23")
>>> board
. b . b . b . b . b
b . b . b . b . b .
. b . b . . . b . b
. . . . b . b . b .
. . . b . . . . . .
. . . . . . . . . .
. w . w . w . w . w
w . w . w . w . w .
. w . w . w . w . w
w . w . w . w . w .
>>> board.pop() # Unmake the last move
Move: 12->23
>>> board.turn
Color.WHITE
Make and unmake moves
>>> board.push_uci("32-28") # Make a move
>>> board.pop() # Unmake the last move
Move: 32->28
Show ASCII board
>>> board = draughts.Board()
>>> print(board)
. b . b . b . b . b . 1 . 2 . 3 . 4 . 5
b . b . b . b . b . 6 . 7 . 8 . 9 . 10 .
. b . b . b . b . b . 11 . 12 . 13 . 14 . 15
b . b . b . b . b . 16 . 17 . 18 . 19 . 20 .
. . . . . . . . . . . 21 . 22 . 23 . 24 . 25
. . . . . . . . . . 26 . 27 . 28 . 29 . 30 .
. w . w . w . w . w . 31 . 32 . 33 . 34 . 35
w . w . w . w . w . 36 . 37 . 38 . 39 . 40 .
. w . w . w . w . w . 41 . 42 . 43 . 44 . 45
w . w . w . w . w . 46 . 47 . 48 . 49 . 50 .
Detects draws and game end
>>> board.is_draw
False
>>> board.is_threefold_repetition
False
>>> board.game_over
False
>>> board.result
'-'
FEN parsing and writing
>>> board.fen
'[FEN "W:W:W31,32,33,...:B1,2,3,..."]'
>>> board = draughts.Board.from_fen("W:WK10,K20:BK35,K45")
>>> board
. . . . . . . B . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . W . . . . .
. . . . . . . . . .
. . . . W . . . . .
B . . . . . . . . .
PDN parsing and writing
>>> board = draughts.Board()
>>> board.push_uci("32-28")
>>> board.push_uci("18-23")
>>> board.pdn
'[GameType "20"]
[Variant "Standard (international) checkers"]
[Result "-"]
1. 32-28 18-23'
>>> board = draughts.Board.from_pdn('[GameType "20"]\n1. 32-28 19-23 2. 28x19 14x23')
Variants
| Variant | Class | Board | Flying Kings | Max Capture | Notes |
|---|---|---|---|---|---|
| Standard | StandardBoard |
10×10 | Yes | Required | International / FMJD rules |
| American | AmericanBoard |
8×8 | No | Not required | Men capture forward only |
| Frisian | FrisianBoard |
10×10 | Yes | Required (by value) | Diagonal + orthogonal captures |
| Russian | RussianBoard |
8×8 | Yes | Not required | Mid-capture promotion |
| Brazilian | BrazilianBoard |
8×8 | Yes | Required | International rules on 8×8 |
| Antidraughts | AntidraughtsBoard |
10×10 | Yes | Required | Lose all pieces (or get blocked) to win |
| Breakthrough | BreakthroughBoard |
10×10 | Yes | Required | First player to make a king wins |
| Frysk! | FryskBoard |
10×10 | Yes | Required (by value) | Frisian rules with 5 men per side |
>>> from draughts import (
... StandardBoard,
... AmericanBoard,
... FrisianBoard,
... RussianBoard,
... BrazilianBoard,
... AntidraughtsBoard,
... BreakthroughBoard,
... FryskBoard,
... )
>>> board = AmericanBoard()
>>> board
. b . b . b . b
b . b . b . b .
. b . b . b . b
. . . . . . . .
. . . . . . . .
w . w . w . w .
. w . w . w . w
w . w . w . w .
SVG Rendering
>>> import draughts
>>> board = draughts.Board()
>>> draughts.svg.board(board, size=400) # Returns SVG string
>>> board = draughts.Board.from_fen("W:WK10,K20:BK35,K45")
>>> draughts.svg.board(board, size=400)
Engine
Built-in alpha-beta engine with transposition tables and iterative deepening:
>>> from draughts import Board, AlphaBetaEngine
>>> board = Board()
>>> engine = AlphaBetaEngine(depth_limit=5)
>>> move = engine.get_best_move(board)
>>> move
Move: 32->28
>>> move, score = engine.get_best_move(board, with_evaluation=True)
>>> score
0.15
External Engines (Hub Protocol)
Use external engines like Scan via the Hub protocol:
>>> from draughts import Board, HubEngine
>>> with HubEngine("path/to/scan.exe", time_limit=1.0) as engine:
... board = Board()
... move, score = engine.get_best_move(board, with_evaluation=True)
... print(f"Best: {move}, Score: {score}")
Best: 32-28, Score: 0.15
Compatible engines:
- Scan - World champion level, supports 10x10
- Kingsrow - Multiple variants, endgame databases
- Any engine implementing the Hub protocol
Engine Benchmarking
Compare engines against each other with comprehensive statistics:
>>> from draughts import Benchmark, AlphaBetaEngine
>>> stats = Benchmark(
... AlphaBetaEngine(depth_limit=4),
... AlphaBetaEngine(depth_limit=6),
... games=20
... ).run()
>>> print(stats)
============================================================
BENCHMARK: AlphaBetaEngine (d=4) vs AlphaBetaEngine (d=6)
============================================================
RESULTS: 2-12-6 (W-L-D)
AlphaBetaEngine (d=4) win rate: 25.0%
Elo difference: -191
...
Writing Your Own AI
Build custom agents with neural networks, MCTS, or any algorithm:
>>> from draughts import Board, BaseAgent, AgentEngine, Benchmark
>>> class GreedyAgent(BaseAgent):
... def select_move(self, board):
... return max(board.legal_moves, key=lambda m: len(m.captured_list))
>>> board = Board()
>>> agent = GreedyAgent()
>>> move = agent.select_move(board)
# Use with Benchmark
>>> stats = Benchmark(agent.as_engine(), AlphaBetaEngine(depth_limit=4), games=10).run()
ML-ready features:
>>> board.to_tensor() # (4, 50) tensor for neural networks
>>> board.legal_moves_mask() # Boolean mask for policy outputs
>>> board.features() # Material, mobility, game phase
>>> clone = board.copy() # Fast cloning for tree search
Server
Interactive web interface for playing and engine testing:
from draughts import Board, Server, AlphaBetaEngine, HubEngine
server = Server(
board=Board(),
white_engine=AlphaBetaEngine(depth_limit=6),
black_engine=HubEngine("path/to/scan.exe", time_limit=1.0)
)
server.run() # Open http://localhost:8000
Performance
Legal moves generation in ~10-30 microseconds:
| Operation | py-draughts | pydraughts | Speedup |
|---|---|---|---|
| Board init | 3.30 µs | 579.45 µs | 176x faster |
| FEN parse | 27.40 µs | 295.10 µs | 11x faster |
| Legal moves | 21.35 µs | 5.18 ms | 243x faster |
| Make move | 1.20 µs | 552.50 µs | 460x faster |
Engine search at various depths:
| Depth | Time | Nodes |
|---|---|---|
| 5 | 274 ms | 3,263 |
| 6 | 619 ms | 7,330 |
| 7 | 2.20 s | 21,642 |
| 8 | 6.55 s | 98,987 |
Testing
Comprehensive test suite with 260+ tests covering all variants and edge cases:
pytest test/ -v
Tests include:
- Move generation - Push/pop roundtrips, legal move validation
- Real game replays - PDN games from Lidraughts for all variants
- Edge cases - Complex king captures, promotion mid-capture, draw rules
- Engine correctness - Hash stability, transposition tables, board immutability
- All 8 variants - Standard, American, Frisian, Russian, Brazilian, Antidraughts, Breakthrough, Frysk!
Contributing
Contributions welcome! Please open an issue or submit a pull request.
License
py-draughts is licensed under the GPL 3.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py_draughts-1.8.1.tar.gz.
File metadata
- Download URL: py_draughts-1.8.1.tar.gz
- Upload date:
- Size: 153.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
00ffacede6b80deca73fe9a104bcf78c0266cf4ddb7c574283c61c216027a21b
|
|
| MD5 |
763085aea0184b6048d0c7af6057fa53
|
|
| BLAKE2b-256 |
c57d87e1b8bc7c106b8f8bd8169bc9e559aae0403fd3b02af1a34c5299f107e0
|
Provenance
The following attestation bundles were made for py_draughts-1.8.1.tar.gz:
Publisher:
python-publish.yml on miskibin/py-draughts
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
py_draughts-1.8.1.tar.gz -
Subject digest:
00ffacede6b80deca73fe9a104bcf78c0266cf4ddb7c574283c61c216027a21b - Sigstore transparency entry: 1390525363
- Sigstore integration time:
-
Permalink:
miskibin/py-draughts@a479289d0a3c4e6ca45afbad0e711171ccf00eda -
Branch / Tag:
refs/tags/v1.8.1 - Owner: https://github.com/miskibin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@a479289d0a3c4e6ca45afbad0e711171ccf00eda -
Trigger Event:
push
-
Statement type:
File details
Details for the file py_draughts-1.8.1-py3-none-any.whl.
File metadata
- Download URL: py_draughts-1.8.1-py3-none-any.whl
- Upload date:
- Size: 166.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
12865ebde5950cdd327bd18720c0c3cf189e3cca3a6876c429e31e2564b9108e
|
|
| MD5 |
e04909d7838cb4998b93d7fe9d2704db
|
|
| BLAKE2b-256 |
72013f322c29b88e97c83b15ff0f3a865d6ce6b6f462cd5e5a97e91273d1f48a
|
Provenance
The following attestation bundles were made for py_draughts-1.8.1-py3-none-any.whl:
Publisher:
python-publish.yml on miskibin/py-draughts
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
py_draughts-1.8.1-py3-none-any.whl -
Subject digest:
12865ebde5950cdd327bd18720c0c3cf189e3cca3a6876c429e31e2564b9108e - Sigstore transparency entry: 1390525375
- Sigstore integration time:
-
Permalink:
miskibin/py-draughts@a479289d0a3c4e6ca45afbad0e711171ccf00eda -
Branch / Tag:
refs/tags/v1.8.1 - Owner: https://github.com/miskibin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@a479289d0a3c4e6ca45afbad0e711171ccf00eda -
Trigger Event:
push
-
Statement type: