This project requires Python 3.7 or higher. Please ensure Python 3.7+ is installed and available on your PATH before running the setup.
First, open a terminal in the directory you'd like to clone the project in.
# Clone the repo
git clone https://github.com/leobeaumont/GoInsight.git
cd GoInsight# Setup the environement
make setup# Activate the virtual environment
source .venv/bin/activate# Download KataGo model
make get-modelYou're all setup !
First, open PowerShell in the directory where you'd like to clone the project.
# Clone the repo
git clone https://github.com/leobeaumont/GoInsight.git
cd ./GoInsight/# Allow PowerShell scripts to run (first time only)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser# Setup the environment
.\make.ps1 setup# Activate the virtual environment
.\.venv\Scripts\Activate.ps1# Download KataGo model
.\make.ps1 get-modelThis will open the project's documentation on your default web browser
make docs.\make.ps1 docsYou can use any version of KataGo and any neuralnet configuration with GoInsight. The default configuration is made to work on any device.
If you need help choosing the right model for your device, click here.
You can choose the model you want to use from here. Simply copy the download link of the model zip of your choice and paste it as the new value of MODEL_URL in Makefile file at line 18 (for Windows user, do the same in the file make.ps1 at line 42).
If everything was done correctly, it should look like this:
MODEL_URL = https://github.com/lightvector/KataGo/releases/download/[model version]/[name of model zip file]Changing the neuralet is the easiest way to balance speed and performance when using GoInsight. You can choose the neuralnet you want from here. Simply copy the download link of the neuralnet tar.gz file of your choice and paste it as the new value of NEURALNET_URL in Makefile file at line 21 (for Windows user, do the same in the file make.ps1 at line 45). You must also change the value of NEURALNET_FILE with the new tar.gz file name at line 20 in Makefile (and at line 44 of make.ps1 for Windows users).
If everything was done correctly, it should look like this:
NEURALNET_FILE = $(NEURALNET_DIR)/[name of the neuralnet tar.gz file]
NEURALNET_URL = https://katagoarchive.org/[neuralnet generation]/neuralnets/[name of the neuralnet tar.gz file]This start an instance of KataGo, type gtp commands to interact with it.
- Use
quitcommand to close the instance - Use
list_commandsto get a list of all the commands
make run-model.\make.ps1 run-modelStart a batch of tests to find the best parameters (This will take a few minutes)
make opt-model.\make.ps1 opt-modelThis will run all tests declared in the tests directory
make tests.\make.ps1 testsRemove setup files and the virtual environment from the project
make clean.\make.ps1 cleanContributions are not welcome yet, as this project is part of students cursus a IMT Atltantique. The project will be opened to contributors after the course ended.
TenukiBrest Go association.IMT Atlantiqueengineering school.KataGoopen ource Go engine.
- Coppin Gilles
- Le Hir Mathieu
- Peillard Étienne
- Beaumont Léo (leo.beaumont@imt-atlantique.net)
- Chambriard Léopold (leopold.chambriard@imt-atlantique.net)
- Chouki Mouad (mouad.chouki@imt-atlantique.net)
- Disdier Jordan (jordan.disdier@imt-atlantique.net)
- Garrana Simon (simon.garrana@imt-atlantique.net)
- Miranda-Gonzales Marcelo (marcelo.miranda-gonzales@imt-atlantique.net)
- Roubertou Amaury (amaury.roubertou@imt-atlantique.net)
For any questions or supports, please contact leo.beaumont@imt-atlantique.net.
The SgfTree object is a complete and structured representation of an SGF (Smart Game Format) file, a standard format used to describe games of board games like Go. It serves as a central interface for reading, manipulating, comparing, converting, and writing SGF games, while preserving the tree structure inherent to this format.
An SgfTree represents a node of the SGF tree. Each node contains:
-
a dictionary of SGF properties, where each key is an SGF identifier (e.g., B, W, SZ, etc.) associated with a list of values,
-
a list of child nodes, allowing the representation of game variants.
This structure allows for the accurate modeling of:
-
the main line of a game,
-
variants and sub-variants,
-
the exact order of moves and metadata.
An SGF tree can be created in several ways:
-
From an SGF file The
from_sgf(path)method reads an SGF file from disk, checks for its existence, and then parses it to construct the corresponding tree. -
From a Game object The
from_game(game)method converts a Game object (internal engine logic) into an SGF tree, thus ensuring complete interoperability between the game's logical representation and the SGF format. -
By directly parsing an SGF string The
parse(input)function transforms a raw SGF string into an SGF tree, rigorously validating the syntax (parentheses, properties, capitalization, delimiters, etc.).
The SgfTree acts as a bridge between different formats:
-
To a Game object The
to_game()method reconstructs a Game object from the SGF tree, allowing you to then simulate, analyze, or modify the game. -
To an SGF string or file The
to_sgf(path=None)method serializes the tree into a valid SGF string.
If a path is provided, the SGF is also written to a file.
The serialization adheres to SGF rules:
-
escaping of special characters,
-
correct handling of variants,
-
generation of a syntactically valid SGF.
The move_sequence() method extracts the sequence of moves played, in order, from the tree:
-
Moves are converted from SGF format to GTP format,
-
The board size is automatically detected if necessary,
-
Moves can be returned either as strings ("B A19") or as tuples ("B", "A19").
This method is particularly useful for:
-
Replaying a game,
-
Interfacing with a Go engine,
-
Analyzing or displaying a game move by move.
The get_board_size() method extracts the board size from the SZ property of the root node:
-
It supports square and rectangular formats,
-
It validates sizes against a maximum constant,
-
It guarantees that the returned size is consistent and usable.
The module includes a complete SGF parser that:
-
validates tree structure,
-
prohibits lowercase properties,
-
correctly handles escaped characters,
-
detects syntax errors (empty trees, incorrect delimiters, invalid format).
This ensures that any SgfTree created from an SGF is structurally valid.
The Move object represents an individual move in a game of Go. It encapsulates all the information necessary to describe, interpret, validate, and convert a move between different standard formats (internal, SGF, and GTP).
General Role
-
a game,
-
a color (black or white),
-
a position on the board or a pass,
-
a turn number in the game.
It thus constitutes the basic unit for replaying, exporting, or analyzing a game.
During instantiation:
-
The color can be explicitly provided (B/W), otherwise it is automatically deduced from the game state,
-
The position is validated using the game board,
-
A move without a position corresponds to a pass. Any attempt to play on an invalid position results in an error, ensuring the game's consistency.
The Move class provides several essential conversion methods:
- SGF -> Internal Coordinates
sgf_to_coord() translates an SGF position ("dd") into coordinates (x, y) usable by the engine.
-
SGF -> GTP sgf_to_gtp() converts an SGF coordinate into GTP notation (A19, Q4, etc.), taking into account the board size and the specific case of a pass.
-
GTP -> Move
from_gtp()allows you to directly create a Move object from a standard GTP instruction ("w A19"), validating the syntax and coordinates.
These conversions ensure interoperability with:
-
Go engines,
-
Graphical interfaces,
-
SGF files.
A move can be exported in different formats:
-
To GTP
to_gtp()returns a valid GTP command representing the move. -
To SGF
to_sgf()generates the corresponding SGF property ({"B": ["dd"]}), which can be directly used in an SGF tree.
The Board object represents the state of the Go board at a given moment, constructed from a sequence of moves. It is responsible for all the spatial logic: stone placement, groups, liberties, and captures.
A Board:
-
maintains a matrix representation of the board,
-
applies the fundamental rules of Go (liberties, captures),
-
allows local and global operations on the game state.
It forms the basis of the game logic.
Upon creation:
-
the board is sized (19×19 by default),
-
the move list is used to reconstruct the game state,
-
each move is played in order with automatic updating of the captures.
Any inconsistency in the move sequence is detected immediately.
The is_valid_pos() method checks:
-
that the position is within the board boundaries,
-
that it is not already occupied.
It is used both to play and to remove moves, guaranteeing the integrity of the board.
The board can be modified dynamically:
-
Adding a move
add_move()places a stone and triggers capture detection. -
Removing a move
remove_move()removes a stone, either by direct reference or by coordinates.
These operations allow, for example:
-
going back,
-
editing a game,
-
analyzing intermediate positions.
The board provides essential analysis tools:
-
Orthogonal Neighborhood
_neighbors()returns adjacent intersections according to Go connectivity. -
Groups and Freedoms
group_and_liberties()identifies: -
a group of connected stones,
-
the set of its freedoms.
This method is at the heart of the capture logic.
The update_board() method:
-
examines the groups affected by a move,
-
detects those that have run out of liberties,
-
automatically removes captured stones.
This implementation is intentionally agnostic to advanced rules (KO, suicide forbidden, etc.), making it robust and easily extensible.
The area_selection_positions() method extracts all intersections of a rectangular area of the board, using GTP notation.
It is particularly useful for:
-
local analysis,
-
integration with engines,
-
visualization or statistical tools.
The Analyzer object is responsible for the automatic analysis of a Go game using the KataGo engine.
It forms the central layer connecting:
-
the internal game representation (Game, SgfTree),
-
the external AI engine,
-
the data required for the user interface.
An Analyzer allows you to:
-
analyze the entire game move by move (global analysis),
-
perform an in-depth analysis of a specific move,
-
extract quantitative indicators (win rate, score lead),
-
normalize the results from the perspective of a given player (Black or White).
During its creation:
-
the SGF file is loaded and converted into an SgfTree,
-
the analyzed player (Black or White) is set,
-
the result storage structures are initialized.
Any invalid value for the player is immediately rejected.
The shalow_game_analysis() method:
-
automatically selects the KataGo binary based on the operating system,
-
reconstructs the game from the SGF tree,
-
generates the JSON input expected by KataGo,
-
runs an analysis for each turn of the game,
-
collects and sorts the results.
The result is stored in game_analysis and contains, for each move:
-
win rate,
-
score lead,
-
current player,
-
moves recommended by the AI.
This analysis forms the basis of all other features.
The deep_turn_analysis() method allows for in-depth analysis of a specific turn:
-
optionally with a spatial restriction (allowed or forbidden zone),
-
with a greater search depth,
-
by extracting the best possible variations.
The results are stored in turn_analysis, indexed by turn number.
game_score_lead() returns the score evolution throughout the game.
The data is ready to be used for graphs or statistics.
The turn_basic_data() method provides the essential information to display for a given turn:
-
win rate of the analyzed player,
-
Lead score of the analyzed player,
-
Best move suggested by KataGo,
-
Expected score after this move,
-
Player who should play the next move.
All values are normalized from the perspective of the selected player, which greatly simplifies the display.
The turn_advanced_data() method returns:
-
An ordered list of the best moves,
-
Their expected score,
-
A truncated main variation.
This data is intended for detailed or interactive display.
The Evaluator object is responsible for assessing the quality of the moves played based on the results provided by the Analyzer.
An Evaluator:
-
Transforms numerical data (win rate) into qualitative judgments,
-
Provides a human and educational interpretation of the game,
-
Applies a standard classification grid.
The classify_move() method:
-
compares the win rate before and after a move,
-
calculates the win rate loss (or gain),
-
corrects the sign according to the player who played,
-
classifies the move into a category:
BEST EXCELLENT GOOD INACCURACY MISTAKE BLUNDER
Classification thresholds are defined in MOVE_CLASSIFICATION_BOUNDS.
The classify_game() method applies this logic to all moves in the game and returns a list aligned with the game's turns. This class therefore allows for the production of:
-
automatic annotations,
-
performance statistics.
The API class constitutes the external interface layer of the project.
It exposes a simple API, designed for consumption through a graphical interface or a web client.
The API:
-
orchestrates the Analyzer and Evaluator,
-
hides the complexity of GoInsight and its internal structures,
-
returns only ready-to-use JSON data.
The all_moves_analysis() method:
-
launches the overall analysis of the game,
-
classifies all moves,
-
groups all data into a single JSON object.
The returned data includes:
-
detailed information per turn,
-
the qualitative classification of each move,
-
the score evolution over the entire game.
This method is designed to be called upon the initial load of an analysis.
The deep_turn_area_analysis() method:
-
launches an in-depth analysis of a given move,
-
allows limiting or excluding an area of the board,
-
returns only the best moves and variations.
This feature is ideal for:
-
interactive exploration,
-
analyze a specific area of the game,
-
local analysis,
-
teaching and commenting on games.
All API methods return:
-
well-formatted JSON strings,
-
directly usable by a frontend,
-
without any dependency on internal engine objects.
