Matching Game for the Tandy PC-6
Recently, I was thinking about the differences between various Radio Shack pocket computers and each one’s specific support of BASIC. Some, like the PC-2 are robust and can even be programmed partially or entirely in assembly. Others like the PC-6 for example have quite limited BASIC support.
By limited BASIC support, I am referring to commands supported for various purposes. For example, without bitwise logic support, string manipulation, ASCII conversion, compound conditionals, pixel addressable display, variable sound, and other extended support, there is only so much that can be done with some models.
I was curious how difficult it would be to program a simple game for the PC-6. I picked a rather simple concept to start with, a “matching” game. This experiment is different than my banner program which requires little to no input from the user and the only output is to the printer.
This post is intended for beginner programmers or those curious about programming in general. This is by no means the best example you can find out there, but it is simple enough to get yourself started if you are a beginner.
Gameplay
Before starting the development, some requirements need to be defined. I would like to use the entire screen, which is 24 characters wide. The PC-6 has some good icon characters, including playing card suits and other symbols that can be used as “cards”. Of course for the pocket computer that lacks symbols, you could always use letters and / or numbers for the cards.
The gameplay I settled on is 12 pairs of “cards” are randomly placed in 24 positions on the screen. You have to find the matches. Each time a match is found, those cards disappear. The game ends when all matches are found. A score is tracked which is a count of how many times you flip over a card to find a match. The lower the score, the better.
Press < to move left, > to move right, and the up arrow to flip the selected card.
PC-6 Limits
The PC-6 is not a fast pocket computer. Loops and display updates are very slow. Some buttons cannot be used for input in a program, such as the white arrow keys on the base half of the clamshell.
PC-6 Strengths
The PC-6 has a larger display than many other models – it has 24 characters of width. The PC-6 also has a buzzer. Even though the buzzer support is limited to two predefined tones (low and high), and duration is not adjustable, it is better than nothing (such as the PC-7 and PC-8). The PC-6 has plenty of memory to work with (8 Kb or 16 Kb).
The most obvious limitation is the speed of the pocket computer. The slow speed really challenges the programmer to come up with hacks or clever tricks to keep the game responsive to user input and to update the screen as quickly as possible.
Trial and Error
As with many programming tasks, one starts by building pieces of functionality at a time and toward the end it is strung together with logic and rules. In this case, most of my trial and error was around performance. I needed to update the screen quickly. This proved to be the biggest challenge.
Results
After several iterations and different methods of display updates, I was able to get some fairly responsive performance from the PC-6 matching game.
Final Thoughts
Even though a matching game is quite simple to program, doing so on a pocket computer with limited BASIC support was a challenge. Additionally, doing so with as best response time as possible made it even more-so.
You can do quite a bit with these pocket computers, such as print banners and create other games like blackjack for example. I have mentioned in a previous post on the PC-6 that the assembly support on this model was used to teach students how to program in assembly with a generic processor model. These can be used to teach BASIC programming as well.
Program Listing
I’ve included the PC-6 matching program as a WAV file, if you have a PC-6 and the cassette interface:
LOAD
(or)
LOAD"MATCH"
Below is the listing for the program. I’ve included the comments inline with the program. Only enter the lines with line numbers into the pocket computer – not the “comments”.
Matching Program Version 1.0
Initialize the variables
10 CLEAR : DIM A(24) : DIM B(2)
20 $=“○☐△✕♠︎♣︎♥︎♦︎Ωµσ¥”
Loop to place each card into a random position twice
30 FOR Y = 1 TO 12 : GOSUB 1100 : GOSUB 1100 : NEXT Y
40 GOSUB 1600
Loop for keyboard input
50 U$ = KEY$ : IF U$ = “” THEN 50
60 IF U$ = “U” THEN Z = -1 : GOSUB 190 : GOSUB 1600
70 IF U$ = “P” THEN Z = 1 : GOSUB 190 : GOSUB 1600
75 IF U$ = “↑” THEN GOSUB 1400 : GOSUB 1600
90 GOTO 50
Logic to move in a set direction (Z) and skip over to next card if the current position is blank.
190 S = T
200 IF C = 2 THEN GOSUB 1400
210 T = T + Z : IF T > 23 THEN T = 0 : GOTO 230
220 IF T < 0 THEN T = 23
230 IF A(T) = 0 THEN 210
240 RETURN
Flip over second card - this is used if user uses arrows after second card is shown, it will flip back the second card to hidden state
400 IF C < 2 THEN RETURN
410 GOSUB 1400 : RETURN
Random placement of given card value (Y), using X as a random number between 0 and 23. If a card is already there, then choose a random direction (left or right) and pick the nearest unoccupied slot
1100 X = INT(RAN#*23) : IF A(X) = 0 THEN 1130
1120 Z = INT(RAN#*2)+1 : GOSUB 1200
1130 A(X) = Y : BEEP 0 : PRINT ”▓”; : RETURN
Move left or right until unused space is found
1200 IF Z = 2 THEN Z = -1
1210 X = X + Z : IF X > 23 THEN X=0 : GOTO 1230
1220 IF X < 0 THEN X = 23
1230 IF A(X) > 0 THEN 1210
1240 RETURN
Flip card at position T and check for match
1400 IF A(T) < 0 THEN B(C) = 0 : C = C - 1 : A(T) = A(T) * -1 : RETURN
1410 IF C = 2 THEN RETURN
1415 PRINT CSRT; MID$(A(T), 1);
1420 B(C) = T + 1 : A(T) = A(T) * -1 : C = C + 1 : E = E + 1 : BEEP 0
1425 IF C = 1 THEN 1490
1430 IF A(B(0) - 1) != A(B(1) - 1) THEN 1490
1433 PRINT CSRB(0) - 1; ” “; CSRB(1) - 1; ” “;
1435 A(B(0) - 1) = 0 : A(B(1) - 1) = 0 : C = 0 : D = D + 1
1440 IF D = 12 THEN 1800
1450 GOSUB 200
1480 GOSUB 1700
1490 GOSUB 1600
1500 RETURN
Update display based on T (current cursor) and S (previous cursor)
1600 IF S = T THEN 1640
1605 IF A(S) < 0 THEN PRINT CSRS; MID$(A(S) * -1, 1);
1620 IF A(S) > 0 THEN PRINT CSRS; ”▓“;
1640 IF A(T) > 0 THEN PRINT CSRT; ”?“;
1650 RETURN
Beep Sequence
1700 BEEP 1 : BEEP 0 : BEEP 1 : RETURN
End of Game
1800 GOSUB 1700 : GOSUB 1700 : PRINT CSR0; ”Score: “; E; : END
Variables Used
$ - Special variable, holds picture representation of the cards.
A(24) - array of chosen cards. Value is the index into the $ array.
B(2) - chosen card indexes
C - chosen card count
D - count of total matches found
E - card flip count (score)
S - previous cursor location
T - cursor location
U$ - keyboard input
X - index into card array, random
Y - loop for each card for placement
Z - direction for moving (+/- 1)