Building a tic-tac-toe solver with AI

Earlier this week I've been working on a tic-tac-toe solver built with the help of AI. You can play with it at the link below.

https://tictactoe.tjwaterman.com

The UI looks like this.

gameboard

My goal with the project was to practice using AI to build something. I also wanted a get a feel for what building an end-to-end product would be like. Most of my time spent developing is pretty close to the database, so I thought this would be a good project to practice both things.

There ended up being about 1000 lines of code total. There's a Vue app that asks an AWS Lambda function what move it should play next. The move is chosen by a reinforcement learning model that was built and trained with the Python standard library.

Overall I was shocked at how nice the app came out looking. I asked Copilot to write all the CSS, which it did in about 30 seconds. There are even nice animations. Without that help, I probably would have spent numerous hours wrangling and fiddling and even then I would have produced something that wasn't as good. I'm pretty much sold on asking AI to write CSS for me from now on.

But when I tried to ask AI for help with the code on the backend I felt it actually ended up costing me time in the long run. I was using the Copilot autocomplete with the Claude Sonnet 4 model and liberally accepting its suggestions.

After some time racing through this, I paused: I did't really understand what Copilot was producing here. I could superficially tell you what was happening, but I didn't have a clear design for the project. I had lost control.

There was inevitably a bug that needed to be fixed and the AI was failing at it. It gave several earnest tries and eventually got stuck in a loop. I realized I was going to have to help out.

I'm sure had I been using my normal development approach I could have solved it pretty quickly. But because I'd been vibe coding I'd now have to go back and carefully read through everything the AI created, which was going to take me just as long, if not longer, than creating it myself.

This was actually one of the first lessons I remember learning about technical projects: it can sometimes be easier to build something from scratch than it is to modify something that someone else created. That's counter intuitive to most people because it's very different than projects in the real world. It's much easier to do a kitchen renovation than it is to rebuild the whole house. But with technical work, it might actually be faster to just throw the whole thing away and restart, so long as "the whole thing" isn't too large.

I think that's the difference between the CSS and the backend. I don't honestly care about being totally in control of the CSS. As long as it's good enough, then I'm more than happy. In fact I'm delighted.

But on the backend, I absolutely want to be in control. I need that in order to really understand the domain I'm working on, and especially to fix some bugs. The AI is great at fixing things say 80% of the time, but that's actually not high enough. If I can't trust it 100% of the time, then I need to be able to complete that remaining percentage; to complete those remainders, I need to have a full understanding of the code.

So I ended up throwing away almost all the backend code that the AI wrote and rewriting it myself pretty quickly.

Overall, I'll definitely be using AI for my next projects, but on a shorter leash. For something like CSS it's perfect; a database schema not so much.