My ZX81 Tic-Tac-Toe May Not Look Pretty, but You Can Win
June’s program of the month is a retro look at my version of tic-tac-toe from 1983.
As June winds down, I find myself reminiscing about writing month’s program. 34 years later, I still remember the glow of the TV as it lit the notebook in my lap. Although I have fond memories of Tic-tac-toe, time isn’t as kind to it. Let’s dig in.
Would you like to play a game?
Almost every budding developer will program a classic strategy game. When I choose tic-tac-toe, I thought I was choosing a pretty simple game. I mean, three in a row on a 3x3 grid seemed pretty easy, right? Boy was I naive.
Visually, my version isn’t bad. It starts by asking if you’d like instructions. After skipping or reading them, you are shown a classic tic-tac-toe grid with numbers in them. You always go first, but for some reason I made you “O” instead of “X.” Oops.
The game progresses with the ZX81 and the player taking turns until there is a winner or tie. I recommend trying a few different strategies. You can actually win—something we’ll discuss later. Tic-tac-toe plays as expected, but the presentation could be better.
Looking back, video game design seems a natural fit, although there was no such thing when I was growing up. I built a Tic-Tac-Toe playing machine in my teens which went up in smoke on the night it was scheduled to go to a science fair.
– David Crane, Developer of Pitfall!
Pick an input method!
The ZX81 offers two ways to get player feedback: INPUT
and INKEY$
. INPUT
is a hold over from the terminal days when programs would wait for the user to respond before continuing. Great for retrieving complex data, the ZX BASIC version will even let you use variables and perform math if you know how, it isn’t great for games.
Contrast that with the he asynchronous nature of INKEY$
. When used, it always returns a value allowing a program to do something whether a key is pressed or not. Although well suited for games where things keep moving, it can be used in other situations.
For Tic-tac-toe, I used both methods, yet neither well. Looking back I shouldn’t have used INPUT
as all. It is clunky and error prone the way the code is written. It’s also a bad experience. First, it takes the user out of the game. And second, it requires two key presses from the player.
It wouldn’t take much to make the change either. For example, here is the original version:
220 INPUT A$
230 IF A$>"9" AND A$<"0" THEN
GOTO 220
240 LET Z=VAL A$
There are a couple of things going on here. First, in ZX BASIC you get two different prompts depending on if you want a number or a string. The variable, A$, says we want a string. I did this because someone might choose the wrong key by accident and I wanted the chance to catch that. If I hadn’t, the program halts with an error.
The problem is that it doesn’t always work. First off, the AND
should be an OR
to work as expected. But, you can still break it by entering a number and a character. Line 230 won’t catch that and cause an error at line 240. Let’s fix that and change line 220 to use INKEY$
.
220 LET A$ = INKEY$
230 IF A$>"9" OR A$<"0" THEN
GOTO 220
240 LET Z=VAL A$
Now we have a more game like experience. In testing this, I found I could remove the delay at line 272 and 274. By also removing FAST
at line 276, I could let the computers move act as the delay without the jarring flicker.
What’s weird is I actually use INKEY$
to ask if you want to play again. Even weirder, I mimicked the INPUT
command with quotes and a prompt. I thought I was being clever, conforming to what people might expect in 1983. But that was silly, even then.
I shouldn’t complain much. I was 13 when I wrote this with no concept of user interface or experience design. I was being influenced by what I knew, but also experimenting.
There is strategy in tic-tac-toe?
The more interesting aspect of the game was that the computer actually things about its move. AI is pretty popular right now, but don’t confuse what I did with AI. These are hard coded routines that act like a human, but don’t learn. And it was the hardest part of the program.
Remember at the start that I was writing in my notebook? I was actually playing tic-tac-toe and learning how to win and lose. That may seem odd, but I didn’t want to have the computer chose a square at random. It needed to know when to win!
I sure wish I’d had access to the Internet back then. I found a great article on tic-tac-toe strategy that would have been nice to have. Instead, I figured it out myself and programmed that into the game.
That said, it isn’t perfect. The game tends to expect you to choose specific locations, and there are ways to take advantage of this. I don’t know if that was by design, but it works well and makes the game actually fun to play.
Sadly, the code that makes all this work is a bit of a mess. The game could use some major cleaning up and optimizing. As always, I leave that exercise to you. Be careful if you use my routines. I’m sure there are better ones out there now.
Win, lose or draw.
Dripping with nostalgia, Tic-tac-toe is great little game. I wish I’d given it some post development love, but otherwise is the game I remember it to be.