TikTakPy is a graphical Tic‑Tac‑Toe game built with Python and tkinter.
Its standout feature is a bot opponent that learns from every match using a simple but effective reinforcement learning approach.
Play against the bot, watch it improve, and even let it train by playing against itself!
- 🎨 Clean GUI built entirely with
tkinter - 🤖 Self‑learning bot – no hard‑coded strategy, no minimax
- 🧠 Experience‑based decisions – the bot remembers which moves worked in the past
- 📁 Persistent memory – learned knowledge is stored in two
.npyfiles - 📈 Continuous improvement – the more you play, the smarter the bot gets
- 🔄 Symmetry awareness – the bot recognizes rotated and mirrored versions of the board, accelerating learning
- ⚡ Lightweight – pure Python, only requires
numpy(andtkinter, which is included in standard Python distributions)
The bot’s “brain” is a move‑bag system inspired by early matchbox‑based learning machines like MENACE.
Instead of calculating numerical weights, the bot literally stores multiple copies of a move to represent how good it is.
The more copies, the more likely that move will be chosen.
All encountered board configurations are saved in cases.npy.
To avoid storing duplicates and to generalize faster, the bot does not just look for the exact current board – it also checks:
- The original board
- Horizontally mirrored version
- Vertically mirrored version
- Rotations of 90°, 180°, and 270°
If any of these 8 symmetric representations matches an existing case, that case is used.
If none is found, the current board is added as a brand‑new case (in its original orientation). This drastically reduces the number of states the bot needs to learn from and speeds up the learning process.
For each case, choices.npy stores an array of moves, where a move is simply the index of an empty cell.
Moves that have proven successful appear multiple times in this array.
When it’s the bot’s turn:
- The current board’s case (found via symmetry) is looked up.
- One move is picked uniformly at random from the corresponding array.
- Because good moves are repeated more often, they have a higher chance of being selected.
After every match, the bot adjusts the arrays based on the outcome.
It traces back all the moves it made during that game and modifies the arrays of the cases it visited:
- Win – The chosen move is copied several times into the array, making it even more likely in the future.
- Lose – One copy of the chosen move is removed from the array, making it less likely.
- Draw – The chosen move is copied once, a mild reinforcement for a non‑loss.
Over many games, winning sequences accumulate many copies, while losing lines slowly disappear.
This simple mechanism balances exploration (early on all moves have similar copy counts) and exploitation (dominant moves become heavily favoured).
The cases.npy and choices.npy files are loaded when the game starts and saved after every update.
You can train the bot for hundreds of games, close the program, and reopen it later – all learned knowledge is preserved.
-
Clone the repository
git clone https://github.com/YasharMohammadii/TikTakPy.git cd TikTakPyto start a game simply run the following python program in a new script:
from TikTakPy import * TikTakPy()
As a default, both
bot=Noneandtraining=OFFoptions are switched off. If you want to activate them simply activate them as inputs of the function:from TikTakPy import * TikTakPy(bot='X', training=ON)
To play as X(first move), set
bot='O', and to play as O, setbot='X'.