Why this project was worth building
I chose Tic Tac Toe because it is familiar to everyone and because the rules are simple enough that the code can stay readable. That makes the project perfect for learning. Instead of spending time on complicated graphics or external libraries, I could focus on the logic that actually matters: turning clicks into moves and moves into a finished game.
The project also helped me understand that simple apps still need structure. Even a nine-cell game becomes messy if you do not clearly track turns, available cells, and results. Once I saw that, I began thinking more carefully about state instead of just writing click handlers one after another.
How the board and moves work
The board is just a group of buttons, but those buttons need to behave like a game board. Each button should know whether it is empty, which player marked it, and whether the game is still active. I stored the board status in JavaScript so the screen could always reflect the actual game state instead of guessing from the UI alone.
That approach makes resets easier too. Instead of trying to manually clean up every button one by one, I can reset the stored state and then repaint the board. This separation between data and display is one of the most useful lessons beginner developers can learn early.
Finding the winner without confusion
The heart of the game is the win-check function. There are only eight winning combinations, but the logic must run after every move and it must stop the game at the right moment. I used an array of winning patterns and compared them against the board after each turn. If a pattern matched, the game announced the winner and disabled the remaining cells.
Draw detection matters too
A lot of beginner examples forget about the draw case. If every cell is filled and no winner exists, the app should say that the match ended in a draw. That sounds like a minor detail, but it makes the game feel complete. It also teaches you to think about all possible outcomes, not just the obvious one.
Keeping the interface responsive
Good game logic is not enough if the player cannot understand what is happening. I made sure the game shows a clear message after each round and that the reset button is easy to find. Visual feedback is important because a player should not have to wonder whether their click worked. The interface should answer that question immediately.
I also found that simple styling choices make a big difference. Hover states, spacing, and button size are not decorative extras. They help the user understand that the board is interactive. Small details like that make a project feel finished instead of temporary.
What I learned from the build
This project taught me to separate logic from presentation and to think in terms of states: empty, active, won, and draw. It also helped me get more comfortable with arrays, loops, and conditional checks. These are basic ideas, but they show up everywhere in JavaScript, so learning them through a game was much easier than memorizing them from notes.
Most importantly, the project showed me that even a small game can teach discipline. A clear game loop, a clean reset, and a predictable UI are all signs of thoughtful development. That lesson carried over into my other projects too.