OXO, or Tic-tac-toe, is a classic game often played by young children and is known for its simple rules. It involves two players who take turns marking either an X or an O on a 3×3 grid. The first player to align three of their marks horizontally, vertically, or diagonally wins the game.
I developed a web-based version of Tic-tac-toe using PHP on my personal computer. This version features an AI opponent and leverages language models to determine winning strategies against human players. Let’s take a closer look at how the application works.
I created this application for educational purposes and experimentation. I didn’t use any frameworks on either the backend or the frontend. My goal was to build an application from scratch to better understand the underlying details. It’s not production-ready. I developed it simply to explore possible solutions and approaches. I’m aware that there are many other ways to implement this game, but I wanted to experiment and try my own approach.
On the backend, I used PHP 8.3 in a Docker containerized environment. The game board is managed server-side, and player moves are stored using session storage. On the frontend, I visualized the data using ECMAScript 6 (ES6) JavaScript classes along with HTML and CSS. When the player clicks on a cell, a request is sent to the backend, where the game board is updated, the move is recorded, and an AI assistant is called to select the next move.
The AI uses an LLM (Large Language Model) to evaluate the game state and make decisions. Backend classes are designed to be switchable, PSR-compliant, and follow the separation of concerns principle. I’ve written unit test cases for the backend as well as tests for the frontend.
You can refer to the UML class diagrams to better understand the application's architecture. For the AI model, I used openrouter.ai as the provider and selected a freely available model: deepseek/deepseek-chat-v3-0324. However, the application is flexible and allows other models to be selected via an environment variable.
This project builds on a previous custom application I developed. It's a pet project, created out of curiosity, to explore how PHP can be integrated with LLM-based applications.
Conclusion
The application works well, and I can play Tic Tac Toe with any LLM (Large Language Model). However, the performance depends on how the model was trained. While an LLM can respond with suggestions and simulate moves, its gameplay is often suboptimal because it relies on statistical language patterns rather than true strategic reasoning. As a result, it may fail to play optimally in abstract positions and seems unable to think ahead by simulating future game states — a better model is needed for that.
Eventually, I created a prompt that described the problem and asked the LLM to suggest a solution and help implement it. This led to the development of a more robust solution using the Minimax algorithm. If the API URL isn’t set in the .env file, the application defaults to using the Minimax-based AI Assistant — which is nearly unbeatable.
Overall, this was an interesting journey. I believe the true power of LLMs lies in their ability to understand complex problems — if your prompt is good enough — and to help suggest and implement working solutions.
Top comments (0)