--- title: "Checkers" id: 56862 type: "computer_media" slug: "checkers" url: "http://localhost/computer_media/checkers/" markdown_url: "http://localhost/computer_media/checkers.md" published_at: "2024-09-29T12:24:02+00:00" modified_at: "2026-04-03T07:58:48+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/330_Chec.png" excerpt: "A draughts game that stores its entire board state directly in display memory, using PEEK and POKE to move pieces and hunt for captures automatically." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 56738 title: "Timex Sinclair Public Domain Library Tape 1007" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1007/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/09/330_Chec.png" media_type_tags: "Game" --- 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: 1. **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. 2. **Computer move logic (lines 55–390):** First attempts a capturing move, then falls back to a random non-capturing move. 3. **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=61` for normal, `R=13` for king), it checks whether an adjacent cell holds a human piece (`S=52` or `S=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. - `RAND` at line 5100 (no argument) re-seeds the random number generator, ensuring varied computer openings each game. - The `Z` flag (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 be `POKE H+16516,12` or `POKE 16516+H,12`. As written, it evaluates the Boolean expression `H=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`–`16725` that 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 `G` and `H`, so invalid input could POKE arbitrary memory locations. ## 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 5000 DIM D(4) 5010 LET D(1)=11 5020 LET D(2)=9 5030 LET D(3)=-9 5040 LET D(4)=-11 5050 FOR J=16626 TO 16725 5060 POKE J-109,PEEK J 5070 NEXT J 5080 LET Z=1 5100 RAND 5200 RETURN 5210 CLEAR 5220 SAVE "1033%0" 5230 RUN ```