Devon Demon

Date: 198x
Type: Cassette
Platform(s): TS 1000
Tags: Game

This program implements a diagonal draughts (checkers) variant called “Devon Demon,” a two-player abstract strategy game where the human plays “X” and the computer plays “O.” The board state is stored directly in memory starting at address 16513, using PEEK and POKE to read and write piece positions, with character codes 52, 61, 27, and 128 representing different board cell states. Lines 30–50 use a self-modifying bootstrap technique: they copy 36 bytes of board-state data from the REM statements at lines 10–20 (offset +42 from address 16514) into the working board area. The computer’s move logic uses a direction array B() with offsets ±5 and ±7 corresponding to diagonal moves on a 6-column board, and includes boundary detection and a simple capture-seeking heuristic.


Program Analysis

Program Structure

The program is divided into three broad phases:

  1. Bootstrap (lines 10–55): Copies initial board data from the REM statements into the working board area in memory, then jumps to the title/instructions routine.
  2. Instructions (lines 1000–1090): Displays the game title and rules, waits for NEWLINE, then jumps to game initialisation at line 60.
  3. Game loop (lines 60–710): Initialises state, handles display, processes human and computer moves, and detects win conditions.

Bootstrap and REM-Based Data Storage

Lines 10 and 20 contain REM statements whose character data encodes the initial board layout. The loop at lines 30–50 copies 36 bytes from address 16514+42 = 16556 (inside the REM statement body) to addresses 16514 through 16549, which form the working board array starting at Z=16513 (so cells are at Z+1 through Z+36). This is a classic ZX81 technique for embedding binary or character data inside REM lines to avoid the overhead of DATA/READ statements.

Board Representation

The board is a 6×6 grid stored as 36 consecutive bytes in RAM from address Z+1 to Z+36. Character codes encode cell contents:

CodeMeaning
52Computer piece (“O”)
61Human piece (“X”)
27Empty square
128Temporary marker during computer move animation

The board is displayed by printing CHR$ PEEK (Z+C) for each cell, relying on the ZX81 character set to render the appropriate glyphs. Column labels A–F are derived by printing CHR$ (C/6+37) at every sixth cell (line 240), and row numbers “1 2 3 4 5 6” are printed at line 260.

Move Input Parsing

The human enters a four-character string such as “A1B2”. Line 340 decodes the source square: D = 6*(CODE A$(1)-38) + CODE(A$(2))-28. Since “A” has ZX81 code 38, CODE A$(1)-38 gives the column index 0–5, multiplied by 6 for the row offset. CODE(A$(2))-28 converts the digit character (“1″=29 in ZX81) to 1–6. Line 350 performs the same calculation for the destination square into E. If the destination holds a computer piece (code 52), the human’s score is incremented (line 360).

Direction Array and Diagonal Movement

Array B() holds four diagonal offsets for a 6-column board:

  • B(1)=5 — diagonal down-left
  • B(2)=7 — diagonal down-right
  • B(3)=-5 — diagonal up-right
  • B(4)=-7 — diagonal up-left

These offsets reflect the fact that adjacent diagonal cells differ by 5 or 7 positions in the linear board array on a 6-wide grid (not the expected ±5/±7 for a standard 8-wide board, since rows are 6 cells wide here).

Computer AI

The computer’s move selection (lines 490–590) works as follows:

  1. Pick a random board cell F; retry if it does not contain a computer piece (code 52).
  2. With 80% probability, select a random direction M from 1–4 (line 530).
  3. Apply boundary guards (lines 540–550) to prevent wrapping off the left or right edges of the board.
  4. At line 560, check if the cell at F+B(M) is an empty square (27) and the cell beyond it (F+2*B(M)) is not a human piece (61) — if this multi-hop condition is met, jump directly to the capture/move execution at line 620.
  5. If the direction is invalid, increment M and try the next; after exhausting all four directions, retry with a new random piece (up to 200 attempts via line 590).

Lines 450–460 also check whether any computer piece can immediately capture a human piece (land on a cell containing 61), providing a simple opportunistic capture before the random-move fallback.

Win Detection

The human wins when S=4 (four computer pieces captured, line 410). The computer wins when N=4 (four human pieces captured, line 650). Both conditions print a result message and STOP.

