planetoceana avatar

Chess in Python: Tkinter GUI + Stockfish (UCI) with a “portable-safe” design

planetoceana

Published: 19 Jul 2026 › Updated: 19 Jul 2026Chess in Python: Tkinter GUI + Stockfish (UCI) with a “portable-safe” design

Chess in Python: Tkinter GUI + Stockfish (UCI) with a “portable-safe” design

3.png
While building my chess project in Python (in Thonny), my goal was to create more than just a “board with pieces”. I wanted a practical desktop application that lets you play against a chess engine or watch an engine-vs-engine match. The result is a Tkinter-based chess app with a graphical board, move highlighting, a move list, captured piece display, configurable engine settings, undo/redo history, and an extra window that shows the engine’s real search depth (“UCI depth”) in real time while it thinks.
Below is an overview of what the app does, what features it includes, and how it’s designed to remain portable and robust (“portable-safe”).

What does the application do?
This is a desktop chess application written in Python. The chess rules and legal move generation are implemented in the code, while computer moves are produced by a UCI chess engine (Stockfish by default). The program provides a GUI, engine configuration (depth/time/threads/hash), captured pieces, and full move history navigation.
Key highlights:
• play vs engine or run engine vs engine,
• visual move highlighting and check indication,
• move list and captured piece panel,
• asynchronous engine thinking (GUI stays responsive),
• portable configuration handling (“portable-safe”),
• live monitoring of UCI search depth.

Game modes

  1. Human vs engine
    You can choose whether the engine plays:
    • White, or
    • Black.
    The other side is controlled by a human via mouse clicks on the board.
  2. Engine vs engine
    Both sides are UCI engines. The application automatically alternates moves, which is useful for testing settings or simply watching engines play.

Graphical user interface (Tkinter)
The interface is built with Tkinter and Canvas widgets.
Chessboard
• An 8×8 board drawn on a Canvas.
• Coordinates are shown around the board (files a–h, ranks 1–8).
• Pieces are rendered using Unicode chess symbols (e.g., ♙, ♞ …).
Highlighting
To make the game easier to follow, the app uses color highlighting for:
• the selected piece and its legal destination squares,
• the engine’s last move and the opponent’s last move in different colors,
• a red outline around the king if it is in check,
• clicking a move in the move list highlights the “from–to” squares on the board.
Captured pieces + move list
A side panel shows:
• captured pieces for both sides (non-captured slots are displayed in gray),
• a move list in UCI format (e.g., e2e4) displayed in rows,
• clicking a move in the list visually marks where that move went on the board.

Chess rules implemented in the code
Because the project is not just a GUI for an engine but also contains its own chess logic, the following rules are implemented:
• legal move generation for P, N, B, R, Q, K,
• castling on both sides, including checks that the king does not cross attacked squares,
• en passant,
• promotion: in this implementation promotion is always to a queen (even if the engine suggests otherwise),
• detection of check, checkmate, and stalemate,
• a Draw ON/OFF setting:
◦ Draw ON: stalemate is a draw,
◦ Draw OFF: stalemate is treated as a win for the opponent (a custom setting for a more “decisive” mode).

Move sound
A simple sound feedback is included:
• after each move, the app plays a short beep (winsound.Beep) if enabled,
• toggle via the Sound ON/OFF button.

UCI engines (Stockfish) and configuration
Default engine and custom engine selection
The app uses a bundled Stockfish (stockfish.exe) by default, but you can select any UCI engine executable:
• separately for White and for Black.
Per-color engine settings
For each color, you can configure:
• Depth (G / depth): go ... depth N,
• Time (Č / movetime): go movetime X (configured in seconds in the GUI, converted to milliseconds internally),
• Threads,
• Hash (MB).
This allows you to tune engine strength and performance without changing the code.

Asynchronous engine thinking (thread + queue)
A key requirement for GUI applications is responsiveness. To prevent the interface from freezing, the engine search runs in the background:
• when it’s the engine’s turn, a worker thread starts,
• the engine output is read continuously,
• once the engine returns bestmove, the result is sent through a queue,
• the GUI uses periodic after() polling to safely fetch results and apply the move.
This design keeps the app responsive even at higher depths or longer thinking times.

Depth monitoring window (UCI “depth”)
A dedicated window (“Stockfish – depth”) displays:
• the current reached depth G: N,
• the maximum depth reached in the current search (max: N).
The worker thread parses UCI output lines like info depth ... and sends depth values into depth_queue. The GUI then updates the display from that queue, which is thread-safe and stable.

Game history (undo/redo)
The app stores complete game states using a GameState dataclass, enabling:
• <- step backward,
• -> step forward.
Each snapshot includes:
• board position,
• side to move,
• castling rights,
• en passant target,
• move history,
• captured pieces,
• draw setting and visual highlighting state.

“Portable-safe” design and saved configuration
The project is designed to work well as a portable app:
• if a PORTABLE.txt file exists in the application directory, settings are stored next to the program in engine_config.json,
• otherwise settings are stored in a user configuration directory (Windows: %APPDATA%/ChessUCI).
The engine_config.json file stores:
• engine path + name for White/Black,
• performance settings (threads, hash).
This way the user doesn’t need to reconfigure engines and performance options every time.

Technical structure (brief)
• Move: dataclass describing a move (from/to, promotion, en passant, castling).
• GameState: dataclass snapshot of the game for history navigation.
• ChessApp: main application class handling:
◦ board and UI drawing,
◦ click handling and move execution,
◦ legal move generation and check detection,
◦ engine communication (subprocess + UCI),
◦ async execution (thread + queue),
◦ event logging to a rotating log file (RotatingFileHandler).

Conclusion and possible improvements
This project is a solid example of combining:
• a GUI (Tkinter),
• custom chess rules and legal move checking,
• UCI engines (Stockfish),
• asynchronous processing (threading + queue),
• portable configuration and robust behavior.
Potential future upgrades:
• allow choosing promotion piece (not only queen),
• PGN export/import,
• SAN notation instead of UCI in the move list,
• more complete draw detection (threefold repetition, 50-move rule, insufficient material),
• starting from custom positions (FEN support).

4.png

5.png

Leave Chess in Python: Tkinter GUI + Stockfish (UCI) with a “portable-safe” design to:

Written by

Read more #python posts


Best Posts From planetoceana

We have not curated any of planetoceana's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.

More Posts From planetoceana