By Romain Berthoule, on 15/03/2026
What better way to understand how video games work than by rebuilding a well-known mini-game? That is how, on November 22, 2020, I got the idea to break down the TicTacToe algorithm and explore game programming methods. Essential questions came up: how do you draw in a window? How do you handle mouse clicks? How should code be structured to integrate both game logic and graphical rendering? This project aims to provide answers to those questions.

| Component | Quantity | Link |
|---|---|---|
| [ ] Computer (Windows, Linux, macOS) | 1 | - |
| Software | Comment |
|---|---|
| [ ] Code editor | VSCode, Neovim, Visual Studio |
| [ ] Compiler | GCC, Clang, and their debugger |
| [ ] Build system | Xmake, CMake, make? |
I was tired of always losing at TicTacToe, so I needed to improve. That is why the game had to include an unbeatable AI (at the time, the term did not carry the same meaning), because you improve by playing against stronger opponents.
To understand the architecture of a video game, TicTacToe needed a home screen and an in-game screen. It also had to be configurable (keys, dimensions, and difficulty). That is why I decided not to use a game engine. It would have been overkill, and it also hides too much of the learning process.
Disclaimer: since the main objective was learning, there was no intention to focus on clean code, documentation, or publishing the game.
For development, I did not start from scratch. I relied on a benchmark of the state of the art. On GitHub, many resources are available to help build a first game, especially the repository SurajSharma90/SFML_RPG. Also Adrien Poupa, who wrote an article about the TicTacToe algorithm, although it is unfortunately no longer available.
The algorithm I used in this game is called Minimax, invented in the 20th century by Von Neumann. Its behavior is close to a decision tree, always centered on the same question: "Will this choice let me win?" and with recursion across choices. The computer therefore evaluates all possible game states. This works well for small games like TicTacToe, but not for larger games like chess.
[!todo] Rework the code and turn it into a standalone algorithm with explanations for some parts.
The game loop follows the same principle as major video games. It follows the same rendering stages:
And that is reflected in this code:
void Game::run()
{
while (this->window->isOpen())
{
this->updateDTime();
this->update();
this->render();
}
}
For the game to be displayed on screen and usable by the player, the application must communicate with several computer subsystems:
That is where SFML is very practical, since it acts as an abstraction layer above those systems. It greatly simplifies development and lets us focus on game behavior and logic.
I would say that for prototyping or developing small/medium games, it is the go-to solution, because this library can be used to build a complete game. SFML can manage visuals, audio, networking, and more.
After a few days of discovery and testing, the game was working. After many attempts, I managed to beat the bot:

[!note] The game was tested on macOS 26, with SFML3 and xmake 2.9.7.
First, visual improvements can be made. Since I implemented time management, particles and/or animations can be added easily.
In addition, a local and networked two-player mode can also be implemented if I find time to explore that system.
Finally, the scoring system was designed but not implemented, so that is an option for future development.
[!help] These articles are drafts. Every bit of feedback helps me improve and better match project expectations. Feel free to contact me.