--- title: "SNICKERS" id: 70830 type: "computer_media" slug: "snickers" url: "http://localhost/computer_media/snickers/" markdown_url: "http://localhost/computer_media/snickers.md" published_at: "2026-08-23T15:08:06+00:00" modified_at: "2026-08-23T20:34:48+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/snickers.png" alt: "SNICKERS screen" excerpt: "A one-versus-computer checkers game with a multi-tier AI that prioritizes safe captures, piece protection, back-row bonuses, and random fallback moves." 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 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/SNICKERS%20%28198x%29%28-%29%28TS2068%29%28US%29%28Program%29.zip" tsrun_member: "SNICKERS (198x)(-)(TS2068)(US)(Program).tap" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/08/snickers.png" alt: "SNICKERS screen" media_type_tags: "Game" --- # SNICKERS SNICKERS is a two-player checkers (draughts) variant for one human and one computer opponent, implemented entirely in BASIC. The board is stored as a one-dimensional array `A(110)` indexed by a two-digit scheme (tens digit = row 1–8, units digit = column 1–8), with pieces represented by their ASCII character codes: `H` (72) for human, `C` (67) for computer, and `.` (46) for an empty black square. The computer’s move logic is structured in a priority hierarchy: it first searches for captures classified as “good safe,” “safe,” or “general,” then looks for moves that protect threatened pieces, then attempts to land on the back row for a bonus point, then selects safe non-capture moves, and finally falls back to a random legal move. Scoring awards one point per capture and an additional point for landing on the opponent’s back row, with the game ending when either side accumulates five points. *** ### Program Structure The program is organized as a main loop dispatching to subroutines, with initialization at line 2070 called once from line 20. The main cycle at lines 40–110 alternates computer and human turns, checking scores after each half-turn. End-of-game handling at lines 120–170 plays a winning or losing fanfare and prints a result message. 1. **Lines 10–170:** Main loop, game-over detection, result display 2. **Lines 190–960:** Computer move — capture search and selection 3. **Lines 980–1130:** Computer move — protect threatened piece 4. **Lines 1140–1290:** Computer move — back-row “disappear” logic 5. **Lines 1310–1610:** Computer move — safe non-capture moves 6. **Lines 1630–1740:** Computer move — random legal move fallback 7. **Lines 1760–1930:** Board display subroutine 8. **Lines 1950–2050:** Human move input and validation 9. **Lines 2070–2360:** Initialization, array setup, board data ### Board Representation The board is stored in a one-dimensional numeric array `A(110)`. Each cell is indexed as `J+K` where `J` is a multiple of 10 (10–80, representing rows) and `K` is 1–8 (columns). This gives indices 11–88 for the 64 board squares, with surrounding unused cells acting as boundary buffers. Piece identity is stored as the ASCII code of the display character: `H`=72 (human), `C`=67 (computer), `.`=46 (empty dark square), space=32 (light square). Diagonal moves in this scheme shift the index by ±9 or ±11 (one row and one column in either diagonal direction). A capture therefore lands at ±18 or ±22 from the starting square, with the captured piece at the midpoint. ### Computer AI — Move Priority Hierarchy The computer evaluates moves in a strict priority order, falling through to the next level only when no move is found at the current level: 1. **Good safe captures** — captures that are safe *and* threaten another human piece (stored in `G()`) 2. **Safe captures** — captures where the landing square is not under immediate threat (stored in `S()`) 3. **General captures** — any other capture (stored in `T()`) 4. **Protect threatened piece** — move a piece that is under attack (lines 980–1120) 5. **Back-row landing** — move a piece already adjacent to the human’s back row (lines 1140–1290) 6. **Safe non-capture move** — forward move not leaving a piece exposed (lines 1310–1610) 7. **Random legal move** — up to 200 random attempts; concedes if none found (lines 1630–1740) ### Move Encoding Moves are packed into a single integer for storage: `100 * start_index + destination_index`. This is decoded at lines 540–550 (captures) and 1510–1520 (non-captures) using integer division and modulo arithmetic. For captures, the offset `ED` encodes the diagonal direction (±9 or ±11) so that `START - ED` gives the captured square and `START - 2*ED` gives the landing square. For non-capture moves the encoding is `100 * start + destination` and decoded identically. ### Scoring and Back-Row Bonus Each capture scores one point (`CS` or `HS` incremented). If a piece lands on or below index 18 (the human’s back two rows), it is removed from the board (`A(...) = B`) and scores an additional point. The human equivalent at line 2030 checks `ED > 80` for landing on the computer’s back row. The game ends when either score reaches 5. ### Human Move Validation At line 1970, the program rejects a start square that does not hold a human piece (`A(START) < H`; since H=72, this accepts only codes ≥ 72, i.e., the character ‘H’ itself). At line 1990, a destination must be an empty black square (`A(ED) = B`); if the move distance exceeds 11 (i.e., it is a capture), the midpoint must hold a computer piece. A capture is recognized at line 2020 by `ABS(START-ED) > 11`. ### Notable Techniques - Variables `E`, `B`, `C`, `H` hold ASCII codes (via `CODE`), allowing the board array to double as a character map for display with `CHR$ (A(J+K))` at line 1860. - The “safety” check subroutine (lines 700–960) inspects three additional squares around the intended landing position to classify a capture as good-safe, safe, or general before storing it. - Multiple `PRINT` and `PAUSE` statements inside the AI search loop (e.g., lines 720–730, 890, 940) expose the computer’s deliberation in real time — a debugging trace left in the released code. - The random move fallback (lines 1650–1740) uses a retry loop with a counter `L`; after 200 failed attempts it concedes with a fanfare. - `POKE 23658,200` at line 15 sets the FLAGS2 system variable to suppress the lower screen scroll prompt on the Spectrum. ### Bugs and Anomalies - **Line 150:** The win message reads `" >> YOY HAVE WON << "` — “YOY” is a typo for “YOU”. - **Lines 1330–1340:** The outer `FOR J=80 TO 30 STEP -10` is immediately overwritten by an inner `FOR J=1 TO 8` — the outer loop variable `J` is shadowed and its intended row-scanning behavior is lost. The inner loop reuses `J` where `K` was presumably intended (compare the working capture loop at lines 300–400). As a result, the safe non-capture move search always scans the same row. - **Lines 1390 and 1440:** Mixed-case variable names (`a(y)`, `a(z)`, `h`) are used. On the Spectrum, BASIC is case-insensitive for variable names entered via keywords, but these lowercase forms may cause issues depending on how the source was entered. - **Line 1070:** The condition `A(Q+9)` (without a comparison operator) is always true for any non-zero array value — the intended comparison (e.g., `=B`) appears to be missing. - **Line 1060:** Similarly, `A(Q+20)` is used as a bare boolean, evaluating as the numeric value of the array cell rather than comparing it to a piece type. - **Line 1500:** In the safe non-capture section, `T()` is reused for move storage, but `T()` is dimensioned to only 18 elements and is shared with the capture-search arrays; this could produce index errors if more than 18 non-capture moves are found. - **Line 620:** The back-row bonus check uses `START-2*ED > 18` to skip the bonus (`RETURN` early if landing index is above 18), which is logically inverted from the stated intent — the bonus should apply *when* the index is ≤ 18, which is what the code does by falling through. ## Source Code ``` 10 REM "SNICKERS" 15 POKE 23658,200: BRIGHT 0: FLASH 0: INK 7: PAPER 1: BORDER 1 20 GO SUB 2070: REM INITIALIZE 30 GO SUB 1760: REM PRINT BOARD 40 REM ** MAIN CYCLE STARTS ** 50 GO SUB 190: REM COMPUTER MOVES 60 GO SUB 1760: REM PRINT BOARD 70 IF CS>4 THEN GO TO 120 80 GO SUB 1950: REM ACCEPT HUMAN MOVE 90 GO SUB 1760: REM PRINT BD 100 IF HS<5 THEN GO TO 50 110 REM ********************* 120 REM END OF GAME 130 PRINT : PRINT "THE GAME IS OVER" 140 PRINT 150 IF HS>CS THEN FOR I=1 TO 22 STEP 2: BEEP .1,I: BEEP .1,I+2: BEEP .2,4: NEXT I: PRINT FLASH 1; INK 1; PAPER 7;" >> YOY HAVE WON << " 160 IF CS>HS THEN FOR I=20 TO 5 STEP -1.5: BEEP .2,I: BEEP .3,I+2: NEXT I: FOR I=1 TO 4: BEEP 1,3: BEEP .2,-1: NEXT I: BEEP 2,20: PRINT FLASH 1; INK 2; PAPER 0;" *** I'M THE WINNER *** " 170 STOP 180 REM ********************* 190 REM COMPUTER MOVE 200 REM ********************* 210 REM SEARCH FOR CAPTURES 220 LET GSAFE=0: REM TO COUNT GOOD,SAFE CAPTURES WHICH THREATEN HUMAN PIECES 230 LET CSAFE=0: REM TO COUNT SAFE CAPTURES WHICH DO NOT PLACE COMP UNDER THREAT 240 LET CCAPTURE=0: REM TO COUNT OTHER CAPTURES FOUND 250 FOR J=1 TO 3 260 LET G(J)=0: REM EMPTY GOOD,SAFE CAPTURE STORE 270 LET S(J)=0: REM EMPTY SAFE CAPTURE STORE 280 LET T(J)=0: REM EMPTY OTHERCAPTURE STORE 290 NEXT J 300 FOR J=80 TO 30 STEP -10 310 FOR K=1 TO 8 320 IF A(J+K)<>C THEN GO TO 390: REM SKIP EVALUATION IF NO COMPUTER PIECE HERE. 330 REM ** CAPTURE TO RIGHT ** 340 LET X=J+K-9: LET Y=J+K-18: LET Z=J+K-27: LET M=-11 350 IF A(X)=H AND A(Y)=B THEN GO SUB 700: REM CAPTURE FOUND 360 REM ** CAPTURE LEFT ** 370 LET X=J+K-11: LET Y=J+K-22: LET Z=J+K-33: LET M=-9 380 IF A(X)=H AND A(Y)=B THEN GO SUB 700: REM CAPTURE FOUND 390 NEXT K 400 NEXT J 410 IF GSAFE+CSAFE+CCAPTURE=0 THEN GO TO 980: REM NO CAPTURES FOUND 420 REM ** NOW CHOOSE CAPTURE TOMAKE ** 430 PRINT : FOR I=1 TO 10: BEEP .3,I: BEEP .2,12: NEXT I: PRINT TAB 8;">> CAPTURE FOUND" 440 PAUSE 400 450 IF GSAFE<>0 THEN GO TO 500 460 IF CSAFE<>0 THEN GO TO 670 470 REM ** CHOOSE FROM GENERAL CAPTURES ** 480 LET MOVE=T(INT (RND*CCAPTURE)+1) 490 GO TO 540 500 REM CHOOSE FROM GOOD SAVE 510 REM SELECT FROM STORED MOVES 520 LET MOVE=G(INT (RND*GSAFE)+1) 530 REM ** MAKE MOVE ** 540 LET START=INT (MOVE/100) 550 LET ED=MOVE-100*START 560 LET A(START)=B 570 LET A(START-ED)=B 580 LET A(START-2*ED)=C 590 LET CS=CS+1 600 REM * CHECK FOR ADDITIONAL SCORE IF LANDING ON BACK ROW ** 610 IF START-2*ED>18 THEN RETURN 620 LET A(START-2*ED)=B 630 LET CS=CS+1 640 PRINT "I CAPTURED AND LANDED ON ";START-2*ED;" ON BACK ROW" 650 PAUSE 600 660 RETURN 670 REM ** SAFE CAPTURE * 680 LET MOVE=S(INT (RND*CSAFE)+1) 690 GO TO 540 700 REM ** CHECK PROPOSED CAPTURE FOR SAFETY ** 710 REM ** CHECK SQUARE BELOW IN SAME DIRECTION AS INTENDED MOVE ** 720 PRINT J+K;" TO ";Y;" CAPTURING ON ";X 730 PAUSE 400 740 IF A(Z)=H THEN GO TO 920: REM STORE AS A NON SAFE CAPTURE 750 REM ** CHECK SQUARE IN OTHER DIRECTION FROM INTENDED MOVE ** 760 IF A(Y+M)=H AND A(Y-M)=B THEN GO TO 920 770 REM NOW CHECK TO SEE IF WILL LEAVE A PIECE EXPOSED BY MAKING MOVE 780 IF A(J+K+M)=H AND A(J+K+2*M)=H THEN GO TO 920 790 REM ** IF REACHED THIS POINT THEN CAPTURE IS "SAFE" ** 800 REM ** STORE THIS MOVE ** 810 LET CSAFE=CSAFE+1 820 LET S(CSAFE)=100*(J+K)+20+M: REM THIS ENCODES ENOUGH INFORMATION TO RECREATE THE MOVE ** 830 REM ** NOW SEE IF THIS DESERVES TO BE CALLED A "GOOD SAFE" MOVE *** 840 LET CHECK=GSAFE 850 IF Y+2*M<1 THEN RETURN 860 IF A(Y+M)=H AND A(Y-(20+M))<>B AND A(Y+2*M)=B THEN LET GSAFE=GSAFE+1 870 IF CHECK=GSAFE THEN RETURN : REM ** THIS MOVE FOUND NOT TO BE A GOOD SAFE ** 880 REM * STORE GOOD SAFE MOVE* 890 PRINT "I AM CONSIDERING ";J+K;" TO ";M+20+J+K 900 LET G(GSAFE)=100*(J+K)+20+M 910 RETURN 920 REM STORE NON SAFE CAPTURE 930 LET CCAPTURE=CCAPTURE+1 940 PRINT "I AM CONSIDERING ";J+K;" TO ";M+20+J+K 950 LET T(CCAPTURE)=100*(J+K)+20+M 960 RETURN 970 REM ********************** 980 REM * MOVE TO PROTECT PIECE UNDER THREAT ** 990 LET MOVE=0 1000 LET J=80 1010 LET K=1 1020 LET Q=J+K 1030 IF A(Q)<>C THEN GO TO 1110: REM DO NOT CONSIDER THIS SQUARE, NO COMP PIECE 1040 IF A(Q+9)=B AND A(Q-9)=H AND A(Q+18)=C THEN LET MOVE=100*(Q+18)+Q+9 1050 REM RANDOM EJECTION OF THIS MOVE IF IT EXPOSES ANOTHER ONE 1060 IF MOVE<>0 AND A(Q-2)=H AND A(Q+20) AND RND>.5 THEN GO TO 1510 1070 IF A(Q+9)=B AND A(Q-9) AND A(Q+20)=C THEN LET MOVE=100*(Q+20)+Q+9: GO TO 1510 1080 IF A(Q+11)=B AND A(Q-11)=H AND A(Q+22)=C THEN LET MOVE=100*(Q+22)+Q+11 1090 IF MOVE<>0 AND A(Q+2)=H AND A(Q+22)=B AND RND>.5 THEN GO TO 1510 1110 IF K<8 THEN LET K=K+1: GO TO 1020 1120 IF J>10 THEN LET J=J-10: GO TO 1010 1130 REM ********************* 1140 REM ** NO CAP FOUND, SO LOOK FOR MOVE TO "DISAPPEAR" ON BACK ROW ********************* 1150 LET MOVE=0 1160 REM UNDESIRABLE MOVES CHECKED FIRST, SO CAN BE OVERWRITTEN BY BETTER ONES 1170 IF A(22)=C AND A(11)=B THEN LET MOVE=22 1180 IF A(22)=C AND A(17)=B THEN LET MOVE=22 1200 IF A(26)=C AND A(17)=B THEN LET MOVE=26 1210 IF A(26)=C AND A(15)=B THEN LET MOVE=26 1220 IF A(24)=C AND A(15)=B THEN LET MOVE=24 1230 IF A(24)=C AND A(13)=B THEN LET MOVE=24 1240 IF MOVE=0 THEN GO TO 1310 1250 PRINT : PRINT INK 4; BRIGHT 1;"I'M MOVING ONTO BACK ROW FROM ";MOVE 1260 PAUSE 500 1270 LET A(MOVE)=B 1280 LET CS=CS+1 1290 RETURN 1300 REM ********************** 1310 REM SAFE NON CAPTURE MOVES 1312 REM *****____________***** 1320 LET CMOVE=0: REM ** COUNTS MOVES FOUND ** 1330 FOR J=80 TO 30 STEP -10 1340 FOR J=1 TO 8 1350 IF A(J+K)<>C THEN GO TO 1460 1360 LET X=J+K-9: LET Y=J+K-18: LET Z=J+K-20 1370 LET Q=J+K+2 1380 IF A(X)<>B THEN GO TO 1460 1390 IF a(y)=h OR a(z)=h AND a(q)=b THEN GO TO 1460 1400 GO SUB 1560 1410 LET X=J+K-11: LET Y=J+K-22: LET Z=J+K-20 1420 LET Q=J+K-2 1430 IF A(X)<>B THEN GO TO 1460 1440 IF A(Y)=H OR A(Z)=H AND A(Q)=B THEN GO TO 1460 1450 GO SUB 1560 1460 NEXT K 1470 NEXT J 1480 IF CMOVE=0 THEN GO TO 1630 1490 REM ** MAKE MOVE ** 1500 LET MOVE=T(INT (RND*CMOVE)+1) 1510 LET START=INT (MOVE/100) 1520 LET ED=MOVE-100*START 1530 LET A(START)=B 1540 LET A(ED)=C 1550 RETURN 1560 REM ** STORES MOVE ** 1570 LET CMOVE=CMOVE+1 1580 PRINT "I AM CONSIDERING ";J+K;" TO ";X 1590 PAUSE 400 1600 LET T(CMOVE)=100*(J+K)+X 1610 RETURN 1620 REM ********************** 1630 REM RANDOM NON CAPTURE MOVE 1640 INK 6: PRINT "LOOKING FOR RANDOM LEGAL MOVE" 1650 INK 7: LET L=0 1660 LET L=L+1 1670 LET J=10*INT (RND*8+1) 1680 LET K=INT (RND*8+1) 1690 IF A(J+K)=C THEN GO TO 1720 1700 IF L<200 THEN GO TO 1660 1710 PRINT : FOR I=1 TO 4: BEEP .5,I: BEEP .2,I+10: BEEP .3,I+5: NEXT I: PRINT "I CONCEDE THE GAME": STOP 1720 IF A(J+K-9)=B THEN LET MOVE=100*(J+K)+J+K-9: GO TO 1510 1730 IF A(J+K-11)=B THEN LET MOVE=100*(J+K)+J+K-11: GO TO 1510 1740 GO TO 1700 1750 REM ********************* 1760 REM PRINT BOARD 1770 CLS 1780 PRINT 1790 PRINT INK 6; BRIGHT 1;"COMPUTER "; FLASH 1;CS; FLASH 0;" HUMAN "; FLASH 1;HS 1800 PRINT 1810 PRINT " 12345678 " 1820 PRINT " ________" 1830 FOR J=80 TO 10 STEP -10 1840 PRINT " ";J/10; 1850 FOR K=1 TO 8 1860 INK 4: PRINT PAPER 5; INK 0;CHR$ (A(J+K)); 1870 NEXT K 1875 INK 7 1880 PRINT J/10 1890 NEXT J 1900 PRINT " ________" 1910 PRINT " 12345678 " 1920 PRINT 1930 RETURN 1940 REM ********************** 1950 REM ** ACCEPT HUMAN MOVE ** 1960 INPUT "MOVE FROM ";START 1970 IF A(START)B OR ABS (START-ED)>11 AND A((START+ED)/2)<>C THEN GO TO 1980 2000 LET A(START)=B 2010 LET A(ED)=H 2020 IF ABS (START-ED)>11 THEN LET A((START+ED)/2)=B: LET HS=HS+1: BEEP .3,7: BEEP .2,6: BEEP 1,15: PRINT INK 7; BRIGHT 1; PAPER 0; FLASH 1;" WELL DONE " 2030 IF ED>80 THEN LET A(ED)=B: LET HS=HS+1: PRINT "THAT'S ONE MORE FOR YOU" 2040 PAUSE 100 2050 RETURN 2060 REM ********************** 2070 REM **** INITIALIZE **** 2080 REM ******************** 2090 CLS 2100 RANDOMIZE 2110 DIM A(110): REM BOARD AND BLANK SPACES BEYOND AND AROUND IT 2120 DIM G(3): REM GOOD SAFE CAPTURE STORE 2130 DIM S(3): REM SAFE CAPTURE STORE 2140 DIM T(18): REM OTHER CAPTURE STORE ALSO USED FOR SAFE NON CAPTURE MOVES 2150 LET E=CODE " ": REM EMPTY "WHITE"SQUARE 2160 LET B=CODE ".": REM EMPTY "BLACK" SQUARE 2170 LET C=CODE "C": REM COMPUTER PIECE 2180 LET H=CODE "H": REM HUMAN PIECE 2190 LET HS=0: REM HUMAN SCORE 2200 LET CS=0: REM COMPUTER SCORE 2210 RESTORE 2290: REM SET UP STARTING BOARD 2220 FOR J=10 TO 80 STEP 10 2230 FOR K=1 TO 8 2240 READ X: LET A(J+K)=X 2250 NEXT K 2260 NEXT J 2270 RETURN 2280 REM ****************** 2290 DATA 72,32,72,32,72,32,72,32 2300 DATA 32,72,32,72,32,72,32,72 2310 DATA 46,32,46,32,46,32,46,32 2320 DATA 32,46,32,46,32,46,32,46 2330 DATA 46,32,46,32,46,32,46,32 2340 DATA 32,46,32,46,32,46,32,46 2350 DATA 67,32,67,32,67,32,67,32 2360 DATA 32,67,32,67,32,67,32,67 ```