Chess tournament pairing engines — FIDE Dutch System (C.04.3), matched against bbpPairings to A.7 conformance.
Project description
caissify-pairings
Chess tournament pairing engines for Python. Currently implements the
FIDE Dutch System (C.04.3), cross-validated against the FIDE-endorsed
reference bbpPairings to full A.7 conformance.
What you get
- A programmable pairing engine — use it as a library, call it from a web service, or wrap it in a tournament-director UI.
- TRF16 parser and writer.
- A Free Pairings Checker (FPC) — validate a TRF file against the engine.
- A Random Tournament Generator (RTG) — generate simulated tournaments for testing.
- A simple JSON-over-stdin CLI.
FIDE A.7 conformance
The FIDE Swiss Pairings Programs Commission evaluates endorsed pairing software using the A.7 test: a program is expected to produce pairings that match an already-endorsed program on at least 4990 of 5000 random tournaments (≤ 10 discrepancies).
Measured against bbpPairings
(FIDE-endorsed, C++) using our Random Tournament Generator + Free Pairings
Checker pipeline:
| Benchmark | Rounds checked | Discrepancies | FIDE target | Result |
|---|---|---|---|---|
| 5000 × 20-player / 9-round | 45,000 | 0 | ≤ 10 | ✅ PASS |
| 5000 × 10-player / 5-round | 25,000 | 0 | ≤ 10 | ✅ PASS |
See doc/ENGINE_STATUS.md for the full story
and doc/DIVERGENCE_TESTING.md for the
methodology.
Note. A.7 conformance is a technical criterion.
caissify-pairingsis not yet FIDE-endorsed — endorsement is a separate administrative process with the FIDE SPP Commission.
Installation
pip install caissify-pairings
Requires Python 3.10+. The only runtime dependency is networkx
(for maximum-weight matching).
Quick start — library
from caissify_pairings import generate_pairings
players = [
{"id": 1, "name": "Carlsen", "score": 2.0, "rating": 2830,
"starting_number": 1, "color_hist": ["white", "black"],
"float_history": [], "bye_count": 0},
{"id": 2, "name": "Firouzja", "score": 2.0, "rating": 2785,
"starting_number": 2, "color_hist": ["black", "white"],
"float_history": [], "bye_count": 0},
{"id": 3, "name": "Ding", "score": 1.5, "rating": 2780,
"starting_number": 3, "color_hist": ["white", "black"],
"float_history": [], "bye_count": 0},
{"id": 4, "name": "Nepo", "score": 1.5, "rating": 2775,
"starting_number": 4, "color_hist": ["black", "white"],
"float_history": [], "bye_count": 0},
]
pairings = generate_pairings(
system="dutch",
players=players,
previous_pairings={(1, 3), (2, 4)},
round_number=3,
total_rounds=9,
)
for p in pairings:
print(f"Table {p['table']}: {p['white_id']} vs {p['black_id']}")
Command-line usage
# Pair a round from a JSON state on stdin, write pairings to stdout
caissify-pairings < tournament_state.json
# Validate a FIDE TRF file against the Dutch engine
caissify-pairings-check tournament.trf
# Generate random tournaments for testing
caissify-pairings-rtg --players 20 --rounds 9 -n 100 -o ./output/
Input JSON schema
{
"system": "dutch",
"players": [
{
"id": 1,
"name": "Player Name",
"score": 0.0,
"rating": 2400,
"starting_number": 1,
"color_hist": [],
"float_history": [],
"bye_count": 0
}
],
"previous_pairings": [[1, 3], [2, 4]],
"round_number": 1,
"total_rounds": 9,
"bye_value": 1.0,
"max_byes_per_player": 1
}
Output JSON schema
[
{"white_id": 1, "black_id": 4, "table": 1},
{"white_id": 3, "black_id": 2, "table": 2}
]
What works today
- FIDE Dutch System (C.04.3, Feb 2026 spec) — full A.7 conformance
against
bbpPairingson 20p/9r and 10p/5r benchmarks (see above). - Full TRF16 round-trip parsing/writing.
- Free Pairings Checker (FPC) for validating existing TRF files.
- Random Tournament Generator (RTG) for test corpora.
- Pure-Python, single runtime dependency (
networkx).
What does not work yet
Being honest up front — these are known limitations you will hit if your use-case is beyond them:
- Only the Dutch system is implemented. No Accelerated Dutch, Burstein, Monrad, or round-robin generators yet.
- Large-tournament fixture match rates are lower against pre-recorded
bbpPairingsoutputs for 40+ players (e.g. 40p/9r reports ~11% exact pair agreement on a handful of fixtures). The 5000-tournament A.7 conformance benchmark tops out at 20p/9r, where the engine is at 0 discrepancies; at larger scales tie-breaking divergences are expected. - No tournament-director UI. This is an engine / library, not a standalone product.
- No FIDE endorsement. A.7 conformance is met technically; endorsement is a separate process that has not been pursued.
- API is not stabilised. Version
0.xmay introduce breaking changes. API will be frozen at1.0.0.
If any of these block you, please open an issue — priorities are driven by real user needs.
Using an engine directly
from caissify_pairings.engines.dutch import dutch_pairings
pairings = dutch_pairings(
players=players,
previous_pairings=set(),
round_number=1,
total_rounds=9,
)
Extending
New pairing systems plug in via a small registry.
from caissify_pairings.base import BasePairingEngine
class MyEngine(BasePairingEngine):
name = "my_system"
def generate_pairings(self) -> list[dict]:
...
Register it in caissify_pairings/engines/__init__.py to expose it through
the top-level generate_pairings(system="my_system", ...) call.
Testing
# Fast suite (skip @slow 5000-tournament benchmarks)
pytest -m "not slow"
# Full suite including FIDE A.7 benchmarks (takes ~25 min)
pytest
Acknowledgements
Cross-validated against the FIDE-endorsed reference implementations:
- bbpPairings by Bierema Boyzvoort Media Foundation — Apache-2.0.
- JaVaFo by Roberto Ricca.
Thanks to their authors for making these tools freely available.
License
MIT — see LICENSE.
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 caissify_pairings-0.1.0.tar.gz.
File metadata
- Download URL: caissify_pairings-0.1.0.tar.gz
- Upload date:
- Size: 139.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f24e2ecfe8d19f51417e1e9134658d9e865b94a48b13daac6b423a65b7670de
|
|
| MD5 |
a8f51f51eb544b2efd2be8ab1b45c543
|
|
| BLAKE2b-256 |
5ed8105352e385e29aef28cb15ebceba3dc95dd4a5fdde2cd12a9e124bc69f12
|
File details
Details for the file caissify_pairings-0.1.0-py3-none-any.whl.
File metadata
- Download URL: caissify_pairings-0.1.0-py3-none-any.whl
- Upload date:
- Size: 48.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b91d9c05b669840a7b88dc4d2520d25235c2a15a24e9170130f1677f875c699
|
|
| MD5 |
3af70b6ffe817c312f9f086371856f53
|
|
| BLAKE2b-256 |
0a3cefabee191d1912b649160f7a49bde02998fee902f57f7d809a399e3805fe
|