Notable Techniques and Anomalies

  • SLOW/FAST switching: The program toggles between SLOW (display-on) and FAST (display-off) modes around display and computation phases to balance responsiveness and speed.
  • Score variable redundancy: LET S=0 appears twice (lines 80 and 90), which is harmless but redundant.
  • Loop variable reuse: Variable M is used both as a direction index within the AI loop and as a loop counter in FOR/NEXT at line 440, which could cause confusion but works because the FOR loop at 440 is always completed before M is reassigned at line 490.
  • Boundary detection coverage: The edge guards at lines 540–550 only cover specific column positions (F=6,16,30 and F=7,19,31), which correspond to the rightmost and leftmost cells of rows on a 6-wide board. This approach is functional but fragile—it would fail for board sizes other than 6.
  • INKEY$ wait idiom: Lines 1060–1070 first flush any held keypress, then wait for NEWLINE (CHR$ 118), a standard ZX81 debounce pattern.
  • Counter K: K is incremented at line 510 during the AI’s random-piece search and checked at line 590 (IF M<200), but M rather than K is the variable tested — this means the 200-iteration guard on line 590 actually checks the direction index, not the attempt count, making it effectively always true for a legal board state. The intended exhaustion guard on K is never used.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Source Code

  10 REM .X.X.XX.X.X..............O.O.OO.O.O.
  20 REM .X.X.XX.X.X..............O.O.OO.O.O.
  30 FOR K=16514 TO 16549
  40 POKE K,PEEK (K+42)
  50 NEXT K
  54 SLOW 
  55 GOTO 1000
  60 LET N=0
  70 LET Z=16513
  80 LET S=0
  90 LET S=0
 100 DIM B(4)
 110 LET B(1)=5
 120 LET B(2)=7
 130 LET B(3)=-5
 140 LET B(4)=-7
 150 SLOW 
 160 LET K=0
 170 GOSUB 200
 180 FAST 
 190 GOTO 490
 200 PRINT AT 5,0;"TIMEX-";N,"HUMAN-";S
 210 PRINT 
 220 FOR C=1 TO 36
 230 PRINT CHR$ PEEK (Z+C);" ";
 240 IF 6*(INT (C/6))=C THEN PRINT CHR$ (C/6+37)
 250 NEXT C
 260 PRINT "1 2 3 4 5 6"
 270 FOR H=1 TO 30
 280 NEXT H
 290 RETURN 
 300 GOSUB 200
 310 SLOW 
 320 PRINT "YOUR MOVE?"
 330 INPUT A$
 340 LET D=6*(CODE A$(1)-38)+CODE (A$(2))-28
 350 LET E=6*(CODE A$(3)-38)+CODE (A$(4))-28
 360 IF PEEK (E+Z)=52 THEN LET S=S+1
 370 POKE (D+Z),27
 380 POKE (E+Z),61
 390 GOSUB 200
 400 FAST 
 410 IF S=4 THEN GOTO 600
 420 LET K=0
 430 FOR F=1 TO 36
 440 FOR M=1 TO 4
 450 IF PEEK (F+Z)=52 AND PEEK (F+Z+B(M))=61 THEN LET N=N+1
 460 IF PEEK (F+Z)=52 AND PEEK (F+Z+B(M))=61 THEN GOTO 620
 470 NEXT M
 480 NEXT F
 490 LET M=1
 500 LET F=INT (RND*36)+1
 510 LET K=K+1
 520 IF PEEK (F+Z)<>52 THEN GOTO 500
 530 IF RND>.2 AND M<3 THEN LET M=4-(INT (RND*4))
 540 IF (F=6 OR F=16 OR F=30) AND (M=2 OR M=3) THEN GOTO 570
 550 IF (F=31 OR F=19 OR F=7) AND (M=1 OR M=4) THEN GOTO 570
 560 IF PEEK (F+Z+B(M))=27 AND PEEK (F+Z+2*B(M))<>61 THEN GOTO 620
 570 LET M=M+1
 580 IF M<5 THEN GOTO 540
 590 IF M<200 THEN GOTO 490
 600 PRINT "YOU WIN"
 610 STOP 
 620 SLOW 
 630 POKE (F+Z+B(M)),128
 640 GOSUB 200
 650 IF N=4 THEN GOTO 700
 660 POKE (F+Z),27
 670 POKE (F+Z+B(M)),52
 680 GOTO 300
 700 PRINT "I WIN      "
 710 STOP 
 1000 PRINT TAB 10;"DEVON DEMON"
 1010 PRINT ,,"IN THIS GAME,YOU MUST CAPTURE   4 OF THE 1000S PIECES.IT IS ""O"",AND YOU ARE ""X"""
 1020 PRINT ,,"YOU CAPTURE BY LANDING ON TOP OFTHE PIECE,AND YOU MOVE ALONG THEDIAGONALS,BACKWORDS AND FORWARDS"
 1030 PRINT ,,"TO MOVE,ENTER THE LETTER AND    NUMBER OF PIECE TO MOVE,AND THEN,AT THE SAME TIME.THE LETTER ANDNUMBER OF THE PLACE TO MOVE TO  E.G.:"
 1040 PRINT "A1B2---YOU WOULD MOVE THE PIECE        ON A1 TO B2"
 1050 PRINT ,,TAB 5;"PRESS NEWLINE NOW"
 1060 IF INKEY$<>"" THEN GOTO 1060
 1070 IF INKEY$<>CHR$ 118 THEN GOTO 1070
 1080 CLS 
 1090 GOTO 60

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top