So I've been working on my first legit app. It started as an exercise in the online iOS/Swift course I've been working through. The exercise was to create a basic tic tac toe game for two players. That was easy enough, but afterwards I thought I'd see if I could get the program to play one side—to see if I could get it to think like a human, at least well enough to play and win (or tie) against a human.
It's actually been a really good exercise. Tic tac toe is a simple enough game with a fairly straightforward strategy that can be distilled down to an algorithm. I played through my app against myself a bunch, trying to take every approach and play out every scenario I could think of, looking for patterns. I also looked at strategy section of the tic tac toe Wikipedia page and compared notes with what I'd come up with. It was actually pretty close to what I'd determined myself, but it was helpful to have it spelled out, and there were things I hadn't thought of. My own experience had more nuance in certain areas, as well.
Actually coding the strategy has been really interesting, too. This is well beyond the stuff in the tutorials so far. I've created a bunch of functions that analyze the grid of nine cells to determine the best next move. I've created a
GridCell class with several different properties and methods to help analyze and manipulate the cells. I've read up about classes like
UISegmentedControl to include interface elements that haven't come up in the course yet.
As I've gone, I've added more and more complexity to the algorithm. It's gone from just reacting to the board, blocking when necessary and winning when possible, to playing more aggressively, looking for opportunities to force the player's hand or create forks that guarantee a win—and even anticipating forks by the player and stopping them before they happen. I've introduced easy, medium, and hard modes. Hard mode may be a bit of a misnomer—unbeatable is more accurate. It's the strategy played out perfectly, so that it will tie another perfect player every time. (An interesting and unexpected result was that, by coding it to compete with an experienced player and testing it that way, I accidentally left gaps in the early stages of the hard mode. An inexperienced player would do something unexpected and could actually beat it. I've plugged those holes now, so it should be actually unbeatable now. I've also improved the algorithm so that it should be better at handling scenarios that I haven't anticipated.)
One of the app's more interesting features (at least in my opinion) started life as a debugging tool—at least the concept did. Testing and debugging the program has involved playing it over and over, trying every possible scenario against every AI mode. Sometimes I'd find a bug in one specific case, but once I tweaked the code, it would take playing through multiple times to try and get that specific scenario to play out again. I found myself wishing there was an easier way to set the game up at a specific midgame state and then trigger the algorithm. To start in two-player mode and then switch to one-player on demand. At first I thought it would be a switch that I would include in the prerelease version, but then I thought that this might be a better interaction for game settings than the series of action alerts that let you choose the mode and starting player. Now there is a segmented control to set the AI to easy, medium, hard, or off. As always, the AI will play in response to a move by the human, but now there is a button to trigger the AI player on demand. This can be used to tell it to start the game, but also to trigger it at any point during the game. These two controls together are great debugging tools, but I think they're a much more interesting approach to the game settings, as well.
This is the best part of learning to code—the course is a great starting point, but what I love is going above and beyond what I've been taught, and figuring things out for myself.
I also have to mention in passing that it's really great that stark, flat, minimalism is in, because that's exactly what my app is. A couple years ago you had to have fancy graphics to be taken seriously, but now a grid and a couple of controls on a white background fits right in.
So I've submitted my first app to Beta Review. It'll be cool to get this thing live on the App Store at some point. Not that I expect it to bring much in, if anything (the release version will probably be ad-supported), but it's a baby step towards someday having apps that might actually make money. And just having an app on the App Store will be cool.