Let two people share the keyboard. X goes first, O follows, and the board keeps track of whose mark each square contains. We will stop when it is full; detecting a winning line comes next.
Replace lines 20, 320, 330, 1060.
Add lines 340, 2040, 2100, 2110, 5000, 5010, 5020, 5030, 5040, 7000, 7010.
20 DIM b(9): LET turn=1: LET moves=0
320 LET b(n)=turn: LET moves=moves+1: GO SUB 2000
330 IF moves=9 THEN PRINT AT 18,2;"Board full. R resets. ": GO TO 5000
340 LET turn=3 -turn: GO SUB 7000: GO TO 250
1060 GO SUB 7000
2040 IF b(n)=2 THEN GO TO 2100
2100 INK 7: FOR z=0 TO 1: PLOT x-6,y+10 -z: DRAW 12,0: DRAW 4,-4: DRAW 0,-12: DRAW -4,-4: DRAW -12,0: DRAW -4,4: DRAW 0,12: DRAW 4,4: NEXT z
2110 RETURN
5000 GO SUB 9000
5010 LET k$=INKEY$: IF k$="" THEN GO TO 5010
5020 IF k$="q" OR k$="Q" THEN GO TO 8000
5030 IF k$="r" OR k$="R" THEN RUN
5040 GO TO 5010
7000 LET t$="X": IF turn=2 THEN LET t$="O"
7010 PRINT AT 18,2; INK 7;t$;" to move: choose 1-9. ": RETURNRUN the changed program.
Complete source at this checkpoint
10 BORDER 0: PAPER 0: INK 7: BRIGHT 1: CLS
20 DIM b(9): LET turn=1: LET moves=0
30 GO SUB 1000
40 GO TO 250
250 GO SUB 9000
260 LET k$=INKEY$: IF k$="" THEN GO TO 260
270 IF k$="q" OR k$="Q" THEN GO TO 8000
280 IF k$="r" OR k$="R" THEN RUN
290 IF k$<"1" OR k$>"9" THEN GO TO 250
300 LET n=VAL k$
310 IF b(n)<>0 THEN PRINT AT 18,2; INK 6;"Taken. Choose an empty square.": GO TO 250
320 LET b(n)=turn: LET moves=moves+1: GO SUB 2000
330 IF moves=9 THEN PRINT AT 18,2;"Board full. R resets. ": GO TO 5000
340 LET turn=3 -turn: GO SUB 7000: GO TO 250
1000 CLS
1010 PRINT AT 0,8; INK 5;"THREE IN A ROW"
1030 INK 1: FOR i=0 TO 3: PLOT 56 +i*48,32: DRAW 0,120: NEXT i
1040 FOR i=0 TO 3: PLOT 56,32 +i*40: DRAW 144,0: NEXT i
1050 FOR n=1 TO 9: GO SUB 2000: NEXT n
1060 GO SUB 7000
1090 PRINT AT 21,2; INK 7;"1-9: place R: reset Q: quit"
1100 RETURN
2000 LET row=INT ((n-1)/3): LET col=n-1 -row*3
2010 LET x=80 +col*48: LET y=132 -row*40
2020 PRINT AT 5 +row*5,10 +col*6; INK 7;" "
2030 IF b(n)=0 THEN PRINT AT 5 +row*5,10 +col*6; INK 7;n: RETURN
2040 IF b(n)=2 THEN GO TO 2100
2050 INK 5: FOR z=0 TO 1: PLOT x-10 +z,y-10: DRAW 20,20: PLOT x-10 +z,y+10: DRAW 20,-20: NEXT z
2060 RETURN
2100 INK 7: FOR z=0 TO 1: PLOT x-6,y+10 -z: DRAW 12,0: DRAW 4,-4: DRAW 0,-12: DRAW -4,-4: DRAW -12,0: DRAW -4,4: DRAW 0,12: DRAW 4,4: NEXT z
2110 RETURN
5000 GO SUB 9000
5010 LET k$=INKEY$: IF k$="" THEN GO TO 5010
5020 IF k$="q" OR k$="Q" THEN GO TO 8000
5030 IF k$="r" OR k$="R" THEN RUN
5040 GO TO 5010
7000 LET t$="X": IF turn=2 THEN LET t$="O"
7010 PRINT AT 18,2; INK 7;t$;" to move: choose 1-9. ": RETURN
8000 PAPER 0: INK 7: BRIGHT 0: PRINT AT 21,2;"Three in a Row finished. ": STOP
9000 IF INKEY$<>"" THEN GO TO 9000
9010 RETURNRUN and choose 1, 2 and 3. The top row should contain X, O, X. The caption names the next player. Try choosing an occupied square: it must not spend a turn.
One value changes the player
turn starts at 1. A legal move copies it into b(n), increments moves and draws the mark. 3 - turn switches 1 to 2 or 2 to 1. We change turn only after an accepted move, so an ignored key cannot hand the keyboard to the other player.
The caption routine puts either "X" or "O" in t$ and prints it with the prompt. Spaces at the end erase any longer message that occupied the same row.
The cell routine now branches to line 2100 when the stored value is 2. Its eight DRAW displacements trace an octagon: a short horizontal top, diagonal corner, vertical side and so on back to the start. A second pass, shifted by one pixel, thickens it. X and O have different shapes as well as different colours.
A full board needs a different loop
After nine accepted moves, line 330 displays the full-board message and goes to 5000. That loop listens only for R and Q. Number keys can no longer change the board. R uses RUN, which recreates the empty array and gives X the first turn again.
The routine at 7000 changes the caption; it does not change turn. Keeping that distinction makes the code easier to trace: ask which statement changes the stored value, and which merely displays it.
What will this checkpoint do after X completes a line while some squares are still empty?
Show the explanation
It will hand over to O. We have only taught it to count accepted moves. A person can recognise the line, but no statement yet checks for one.
Play through all nine positions. Hold a key, try a taken square and restart before the board fills. Check that the caption and actual mark always agree.
Sources
Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapter 7, chapter 13, chapter 17.
Run it here
This unit's program, built for you.
- Program
- three.tap
- Machine
- ZX Spectrum 48K (PAL)