Project overview¶
What this project is¶
This repository is a self-play and MCTS experiment system built around a 15x15 board. The board looks Go-like, but the rules are intentionally simplified so the project can focus on search, training, record keeping, and recovery instead of full referee complexity.
If you are completely new to projects like this, you can picture it as a loop:
- the program plays games against itself
- it saves what happened in those games
- it trains the model from those saved games
- it uses the updated model in later games
Why the project is built this way¶
Long-running training systems fail in predictable ways if their boundaries are vague:
- the rules become too complicated to validate
- the training loop runs for hours and still does not leave enough data behind to explain what happened
This project narrows the rules, then builds a clear path from self-play to training to checkpoints and metrics.
Core components¶
Simplified rules¶
What it is: a Go-like move and capture system with alternating turns, pass, suicide checks, captures, and repeated-position protection.
Why it is needed: MCTS and self-play need a stable state transition model. If the rules are inconsistent, the training data stops meaning one thing.
How it is used here: the rules live in the Rust engine only. Python does not implement another copy.
Inputs and outputs:
- input: board state, side to move, candidate action
- output: legality decision, next state, capture data, end reason, and scoring fields
How to judge a normal result:
- illegal moves are rejected
- two consecutive passes end the game
- repeated in-game positions are rejected
- captures and score-related fields appear in saved records
If pass is unfamiliar, it simply means skipping a move and giving the turn to the other side.
MCTS¶
What it is: Monte Carlo Tree Search used to allocate search effort and choose moves.
In plainer language, it means trying several possible continuations before committing to a move.
Why it is needed: the project is not a random playout generator. It needs a search process that can combine model guidance with board state exploration.
How it is used here: Rust handles node structure, selection, expansion, and backpropagation while Python provides model inference.
Inputs and outputs:
- input: current state, legal actions, model policy/value outputs
- output: search statistics and a selected action
How to judge a normal result:
- search does not produce rule-breaking actions
- visit counts and value statistics accumulate as the tree grows
- self-play can reach legal terminal states
Training loop¶
What it is: a cycle where self-play data is fed back into model training, then reused in later self-play.
Why it is needed: without the training stage, the project would only generate games and never test whether the model improves from saved data.
How it is used here: Python reads stored game records, builds batches, updates the residual CNN, saves checkpoints, and feeds the next round.
Inputs and outputs:
- input: game records, configuration, previous checkpoints, training device information
- output: updated weights, checkpoints, metrics, and a model ready for later inference
How to judge a normal result:
- checkpoints and metrics keep being written
- interrupted runs can recover
- hardware selection changes the device, not the model route
Here, metrics means the numeric trace of training and runtime behavior, such as step counts, loss values, or worker usage. Those numbers are what let you tell the difference between a healthy run and one that quietly drifted off course.
What the project is not trying to do¶
- It is not a full Go referee.
- It does not promise professional-strength play.
- It does not trade away reusable data for demo convenience.
- It does not keep separate rules implementations in Rust and Python.