This program implements a draughts (checkers) board game on an 80-cell memory-mapped display area starting at address 16516. The board state is stored directly in PEEK/POKE operations on the display file, using specific byte values (61 for one piece type, 13 and 52/12 for others) to represent pieces and board squares. The direction array D(4) encodes the four diagonal move offsets (11, 9, −9, −11) corresponding to the four diagonal directions on a 9- or 11-wide board layout. The computer’s move logic scans the display memory for valid captures (lines 60–110) before falling back to random single-step moves (lines 120–180), and the human player enters moves by specifying source and destination cell numbers which are translated to memory addresses.
Program Analysis
Program Structure
The program divides into three logical sections:
- Initialisation (line 5000–5200): Sets up the direction array, copies board data from ROM/memory into the display area, seeds the RNG, and returns to begin play.
- Computer move logic (lines 55–390): First attempts a capturing move, then falls back to a random non-capturing move.
- Human move input and display (lines 200–480): Prompts for source and destination square numbers, validates the move, updates memory, and redraws the board.
Memory-Mapped Board Representation
The board is stored entirely within the ZX81 display file. The 80-cell region from address 16517 to 16616 (printed at lines 440–470) represents the playable squares. Cell values use specific byte codes:
| Value | Meaning |
|---|---|
| 61 | Computer piece (SPACE in ZX81 character set = empty cell marker, repurposed) |
| 13 | Computer piece (promoted / king) |
| 52 | Human piece |
| 12 | Human piece (promoted / king) |
| 0 | Empty square |
The board initialisation at lines 5050–5070 copies 100 bytes from address 16626 downward into 16517, seeding the initial piece layout from pre-existing memory content — an unusual but compact technique that avoids explicit POKE statements for every starting square.
Direction Array and Move Offsets
The array D(4) stores the four diagonal offsets: 11, 9, −9, −11. These correspond to forward-left, forward-right, backward-right, and backward-left moves on a board stored in a linear memory region approximately 9–11 cells wide per row. The subroutine at line 20 uses B as the current cell address and X as the direction index, peeking the current cell (R), the adjacent cell (S = PEEK(B+D(X))), and the cell two steps away (T = PEEK(B+2*D(X))).
Computer AI Logic
The computer’s turn proceeds in two phases:
- Capture scan (lines 55–110): Iterates over all 80 board cells. For each cell containing a computer piece (
R=61for normal,R=13for king), it checks whether an adjacent cell holds a human piece (S=52orS=12) and the cell beyond is empty (T=0). If found, execution jumps to line 300 to execute the capture. - Random move (lines 120–180): Up to 400 attempts are made to find a computer piece with an empty adjacent cell (
S=0), then the piece is moved there.
The capture routine at lines 300–390 implements chain captures: after performing a capture it loops back via GOTO 300 to check whether another capture is immediately available from the new position, continuing until no further captures exist.
Promotion (Kinging)
Line 420 checks whether a moved computer piece has reached or passed address 16597 (the far end of the board) and if so, POKEs value 13 to mark it as a king. The equivalent check for the human player is handled at line 230, which POKEs 12 if the destination index is less than 20 (i.e., reached the computer’s back row).
Human Move Input
The human enters moves as square numbers. The program converts these by adding 16516 to obtain the actual memory address (lines 220, 240). The midpoint between source and destination is computed at line 250 — (H+G)/2 — and if the distance is 18 or 22 (the two possible jump distances in this layout), the intermediate cell is cleared to remove the captured piece.
Display Refresh
The board is redrawn at lines 430–472 by reading bytes directly from memory addresses 16517–16616 and printing them via CHR$. Line 460 uses the idiom 10*INT((A+4)/10)=A+4 to detect every tenth cell (end of row), printing a TAB 8 to begin the next row at column 8. The display is anchored at PRINT AT 6,8.
Notable Techniques and Idioms
- FAST/SLOW switching (lines 12, 200, 285, 425) is used to suppress the display flicker during computation-heavy sections while restoring normal display during human interaction.
RANDat line 5100 (no argument) re-seeds the random number generator, ensuring varied computer openings each game.- The
Zflag (set to 1 at line 5080) allows line 475 to jump back to the capture scan after a human move, enabling the computer to immediately search for captures rather than going through the full initialisation again. - The subroutine at line 20 (lines 20–50) is called repeatedly within tight loops — a clean factoring of the three-cell lookahead used by both the capture and random-move phases.
Potential Bugs and Anomalies
- Line 230 contains
POKE H=16516,12, which is syntactically unusual — this likely should bePOKE H+16516,12orPOKE 16516+H,12. As written, it evaluates the Boolean expressionH=16516(0 or 1) as the POKE address, almost certainly a typo for the promotion POKE. - The board initialisation (lines 5050–5070) relies on specific content at addresses
16626–16725that is not set by the program itself. This content must exist in memory prior to execution, suggesting the program is intended to be loaded as a saved file where that memory region already contains the board layout. - No bounds checking is performed on human-entered values
GandH, so invalid input could POKE arbitrary memory locations.
Content
Source Code
10 REM AAA% 23456789% 1% X% X% X% X12X% X% X% X% 23% % X% X% X34 % X% % % 45% % % % 56O% O% O% O% 67% O% O% O% O78O% O% O% O% 8% 23456789%
11 REM AAA% 23456789% 1% X% X% X% X12X% X% X% X% 23% X% X% X% X34 % % % % 45% % % % 56O% O% O% O% 67% O% O% O% O78O% O% O% O% 8% 23456789%
12 FAST
17 GOSUB 5000
19 GOTO 430
20 LET R=PEEK B
30 LET S=PEEK (B+D(X))
40 LET T=PEEK (B+2*D(X))
50 RETURN
55 LET Z=0
60 FOR B=16528 TO 16607
70 FOR X=1 TO 4
80 GOSUB 20
90 IF ((X<3 AND R=61) OR R=13) AND (S=52 OR S=12) AND T=0 THEN GOTO 300
100 NEXT X
110 NEXT B
120 FOR A=1 TO 400
130 LET B=INT (RND*80)+16528
140 FOR X=1 TO 4
150 GOSUB 20
160 IF ((X<3 AND R=61) OR R=13) AND S=0 THEN GOTO 400
170 NEXT X
180 NEXT A
190 PRINT "YOU WIN";Q
200 SLOW
202 PRINT AT 0,0;"FROM ?"
205 INPUT G
207 PRINT AT 0,4;" ";G;" TO ?"
210 INPUT H
215 PRINT AT 0,0;" "
220 POKE 16516+H,PEEK (G+16516)
230 IF H<20 THEN POKE H=16516,12
240 POKE 16516+G,0
250 IF ABS (H-G)=18 OR ABS (H-G)=22 THEN POKE 16516+(H+G)/2,0
260 PRINT AT 17,0;"CAN YOU MOVE AGAIN ?"
270 INPUT A$
275 PRINT AT 17,0;" "
280 IF A$<>"" THEN GOTO 430
285 FAST
290 GOTO 60
300 POKE B+2*D(X),R
310 POKE B,0
320 POKE B+D(X),0
330 LET B=B+2*D(X)
340 IF B>16597 THEN GOTO 490
350 FOR X=1 TO 4
360 GOSUB 20
370 IF ((X<3 AND R=61) OR R=13) AND (S=52 OR S=12) AND T=0 THEN GOTO 300
380 NEXT X
390 GOTO 430
400 POKE B+D(X),R
410 POKE B,0
420 IF B+D(X)>16597 THEN POKE B+D(X),13
425 SLOW
430 PRINT AT 6,8;
440 FOR A=16517 TO 16616
450 PRINT CHR$ (PEEK A);
460 IF 10*INT ((A+4)/10)=A+4 THEN PRINT TAB 8;
470 NEXT A
472 PRINT
475 IF Z=1 THEN GOTO 55
480 GOTO 200
490 POKE B,13
500 GOTO 430
\n5000 DIM D(4)
\n5010 LET D(1)=11
\n5020 LET D(2)=9
\n5030 LET D(3)=-9
\n5040 LET D(4)=-11
\n5050 FOR J=16626 TO 16725
\n5060 POKE J-109,PEEK J
\n5070 NEXT J
\n5080 LET Z=1
\n5100 RAND
\n5200 RETURN
\n5210 CLEAR
\n5220 SAVE "1033%0"
\n5230 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
