Game · 2025 · 10 / 10
XO Game.
A JavaFX tic-tac-toe built to exercise minimax, FXML navigation, and desktop packaging in one tidy 800-line project.
- Context
XO Game is a desktop tic-tac-toe written in Java 21 and JavaFX 21, structured as a four-scene FXML app: main menu, difficulty picker, game board, and settings. The computer opponent runs a full minimax search, and the four difficulty levels mix the optimal move with a random legal move at set probabilities so one algorithm covers the whole curve. Theme (Classic / Dark / Light / Neon), sound volumes, and win / loss / draw stats all persist through java.util.prefs.Preferences, and the Maven build goes all the way to a jlink-trimmed runtime image wrapped by jpackage into a Windows installer that ships as a GitHub release.
- Approach
The point was never the game - tic-tac-toe is small enough that the interesting surface is the stack around it. FXML keeps layout out of the controllers, so every screen is a one-file scene that can be swapped with a single stage.setScene(). The AI is one minimax function shared by every difficulty tier, which drops the probability-of-random down to a single ternary and makes the whole ladder trivially tunable. Everything persistent piggybacks on the JDK's own Preferences API rather than adding a dependency, and the packaging pipeline (javafx-maven-plugin → jlink → jpackage) produces a double-click Windows installer rather than a "here is a jar, good luck" download.
- Outcome
Shipped as v1.0.0 on GitHub in February 2025 with a Windows installer. The project was the scratch-pad for learning JavaFX controls, FXML / controller separation, Preferences persistence, and the jpackage end of the Java desktop story - a small board game that teaches the shape of a real desktop app.
- The numbers
minimax, full tree
AI depth
4
Difficulty tiers
4
Themes
v1.0.0 · Windows
Release
- Process
- 01
FXML-first layout
Every scene lives as its own FXML file - menu, difficulty, game, settings - and the controllers only handle behaviour. Swapping scenes is a one-line stage.setScene(), and the CSS theme re-applies on each transition so the look stays consistent across navigation.
- 02
Minimax with a probability dial
Impossible plays pure minimax and will never lose. Easy / Medium / Hard mix the optimal move with a random legal move at 20 / 50 / 80 percent, so the same algorithm powers every tier without separate heuristics. The difficulty curve falls out of one line of code.
- 03
Persistent everything via Preferences
Theme choice, sound volumes, and W/L/D stats all live in java.util.prefs.Preferences on the user node, so closing the app and re-opening keeps the same state. No database, no file I/O - the JDK already ships the right tool.
- 04
Packaged as a real desktop app
Maven pipeline goes javafx-maven-plugin to jlink a trimmed runtime image, then jpackage wraps it into a Windows installer with a Start-menu entry. The v1.0.0 release is the installer, not a jar a visitor has to figure out how to run.
- Credits
- Build
- Salah Boussettah
- Next
→ Hisab Digital
Product · 2026