--- title: "Draughts" id: 56780 type: "computer_media" slug: "draughts" url: "http://localhost/computer_media/draughts/" markdown_url: "http://localhost/computer_media/draughts.md" published_at: "2024-09-29T01:49:39+00:00" modified_at: "2026-04-04T20:17:46+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/294_Drau.png" excerpt: "A complete checkers game with capture logic, king promotion, and a computer opponent that tries to avoid leaving its pieces vulnerable — all in BASIC." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" - name: "Games" slug: "games" taxonomy: "category" url: "http://localhost/category/software/games/" 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/294_Drau.png" media_type_tags: "Game" --- Draughts is a two-player checkers game for a single human opponent against the computer, requiring 16K of RAM. The board is represented as a one-dimensional array `A(100)` with only certain indices used to model the diagonal playable squares, and piece types are stored as character codes (e.g., `H=189`, `C=180`, `W=188`, `K=176`, `B=128`) so they can be printed directly with `CHR$`. User input uses a letter-number coordinate system (e.g., “A2”), which is decoded by computing `CODE B$(1)*10+CODE B$(2)` and mapping through a long chain of IF statements to internal array indices. The computer’s move logic includes a capture-priority routine, a positional look-ahead that checks for unsafe moves, and a fallback random-move generator using a shuffled index array `I(49)`. Kings are promoted automatically when a computer piece reaches row A, and the game tracks captured pieces for both sides with score counters `S` and `T`. *** ## Program Analysis ### Program Structure The program is organized into clearly delineated sections, each beginning at a round line number: - **Lines 5–70:** Initialization and first-move selection. - **Lines 1000–1460:** Human move input and coordinate decoding. - **Lines 2000–2490:** Computer move logic — capture, intelligent move, and random move phases. - **Lines 7000–7320:** Board display subroutine. - **Lines 8000–8050:** Capture-check subroutine. - **Lines 9000–9420:** Initialization, board setup, and SAVE block. ### Board Representation The board is stored in a one-dimensional array `A(100)`. Only a subset of indices — those mapping to playable dark squares — are used; out-of-bounds and non-playable cells are filled with `9` as a sentinel value. The diagonal neighbor offsets are held in `X(4)` with values `-6`, `-7`, `6`, and `7`, reflecting the staggered layout of usable indices across alternating rows of four. Piece types are stored as character code integers so they can be printed directly via `CHR$`: | Variable | Value | Meaning | | --- | --- | --- | | `H` | 189 | Human man | | `W` | 188 | Human king | | `C` | 180 | Computer man | | `K` | 176 | Computer king | | `B` | 128 | Empty square | | `9` | 9 | Off-board sentinel | ### Coordinate Decoding Human input is a two-character string such as `"A2"`. The program computes `CODE B$(1)*10+CODE C$(2)` to produce a two-or-three digit numeric key (e.g., `410` for A1), then maps each key to an internal array index through a chain of 32 `IF` statements (lines 1090–1400). This approach avoids any arithmetic formula for the irregular index layout and handles the two-dimensional coordinate system entirely through lookup. ### Computer Move Logic The computer’s turn is handled in three prioritized phases: 1. **Forced captures (lines 2000–2210):** Iterates over all computer pieces; calls subroutine 8000 to check whether a jump is available from square `Z`. If so, executes the capture, updates scores in `S`, clears the jumped piece, redraws the board, and loops to check for chain captures. 2. **Intelligent move (lines 2240–2345):** Scans all computer pieces and for each diagonal direction checks whether moving there would expose the piece to immediate recapture, or whether it can move a piece that is already under threat. The condition on line 2280–2290 implements rudimentary positional avoidance. 3. **Random move (lines 2348–2490):** Builds an array `I(49)` of all valid board indices, then repeatedly draws random entries (removing each after selection via a swap-and-shrink technique) until a legal move is found. A flag `IT` tracks whether the “safe-move” filter is active; on the second pass (`IT=1`) the safety check is skipped. If no move is found at all, `E$="LOSE"` is set and the game ends with a concession message. ### Subroutines Subroutine at line **8000** checks all four diagonal directions from square `Z` for a valid capture: an enemy piece adjacent and an empty square beyond. It respects piece type — men only move in directions `D=1,2` (indices 1–2 in `X`), while kings use all four. The result is returned in `Q` (the offset of the jump direction, or 0 if none). Subroutine at line **7000** redraws the full board display using `PRINT AT` with `CHR$` of each array cell value, displays captured-piece tallies using `CHR$ (S+156)` and `CHR$ (T+156)` (block graphics characters whose density represents count), checks win/lose/concede conditions, and optionally prompts for a chain-jump continuation. ### King Promotion Computer men reaching the human’s back row (squares 69–72) are promoted to kings at line 2005: `IF A(Z)=H THEN LET A(Z)=W` — note this promotes *human* pieces that reach the computer’s back row (rows A, i.e., indices 69–72). Computer man promotion to king (`C` → `K`) is handled at line 2030 when a computer piece occupies indices 24–27 (the human’s home row). ### Notable Techniques - The random-move picker uses a *partial Fisher-Yates* style draw: `I(Y)=I(N)` followed by `N=N-1` ensures each board square is tried at most once without a full shuffle. - `FAST` / `SLOW` mode switching is used strategically — display updates run in SLOW for visible rendering; computation runs in FAST. - The move-legality check for the human relies entirely on the player entering correct notation; there is no validation of whether the input square actually contains a human piece or whether the destination is legal, meaning illegal moves are silently accepted. - The midpoint formula `(B(1)+B(2))/2` at line 1460 to find the captured piece’s square is only valid when the jump distance is exactly one step (offset 6 or 7). Multi-step captures by the human are not detected automatically — the game prompts “CAN YOU JUMP AGAIN?” and relies on the human to input the continuation. - Line 1200 appears to be a bug: both `Z(U)=432` and `Z(U)=436` map to `B(U)=56`, which means coordinate B4 and B6 map to the same internal square. The correct value for B4 should likely be `58` (one of the row-B indices), suggesting a transcription error in the coordinate table. ### Initialization Lines 9000–9390 allocate all arrays, set piece-code constants, place pieces on the board by filtering index ranges with multiple `AND` conditions to skip non-playable cells, and offer the human the choice of moving first. If the computer moves first, it makes a simple random opening move by picking from indices near the center of its starting rows. ## Source Code ``` 5 REM DRAUGHTS-16K 10 FAST 20 RAND 30 GOSUB 9000 50 LET MOVE=0 60 GOSUB 7000 70 SLOW 1000 IF C$(1)="K" THEN GOTO 1010 1005 PRINT AT 16,3;"YOUR LAST MOVE WAS TO ";C$ 1010 LET MOVE=0 1015 PRINT AT 17,4;"THIS MOVE ? LETTER,NO. " 1020 INPUT B$ 1030 PRINT AT 17,14;" FROM ";B$;" TO ? " 1040 INPUT C$ 1050 PRINT AT 17,25;" ";C$,"[S][T][A][N][D]█[B][Y]" 1060 LET Z(1)=CODE B$(1)*10+CODE B$(2) 1070 LET Z(2)=CODE C$(1)*10+CODE C$(2) 1080 FOR U=1 TO 2 1090 IF Z(U)=410 THEN LET B(U)=72 1100 IF Z(U)=412 THEN LET B(U)=71 1110 IF Z(U)=414 THEN LET B(U)=70 1120 IF Z(U)=416 THEN LET B(U)=69 1130 IF Z(U)=419 THEN LET B(U)=66 1140 IF Z(U)=421 THEN LET B(U)=65 1150 IF Z(U)=423 THEN LET B(U)=64 1160 IF Z(U)=425 THEN LET B(U)=63 1170 IF Z(U)=430 THEN LET B(U)=59 1180 IF Z(U)=432 THEN LET B(U)=56 1190 IF Z(U)=434 THEN LET B(U)=57 1200 IF Z(U)=436 THEN LET B(U)=56 1210 IF Z(U)=439 THEN LET B(U)=53 1220 IF Z(U)=441 THEN LET B(U)=52 1230 IF Z(U)=443 THEN LET B(U)=51 1240 IF Z(U)=445 THEN LET B(U)=50 1250 IF Z(U)=450 THEN LET B(U)=46 1260 IF Z(U)=452 THEN LET B(U)=45 1270 IF Z(U)=454 THEN LET B(U)=44 1280 IF Z(U)=456 THEN LET B(U)=43 1290 IF Z(U)=459 THEN LET B(U)=40 1300 IF Z(U)=461 THEN LET B(U)=39 1310 IF Z(U)=463 THEN LET B(U)=38 1320 IF Z(U)=465 THEN LET B(U)=37 1330 IF Z(U)=470 THEN LET B(U)=33 1340 IF Z(U)=472 THEN LET B(U)=32 1350 IF Z(U)=474 THEN LET B(U)=31 1360 IF Z(U)=476 THEN LET B(U)=30 1370 IF Z(U)=479 THEN LET B(U)=27 1380 IF Z(U)=481 THEN LET B(U)=26 1390 IF Z(U)=483 THEN LET B(U)=25 1400 IF Z(U)=485 THEN LET B(U)=24 1410 NEXT U 1420 LET MOVE=0 1430 LET A(B(2))=A(B(1)) 1440 LET A(B(1))=B 1450 IF ABS (B(1)-B(2))>7 THEN LET MOVE=1 1460 IF ABS (B(1)-B(2))>7 THEN LET A((B(1)+B(2))/2)=B 1465 FAST 1470 GOSUB 7000 2000 REM [C][A][P][T][U][R][E] 2002 LET Q=0 2004 FOR Z=69 TO 72 2005 IF A(Z)=H THEN LET A(Z)=W 2007 NEXT Z 2009 FOR Z=24 TO 72 2020 IF A(Z)<>C AND A(Z)<>K THEN GOTO 2110 2030 IF A(Z)=C AND Z>23 AND Z<28 THEN LET A(Z)=K 2040 GOSUB 8000 2080 IF Q<>0 THEN GOTO 2125 2110 NEXT Z 2120 GOTO 2240 2125 LET A(Z+2*Q)=A(Z) 2130 LET S=S+1 2135 LET A(Z+Q)=B 2145 LET A(Z)=B 2150 GOSUB 7000 2155 LET Z=Z+2*Q 2160 LET Q=0 2170 GOSUB 8000 2190 IF Q<>0 THEN GOTO 2125 2210 GOTO 50 2235 REM [I][N][T][E][L][L][I][G][E][N][T]█[M][O][V][E] 2240 FOR Z=24 TO 72 2250 IF A(Z)=9 OR A(Z)=B OR A(Z)=H OR A(Z)=W THEN GOTO 2305 2260 FOR D=1 TO 4 2270 IF A(Z+X(D))=H AND D<3 THEN GOTO 2290 2280 IF (A(Z+X(D))=H OR A(Z+X(D))=W) AND A(Z-X(D))=B AND A(Z-2*X(D))=K THEN LET Q=Z-2*X(D) 2290 IF Q=0 AND (A(Z+X(D))=H OR A(Z+X(D))=W) AND A(Z-X(D))=B AND (A(Z-2*X(D))=K OR A(Z-2*X(D))=C) THEN LET Q=Z-2*X(D) 2300 IF Q=0 THEN NEXT D 2305 IF Q=0 THEN NEXT Z 2310 IF Q=0 THEN GOTO 2348 2320 LET A(Q+X(D))=A(Q) 2330 LET A(Q)=B 2340 GOSUB 7000 2345 GOTO 50 2347 REM [R][A][N][D][O][M]█[M][O][V][E] 2348 FAST 2349 LET IT=0 2350 DIM I(49) 2355 FOR J=1 TO 49 2360 LET I(J)=J+23 2365 NEXT J 2370 LET N=49 2373 LET Y=1+INT (RND*N) 2375 LET Z=I(Y) 2380 IF A(Z)=9 OR A(Z)=B OR A(Z)=H OR A(Z)=W THEN GOTO 2430 2390 FOR D=1 TO 4 2400 IF A(Z)=C AND D>2 THEN GOTO 2430 2404 IF IT=1 THEN GOTO 2410 2406 IF A(Z+X(D))=B AND A(Z+2*X(D))<>H AND A(Z+2*X(D))<>W AND A(Z+13*SGN X(D))<>H AND A(Z+13*SGN X(D))<>W AND A(Z-1+2*(ABS (D-25)>1))<>H AND A(Z-1+2*(ABS (D-25)>1))<>W THEN LET Q=X(D) 2408 GOTO 2420 2410 IF A(Z+X(D))=B THEN LET Q=X(D) 2420 IF Q<>0 THEN GOTO 2460 2425 NEXT D 2430 LET I(Y)=I(N) 2433 LET N=N-1 2436 IF N>0 THEN GOTO 2373 2438 LET IT=IT+1 2439 IF IT=1 THEN GOTO 2355 2440 LET E$="LOSE" 2450 GOTO 7000 2460 LET A(Z+Q)=A(Z) 2470 LET A(Z)=B 2490 GOTO 50 7000 REM [P][R][I][N][T]█[B][O][A][R][D] 7005 SLOW 7007 PAUSE 250 7010 PRINT AT 16,0;" " 7020 PRINT AT 17,0;" " 7030 IF MOVE=1 THEN LET T=T+1 7090 PRINT AT 2,4;"[C][O][M][P][U][T][E][R] ";CHR$ (S+156)," [H][U][M][A][N] ";CHR$ (T+156) 7100 PRINT AT 4,8;"█▒[1][2][3][4][5][6][7][8]▒█" 7110 PRINT AT 5,8;"[A]▒ ";CHR$ A(72);" ";CHR$ A(71);" ";CHR$ A(70);" ";CHR$ A(69);"▒[A]" 7120 PRINT AT 6,8;"[B]▒";CHR$ A(66);" ";CHR$ A(65);" ";CHR$ A(64);" ";CHR$ A(63);" ▒[B]" 7130 PRINT AT 7,8;"[C]▒ ";CHR$ A(59);" ";CHR$ A(58);" ";CHR$ A(57);" ";CHR$ A(56);"▒[C]" 7140 PRINT AT 8,8;"[D]▒";CHR$ A(53);" ";CHR$ A(52);" ";CHR$ A(51);" ";CHR$ A(50);" ▒[D]" 7150 PRINT AT 9,8;"[E]▒ ";CHR$ A(46);" ";CHR$ A(45);" ";CHR$ A(44);" ";CHR$ A(43);"▒[E]" 7160 PRINT AT 10,8;"[F]▒";CHR$ A(40);" ";CHR$ A(39);" ";CHR$ A(38);" ";CHR$ A(37);" ▒[F]" 7170 PRINT AT 11,8;"[G]▒ ";CHR$ A(33);" ";CHR$ A(32);" ";CHR$ A(31);" ";CHR$ A(30);"▒[G]" 7180 PRINT AT 12,8;"[H]▒";CHR$ A(27);" ";CHR$ A(26);" ";CHR$ A(25);" ";CHR$ A(24);" ▒[H]" 7190 PRINT AT 13,8;"█▒[1][2][3][4][5][6][7][8]▒█" 7195 FAST 7210 IF E$="LOSE" THEN PRINT AT 17,7;"[I]█[C][O][N][C][E][D][E]█[T][H][E]█[G][A][M][E]" 7220 IF E$="LOSE" THEN STOP 7230 IF S>=12 THEN PRINT AT 17,12;"[I]█[W][I][N]" 7240 IF T>=12 THEN PRINT AT 17,10;"[Y][O][U]█[W][I][N]" 7250 IF S>=12 OR T>=12 THEN STOP 7260 LET U$="" 7270 IF MOVE=1 THEN PRINT AT 15,2;"CAN YOU JUMP AGAIN?(Y OR N)" 7280 IF MOVE=1 THEN INPUT U$ 7290 PRINT AT 15,2;" " 7300 LET MOVE=0 7310 IF U$="Y" THEN GOTO 1000 7320 RETURN 8000 FOR D=1 TO 4 8010 IF A(Z)<>K AND D>2 THEN GOTO 8050 8020 IF (A(Z+X(D))=H OR A(Z+X(D))=W) AND A(Z+2*X(D))=B THEN LET Q=X(D) 8030 IF Q<>0 THEN GOTO 8050 8040 NEXT D 8050 RETURN 9000 DIM A(100) 9005 LET Y=0 9010 DIM X(4) 9020 LET X(1)=-6 9030 LET X(2)=-7 9040 LET X(3)=6 9050 LET X(4)=7 9060 LET H=189 9070 LET C=180 9080 LET W=188 9090 LET K=176 9100 LET B=128 9105 LET Q=0 9110 FOR Z=1 TO 100 9120 LET A(Z)=9 9130 IF Z<73 AND Z>55 AND Z<>67 AND Z<>68 AND Z<>60 AND Z<>61 AND Z<>62 THEN LET A(Z)=C 9140 IF Z<54 AND Z>42 AND Z<>47 AND Z<>48 AND Z<>49 THEN LET A(Z)=B 9150 IF Z<41 AND Z>23 AND Z<>34 AND Z<>35 AND Z<>36 AND Z<>28 AND Z<>29 THEN LET A(Z)=H 9160 NEXT Z 9170 LET E$="" 9180 LET S=0 9190 LET T=0 9210 DIM B$(2) 9220 DIM C$(2) 9225 LET C$(1)="K" 9230 DIM Z(2) 9240 DIM B(2) 9300 PRINT AT 10,4;"[D][O]█[Y][O][U]█[W][A][N][T]█[T][H][E]█[F][I][R][S][T]█[M][O][V][E][?]";TAB 9;" [Y]█[O][R]█[N][?] " 9310 INPUT Y$ 9320 CLS 9330 IF Y$="Y" THEN RETURN 9335 LET MOVE=0 9340 GOSUB 7000 9350 LET Z=57+INT (RND*3) 9360 LET Q=-7+INT (RND*2) 9370 LET A(Z+Q)=C 9380 LET A(Z)=B 9390 RETURN 9400 CLEAR 9410 SAVE "1029[4]" 9420 RUN ```