/'siːn.meɪt/, by the way (If you are a linguistics nerd like me)
CynMeith is a stateless board-game engine for building turn-based games with custom movement rules, side effects, turn structures, win conditions, phases, scoring, and resources — on square and hexagonal boards.
The whole game situation lives in one immutable GameState, and the engine is a
set of pure functions over it (legal_moves / apply / outcome). That makes
undo/redo trivial, save-states and puzzles a one-liner, and parallel AI rollouts
(Minimax/MCTS) safe by construction — forking a game is just passing the same
value to another worker.
It ships built-in presets for common patterns: piece-elimination and reach-cell wins, move-limit draws, ply-based phases, action points, piece-count and material scoring, and a royal-safety/checkmate family for chess-like games.
It includes playable Tk examples for chess, xiangqi, and a custom game (Exist).
After cooking some spaghetti that made me refuse to look at them again, I decided to write a brand new one, with my brand new brain.
Practice makes perfect
The first version coupled game logic to a mutable board of piece objects. This
rewrite pulls all mutable data into an immutable GameState, turns pieces into
plain data, and makes board geometry a swappable strategy — so hex boards, save
states, and AI search stopped fighting the engine.
- Stateless core: immutable
GameState, pureEngine. Undo is a list index; a rollout is a fork. - First-class hex geometry: axial
(q, r)coordinates with O(1) cube math for neighbors, distance, rings, and area-of-effect — no offset arrays, no BFS. - Pieces as data: define a knight with
PieceDef("N", "Knight", moves=leaper(*KNIGHT_OFFSETS))— no subclassing. - Serializable: any position round-trips through JSON or FEN (square and hex).
- Tk examples included: fully playable Chess, Xiangqi (Cờ Tướng), and Exist.
Make sure you have Poetry installed, then run:
poetry install(No PyPI release yet because I lack the confidence.)
poetry run python examples/tk_demo.py chess
poetry run python examples/tk_demo.py xiangqi
poetry run python examples/tk_demo.py existfrom cynmeith import Coord
from examples.chess.game import CHESS
session = CHESS.new_session() # or .new_session(setup="<fen>") for a puzzle
session.move(Coord(1, 4), Coord(3, 4)) # 1. e4 — (row, col) start -> end
print(session.side_to_move, session.outcome)A game is described by a single GameDef (geometry, pieces, starting position,
and rule components); new_session() builds an interactive GameSession, and
GameDef.engine() gives you the pure-function Engine for AI search. See
docs/quickstart.md.
- Start here: docs/index.md
- Overview: docs/overview.md
- Python-enough guide: docs/python-enough.md
- First custom game: docs/first-game.md
- Architecture (the stateless design): docs/architecture.md
- API reference: docs/api.md
- Examples launcher: examples/tk_demo.py
This project is licensed under the MIT License - see the LICENSE file for details.
If you use CynMeith in your spaghetti code, please put this line in your "About" section or Credits screen so I can flex with my friends:
CynMeith Board-Game Engine by Cynmeiciel/Tran Van Duy (https://github.com/cynmeiciel/cynmeith)
If you made something cool with this, please open an Issue or PR, or just drop a Star to validate my existence to let me brag about it.