Computact is March’s ZX81 Program
Run the trench and land your ship to destroy the COMPUTACT.
Ah, spring time. As winter melts away, the weather goes haywire and it’s time to enjoy the bouts of sunshine, rain and the occasional thunderstorm of hail. Perhaps it’s fitting that in the middle of this meteorological mayhem that Computact came back to life. An outwardly simple landing game that is almost impossible to play. No matter, it demonstrates some interesting use of ZX81 BASIC as March’s Program of the month.
Before diving in too deep, let’s talk about how to play the game. Easy, just use the left and right arrow keys—5 and 8 on the ZX81 keyboard, no shift required—to move your ship. When you die, answer yes by pressing Y to start over. You’ll be doing that a lot so I thought I’d help you avoid that frustration. I spent a good minute hitting keys until I realized it was actually asking me a question.
While you’re busy dying, let’s talk about the name. The name, if memory serves, is a mashup of the words computer and tactics. Not a bad name, but as many of those made up by a 14 year old it doesn’t match the material. Sure, there is a computer, at least the one you’re using to run it on. But yet, there isn’t any tactics. Moving a ship from side to side through a trench—you did guess that was a trench, right?—and trying to land on a tiny moving platform doesn’t lend itself to tactical thinking.
Looking for the silver in the gray clouds that sit outside my window this morning, I reflect on what is right with the game. For me, it was more of a tech demo than a game. I’m sure I had visions of Star Wars and Zaxxon in my head when I wrote this. Knowing that a 3D trench on the ZX81 was already hard enough, I decided to play with colors—err, variations of black and hash—to convey depth.
The picture doesn’t do it justice, you need to watch the animation to better understand. Each move shifts the colors up to emphasize that the middle is separate from the sides. The effect is decent, although a bit more speed would have helped. But remember this is a program from 32 years ago, the fact that I was able to move that amount of graphics in a single move is pretty awesome.
I’m sure you aren’t asking how it is done, but I’m going to tell you anyway. One of the cool things that the ZX81 did well was string array splicing. That is, you can use things like
A$( TO 10) to get the first 10 characters of a string. It is fast enough, even in BASIC, to allow for some interesting graphics. It also keeps the program relatively short. The main routine is only nine lines long.
If you look at the listing, the first use of string splicing is to build the trench in lines 80-100. Each segment of the trench is a mix of hash and black blocks, two rows of 64 elements. Since you can replace part of a string using a slice, I inserted those two lines over and over using this code:
40 DIM A$(384)
80 FOR A=0 TO 11 STEP 2
90 LET A$((A*32+1) TO (A*32)+64)="…blocks of graphics…"
100 NEXT A
Now, if I’d been thinking, I could have removed a lot of that math from the routine by doing something like this:
80 FOR A=1 TO 320 STEP 64
90 LET A$(A TO A+64)="…blocks of graphics…"
100 NEXT A
This would have been a little faster and saved about 18 bytes of memory. In either case, the code works and shows the power of the slice. Later on, I use this simple line to scroll the trench and create the moving effect:
170 LET A$=A$(33 TO )+A$( TO 32)
This basically pops the top row off the stack and pushes it to the bottom. It is interesting that it works. Given you are overwriting the existing variable, the ZX81 must be making copies of the data before reassembling them into the array. It does so surprisingly fast and is seamless to the BASIC programmer.
I use this same push and pop method to move the landing pad. The code is a bit more complex as we need to randomly shift it right or left. Using the ZX81’s boolean logic, it is done in two lines of code:
175 LET V=INT (RND*2)
180 LET C$=((C$(2 TO )+C$(1)) AND (C$(11)="_" AND V))
+((C$(32)+C$( TO 31)) AND (C$(22)="_" AND NOT V))
+(C$ AND (C$(11)<>"_" OR C$(22)<>"_"))
Reading that can be confusing, let’s break it into pseudocode.
Let V = random 0 or 1
If V is 1 and the value C$(11) is a black square
Then let C$ = shift left—C$(2 TO )+C$(1)
If V is 0 and the value C$(2) is a black square
Then let C$ = shift right—C$(32)+C$( TO 31)
Otherwise let C$ equal
That is a lot of logic packed into a single line. It is also a lot of processing. In this case, using the string slice wasn’t the best choice. The code would have been simpler, and faster, if I’d used a variable to hold the position of the landing pad.
The rest of the program is pretty straight forward. There is a nice random snow effect as you move to the next level, assuming you are so lucky. I just wish I’d let you press any key to continue.
Let’s go back to game play for a minute. That same routine above is also the reason the game is next to impossible to play. Do you see it? Hint, it’s on line 175. Nope? Still not seeing it. The boolean value of V means that every move the landing pad shifts right or left. Only when it is against the side of the trench will it not move. Oh, and the landing pad is only one square larger than your ship. Combine these two elements are combined it is nearly impossible to stick the landing.
There are a couple of ways I could have made the game fair. First off, making the landing pad larger would have been more forgiving. I could also have allowed the wings to overlap and only counted the body of your ship. Allowing the landing pad to stay put from time to time would have helped. Or, in lieu of that, making the movement more predictable would also have helped.
Using any of the above, and perhaps combining them, could also have opened up the game play a bit. With each successful landing Computact could have made the game progressively harder. This would make it a challenge without being brutal.
Oh, one more thing, my obsession with random scoring is evident in this game. Check out the score line:
230 LET S=S+INT (RND*10*100)
Beyond the fact that your score is unpredictable, it can be downright cruel. Read that line again. I tried to hide it, but let me make the random part clearer:
INT (RND*1000). Can you see it now? Yep, Computact will gleefully give you a score between 999 and, get this, 0. Not only is the game impossible, but it might give you nothing for your troubles. Don’t follow my example and give out random points. Instead, make games that are challenging, but fun and predictable.
And that, my friends, is Computact, March’s program of the month. A tech demo for string slices wrapped into a completely unfair and horrible game. Sweet and sour to kick off spring. Is that thunder?