--- title: "Battleship" id: 71425 type: "computer_media" slug: "battleship" url: "http://localhost/computer_media/battleship/" markdown_url: "http://localhost/computer_media/battleship.md" published_at: "2026-09-09T09:01:27+00:00" modified_at: "2026-09-09T09:01:27+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/09/battleship-12.png" excerpt: "A naval strategy game with two AI difficulty levels — one fires randomly, the other hunts ships using a directional offset array after scoring a hit." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "1986" slug: "year-1986" taxonomy: "post_tag" url: "http://localhost/tag/year-1986/" - 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/" indiv: - name: "Algis Gedris" slug: "algis-gedris" taxonomy: "indiv" url: "http://localhost/indiv/algis-gedris/" - name: "Bob Mitchell" slug: "bob-mitchell" taxonomy: "indiv" url: "http://localhost/indiv/bob-mitchell/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_type: "Program" programmers: - name: "Algis Gedris" slug: "algis-gedris" taxonomy: "indiv" url: "http://localhost/indiv/algis-gedris/" - name: "Bob Mitchell" slug: "bob-mitchell" taxonomy: "indiv" url: "http://localhost/indiv/bob-mitchell/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Battleship%20(1986)(Gedris%2C%20Algis)(TS2068)(US)(Program).zip" tsrun_member: "Battleship (1986)(Gedris, Algis)(TS2068)(US)(Program).tap" mediadate: "1986" images: - url: "http://localhost/wp-content/uploads/2026/09/battleship-12.png" - url: "http://localhost/wp-content/uploads/2026/09/battleships-1.png" media_type_tags: "Game" --- # Battleship Battleship is a two-player naval combat game where the human positions nine ships across a 9×26 grid and then exchanges shots with a computer opponent. The computer places its own fleet randomly using a one-dimensional 234-element array (W) that maps grid coordinates to a linear index, stepping through cells in increments of 1 (horizontal) or 26 (vertical). The program implements two AI difficulty levels: Level 1 fires randomly using a Fisher-Yates-style shuffle on array M to avoid repeat shots, while Level 2 adds a hunt/target strategy that, after scoring a hit, probes the four cardinal directions using offset array H(4) containing −1, 1, 26, and −26. SOUND commands drive explosion effects on hits, and SCREEN$ and ATTR reads are used to detect occupied cells and reconstruct board state between replays. *** ### Program Structure The program is organized into numbered sections separated by `REM` labels. Execution begins at line 130, which calls initialization subroutines and jumps to the main routine at line 420. The high-level flow is: 1. Display rules and select difficulty (lines 2260–2430) 2. Initialize the alphabet string and strategy variables (lines 2440–2460) 3. Draw the player’s grid and accept ship placements (lines 420–780) 4. Place the computer’s ships randomly (lines 800–1000) 5. Alternate player and computer shots until 32 hits are scored (lines 1040–1480) 6. Declare a winner or reveal hidden ships on quit (lines 1820–2000) 7. Offer new game, same positions, or exit (lines 2010–2240) ### Grid Coordinate System The playing area uses a 9-row × 26-column layout mapped to a flat 234-element array. A coordinate string `A$` (e.g., `"C3"`) is converted to a linear index via `RN = (CODE A$(1)-64) + 26*(CODE A$(2)-49)` at line 1130. The inverse conversion (index back to coordinate string) appears at lines 1790 and 1860 using integer division by 26. Column position is extracted with `X - INT((X-1)/26)*26`, and row with `INT((X-1)/26)`. The subroutine at line 170 translates `A$` into screen row `R` and column `C`, applying an offset `N` (0 for the computer’s grid, 11 for the player’s). ### Ship Placement — Player Nine ships are placed in a loop (lines 540–780): two aircraft carriers (length 5), three cruisers (length 4), two destroyers (length 3), and two frigates (length 2). Ship type and length are encoded in the string `E$`; the length is read back with `VAL E$(14)`, extracting character 14 of the type string. The player enters start and end coordinates; the program checks that the Chebyshev distance in one axis equals the required ship length minus one (line 690) and that the ship is axis-aligned (line 700). Occupied cells are detected by reading `ATTR` values rather than a separate data array. ### Ship Placement — Computer The computer fills array `W(234)` with ship cells. For each ship, a random start cell `RN` is chosen (line 850) and a direction `D` of ±1 or ±26 is selected (lines 888–890). For horizontal moves (`ABS D = 1`), line 920 checks that all cells stay within the same row by comparing integer-divided row indices. Lines 930–960 verify no cell is already occupied before marking the run. The length calculation at line 870 uses cascaded boolean additions: `L = 1 + (J<8) + (J<6) + (J<3)`, giving lengths 2, 3, 4, or 5 depending on ship index `J`. ### Shot Tracking and the Shuffle Array Array `M(234)` is initialized so that `M(J)=J` (line 1020–1030), creating an index pool. Each computer shot performs a partial Fisher-Yates shuffle: a random position in the remaining pool is chosen (line 1322), its value `X` is swapped with the last live entry (lines 1340–1350), and the pool shrinks by one (tied to `G`, the total shot count). This guarantees the computer never fires at the same square twice in Level 1 mode. ### AI Strategy — Level 2 When difficulty 2 is selected, array `H(4)` is initialized with offsets `-1, 1, 26, -26` representing left, right, down, and up in the linear coordinate space. Variable `H` stores the index of the first hit on a ship; `H1` saves it for backtracking; `H2` counts probes. After a hit, lines 1510–1720 iterate over the four offsets, probing adjacent cells (line 1550). If an adjacent cell has already been fired upon (`ATTR` check at line 1580), the next direction is tried. When a new hit is confirmed (line 1590–1650), the fired cell is also removed from pool `M` so it won’t be re-selected randomly. If all four directions from `H` are exhausted without extending the ship, the strategy backtracks to `H1` (line 1740) and retries. Resetting `H=0` (line 1760) returns to random firing. The direction priority is rotated by swapping `H(J)` with `H(1)` (lines 1680–1690) so that a productive direction is tried first on subsequent probes. ### Display Techniques Two grids share the same screen: the player’s fleet occupies rows 2–10 (columns 1–26) with `PAPER 2` (red) ink scheme, and the computer’s grid occupies rows 13–21 with `PAPER 4` (green). Row and column labels (letters and digits) are printed using `CHR$` arithmetic. Hit detection on the player’s grid reuses `ATTR` reads: attribute value 16 (black ink on black paper) indicates an unshot ship cell. The flash animation in subroutine 340 uses `FLASH F; OVER 1; INK 8; PAPER 8` to strobe grid rows, and the SOUND sequence at line 150 produces a multi-channel explosion effect followed by a `PAUSE 90` and envelope release. ### Replay Without Re-entering Ship Positions The “same positions” replay path (lines 2070–2210) manually restores the player’s ship display. Lines 2090–2130 iterate all player-grid cells, checking `SCREEN$` and `ATTR` to identify hit markers (`ATTR 58` = hit ship, `ATTR 56` = missed ship cell, `ATTR 23` = hit on player’s ship) and repaints them as empty ocean. The shot arrays and computer ships are then re-initialized while `REPLAY=1` causes the player-ship-entry block at line 490 to be skipped. ### Notable Bugs and Anomalies - Line 1160 branches to `1220 + W(RN)`. When `W(RN)=0` (miss) this correctly goes to 1220; when `W(RN)=2` (already fired) it goes to 1222, a non-existent line, causing a fall-through — a well-known BASIC technique, though the intended behavior (ignoring duplicate shots) works only because the interpreter advances to the next line. - Line 500 uses `AT 11, PI`. `PI` evaluates to approximately 3.14159, which is truncated to column 3. This pattern recurs throughout, functioning as a compact literal for column 3. - The win condition checks `S(1)=32` and `S(2)=32` (lines 1270, 1480), but the winner declaration at line 1960 compares `S(2)>S(1)` rather than checking which reached 32 first, which could misjudge the winner if both scores happen to be equal at game end. - The rules screen at line 2270 contains a credit string; the `PRINT '` idiom (newline before string) is used throughout to control spacing without explicit `AT` positioning. - Line 2200 references variable `H` which may be uninitialized if Level 1 was chosen for the first game and “S” replay is selected; however, Level 1 sets `H = VAL "1" - 2 = -1` at line 2420, so the guard `IF H <> -1` correctly skips Level 2 re-initialization. ## Source Code ``` 1 REM \{6}\{6}THIS PROGRAM HAS BEEN DONATED BYTORONRO TIMEX SINCLER USER'S\{6}GROUP\{6}\{6}MODIFIED & COPIED BY ALGIS E.\{6}GEDRIS, 12-20-86\{6}\{6} 100 REM \{20}\{1}BATTLESHIP\{20}\{0} 110 POKE 23658,8:POKE 23609,25 120 RANDOMIZE 130 GO SUB 2460:GO SUB 2260:PAPER 7:CLS :GO TO 420 140 REM \{20}\{1}EXPLOSIVE SOUND\{20}\{0} 150 SOUND 6,6;7,7;8,16;9,16;10,16;12,56;13,8:PAUSE 90:SOUND 8,0;9,0;10,0:RETURN 160 REM \{20}\{1}GRID POSN > SCREEN POSN\{20}\{0} 170 LET C= CODE A$(1)-64:LET R= CODE A$(2)-47+N 180 LET P$= SCREEN$ (R,C):RETURN 200 REM \{20}\{1}ENTRY POINT\{20}\{0} 210 INPUT LINE A$ 220 LET R=0:LET C=R 230 IF A$="QQQ" AND G <>0 THEN RETURN 240 IF LEN A$ <>2 THEN GO TO 210 250 IF A$(1)<"A" OR A$(1)>"Z" OR A$(2)<"1" OR A$(2)>"9" THEN GO TO 210 260 GO SUB 170:RETURN 280 REM \{20}\{1}CLEAR LOWER GRID\{20}\{0} 290 FOR J=13 TO 21 300 PRINT AT J,1,,:NEXT J:RETURN 330 REM \{20}\{1}FLASH GRID AREAS\{20}\{0} 340 LET F=1 350 FOR J=F TO 6 360 IF J >=6 THEN LET F=0 370 FOR I=FLS TO FLE 380 PRINT FLASH F; OVER 1; INK 8; PAPER 8; AT I,1," " 390 NEXT I:NEXT J:RETURN 410 REM \{20}\{1}MAIN ROUTINE\{20}\{0} 420 CLS 430 PRINT TAB 10;"BATTLESHIPS" 440 PRINT PAPER 2; INK 7;" ";T$ 450 FOR I=2 TO 10:PRINT AT I,0; PAPER 2; INK 7; CHR$ (I+47):NEXT I 460 REM \{20}\{1}POS'N PLAYER'S SHIPS\{20}\{0} 470 LET REPLAY=0 480 DIM W(234):DIM M(234):DIM S(2):LET N=0:LET G=N 490 IF REPLAY THEN GO TO 800 500 FOR I=1 TO 50:PRINT AT 11, PI;"\{18}\{1}ENTER YOUR SHIP POSITIONS\{18}\{0}":NEXT I 510 PRINT AT 11, PI;"ENTER YOUR SHIP POSITIONS" 520 PRINT TAB 15;"Len From To " 530 LET E$="A/CARRIER (5)" 540 FOR J=1 TO 9 550 IF J>2 AND J<6 THEN LET E$="CRUISER (4)" 560 IF J=6 OR J=7 THEN LET E$="DESTROYER (3)" 570 IF J>7 THEN LET E$="FRIGATE (2)" 580 PRINT AT J+12, PI; FLASH 1;E$ 590 GO SUB 210 600 IF P$ <>" " THEN GO TO 590 610 PRINT AT R,C; PAPER 2;" " 620 LET R1=R:LET C1=C 630 PRINT AT J+12,20;A$ 640 GO SUB 210 650 PRINT AT J+12, PI;E$ 660 IF P$ <>" " THEN GO TO 640 670 LET D=0 680 LET R2=R:LET C2=C 690 IF ABS (R-R1)= VAL E$(14)-1 OR ABS (C-C1)= VAL E$(14)-1 THEN LET D=1 700 IF D=1 AND R1 <>R2 AND C1 <>C2 THEN GO TO 640 710 IF NOT D THEN GO TO 640 720 PRINT AT R,C; PAPER 2;" " 730 FOR K=1 TO VAL E$(14)-1 740 IF ABS (R-R1)=0 THEN IF ATTR (R,C-K)=56 THEN PRINT AT R,C-K; PAPER 2;" " 750 IF ABS (C-C1)=0 THEN IF ATTR (R-K,C)=56 THEN PRINT AT R-K,C; PAPER 2;" " 760 NEXT K 770 PRINT AT 12+J,24;A$ 780 NEXT J 790 REM \{20}\{1}POS'N COMPUTER'S SHIPS\{20}\{0} 800 PRINT AT 11,2;"\{18}\{1}COMPUTER NOW PLACING ITS SHIPS\{18}\{0}" 810 PRINT PAPER 4; INK 7;" ";T$ 820 FOR I=13 TO 21:PRINT AT I,0; PAPER 4; INK 7; CHR$ (I+36):NEXT I 830 GO SUB 290 840 FOR J=1 TO 9 850 LET RN= INT (RND*234)+1 860 IF W(RN)=1 THEN GO TO 850 870 LET L=1+(J<8)+(J<6)+(J<3) 880 LET D=(RND>.5)*25+1 890 IF RND>.5 THEN LET D=-1*D 900 IF ABS D <>1 THEN GO TO 930 910 LET K=L*D+RN-1 920 IF INT (K/26) <> INT ((RN-1)/26) THEN GO TO 850 930 IF RN+(L*D)>234 OR RN+(L*D)<1 THEN GO TO 850 940 FOR K=RN TO RN+(L*D) STEP D 950 IF W(K)=1 THEN GO TO 850 960 NEXT K 970 FOR K=RN TO RN+(L*D) STEP D 980 LET W(K)=1 990 NEXT K 1000 NEXT J 1010 FOR J=1 TO 234 1020 LET M(J)=J 1030 NEXT J 1040 REM \{20}\{1}PLAYER'S SHOTS\{20}\{0} 1050 PRINT AT 11,0;"\{18}\{1}ENTER YOUR TARGET COORDINATES \{18}\{0}" 1060 PRINT AT 8,28; PAPER 2; INK 7;"HITS" 1070 PRINT AT 19,28; PAPER 4; INK 7;"HITS" 1080 PRINT AT 0,27; PAPER 5;"SHOTS" 1090 LET N=11 1100 GO SUB 210 1110 IF A$="QQQ" THEN GO TO 1830 1120 PRINT AT 17,29;A$ 1130 LET RN=(CODE A$(1)-64)+(26*(CODE A$(2)-49)) 1140 LET C= CODE A$(1)-64:LET R= CODE A$(2)-47 1150 LET S$="*" 1160 IF W(RN) <>1 THEN GO TO 1220+W(RN) 1170 LET S$="*" 1180 LET W(RN)=2 1190 LET S(1)=S(1)+1 1200 LET FLS=13:LET FLE=21 1210 GO SUB 150:GO SUB 340:GO TO 1230 1220 PRINT AT R+N,C; PAPER 7; INK 0;S$:GO TO 1240 1230 PRINT AT R+N,C; PAPER 4; INK 7;S$ 1240 PRINT AT 20,29;S(1) 1250 LET G=G+1 1260 PRINT AT 1,29;G 1270 IF S(1)=32 THEN GO TO 1950 1280 REM \{20}\{1}COMPUTER'S SHOTS\{20}\{0} 1290 PRINT AT 11,0,, 1300 LET N=0 1310 IF H <>-1 THEN GO TO 1510 1320 LET RN= INT (RND*(235-G))+1 1330 LET X=M(RN) 1340 LET M(RN)=M(235-G) 1350 LET M(235-G)=X 1360 GO SUB 1790 1370 PRINT AT 6,29;A$ 1380 LET S$="*" 1390 IF ATTR (R,C) <>16 THEN GO TO 1450 1400 IF H>-1 THEN LET H=X 1410 LET S(2)=S(2)+1 1420 LET S$="*" 1430 LET FLS=2:LET FLE=10 1440 GO SUB 150:GO SUB 340:GO TO 1460 1450 PRINT AT R,C; PAPER 7; INK 0;S$:GO TO 1470 1460 PRINT AT R,C; PAPER 2; INK 7;S$ 1470 PRINT AT 9,29;S(2) 1480 IF S(2)=32 THEN GO TO 1950 1490 GO TO 1090 1500 REM \{6}\{6}\{20}\{1}COMPUTER'S STRATEGY LEVEL TWO \{20}\{0} 1510 IF NOT H THEN GO TO 1320 1520 LET H2=H2+1 1530 IF H2=1 THEN LET H1=X 1540 FOR J=1 TO 4 1550 LET X=H+H(J) 1560 IF X<1 OR X>234 THEN GO TO 1720 1570 GO SUB 1790 1580 IF ATTR (R,C) <>16 THEN GO TO 1720 1590 LET Q=1 1600 IF M(X) <>X THEN LET Q=X 1610 FOR K=Q TO 235-G 1620 IF M(K) <>X THEN GO TO 1660 1630 LET M(K)=M(235-G) 1640 LET M(235-G)=X 1650 LET K=235-G 1660 NEXT K 1670 LET K=H(J) 1680 LET H(J)=H(1) 1690 LET H(1)=K 1700 PRINT AT 6,29;A$ 1710 GO TO 1380 1720 NEXT J 1730 IF H1=H THEN GO TO 1760 1740 LET H=H1 1750 GO TO 1540 1760 LET H=0 1770 LET H2=H 1780 GO TO 1320 1790 LET A$= CHR$ (X-(INT ((X-1)/26)*26)+64)+ CHR$ (INT ((X-1)/26)+49) 1800 GO SUB 170 1810 RETURN 1820 REM \{20}\{1}REVEAL COMPUTER'S SHIPS\{20}\{0} 1830 LET N=11 1840 FOR X=1 TO 234 1850 IF W(X) <>1 THEN GO TO 1890 1860 LET A$= CHR$ (X-(INT ((X-1)/26)*26)+64)+ CHR$ (INT ((X-1)/26)+49) 1870 GO SUB 170 1880 PRINT AT R,C; PAPER 4;" " 1890 NEXT X 1900 PRINT AT 11, PI; PAPER 6; INK 0;"\{18}\{1}PRESS ANY KEY TO CONTINUE\{18}\{0}" 1910 IF INKEY$="" THEN GO TO 1910 1920 PRINT AT 11,0,, 1930 GO TO 2010 1940 REM \{20}\{1}DECLARE WINNER\{20}\{0} 1950 LET W$="YOU" 1960 IF S(2)>S(1) THEN LET W$="I" 1970 PRINT AT 11, PI; PAPER PI; FLASH 1; INK 7;W$;" WON BY "; ABS (S(1)-S(2)) 1980 IF W$="I" THEN GO TO 1830 1990 PAUSE VAL "240" 2000 GO TO 1900 2010 GO SUB 290 2020 REM \{20}\{1}END OPTIONS\{20}\{0} 2030 PRINT AT 15,2; PAPER 2; INK 7;"PRESS N FOR NEW GAME"; AT 17,8; PAPER 1; INK 7;"S FOR SAME POSITIONS"; AT 19,8; PAPER 5; INK 0;"X TO END" 2040 IF INKEY$="N" THEN CLS :GO TO 2220 2050 IF INKEY$="X" THEN CLS :STOP 2060 IF INKEY$ <>"S" THEN GO TO 2040 2070 REM \{6}\{6}\{20}\{1}RETAIN PLAYER'S POS'NS \{20}\{1}FOR NEW GAME\{20}\{0} 2080 GO SUB 290 2090 FOR I=2 TO 10:FOR J=1 TO 26 2100 IF SCREEN$ (I,J)="*" AND ATTR (I,J)=58 THEN PRINT AT I,J; PAPER 7;" " 2110 IF SCREEN$ (I,J)="*" AND ATTR (I,J)=56 THEN PRINT AT I,J; PAPER 7;" " 2120 IF SCREEN$ (I,J)="*" AND ATTR (I,J)=23 THEN PRINT AT I,J; PAPER 2;" " 2130 NEXT J:NEXT I 2140 PRINT AT 9,29;" " 2150 PRINT AT 8,28;" " 2160 PRINT AT 0,27;" " 2170 PRINT AT 1,29;" " 2180 PRINT AT 6,29;" " 2190 LET REPLAY=1 2200 IF H <>-1 THEN GO SUB 2450 2210 GO TO 480 2220 GO SUB 290 2230 GO SUB 2390 2240 GO TO 420 2250 STOP :REM \{20}\{1}RULES\{20}\{0} 2260 BORDER 1:PAPER 5:INK 0:CLS :PRINT TAB 10; PAPER 1; INK 7;"BATTLESHIPS" 2270 PRINT '"\{19}\{1} Robert H. Mitchell 1984 \{19}\{0}" 2280 PRINT ''" Set up your ships on the top half of the screen." 2290 PRINT '" All coordinates should be in the form LETTER followed by NUMBER." 2300 PRINT '" The computer will then place its ships." 2310 PRINT '" When prompted, enter co-ord- inates of your first shot." 2320 PRINT #0;"Press any key to continue" 2330 PAUSE NOT PI 2340 CLS 2350 PRINT " The winning score is 32 hits." 2360 PRINT '" You may quit by typing 'QQQ'." 2370 PRINT '" After a computer win, or when you quit, the position of the computer's remaining ships will be revealed." 2380 PRINT '" AT the end of the game, press 'S' to retain the same"'" positions for your ships."'" (The computer will, of"'" course, reposition its"'" ships.)" 2390 PRINT AT 17,0;" LEVEL 1: EASY"'" LEVEL 2: HARD"''" (PRESS 1 OR 2)" 2400 LET I$= INKEY$ 2410 IF I$<"1" OR I$>"2" THEN GO TO 2400 2420 LET H= VAL I$-2 2430 IF H THEN RETURN 2440 REM \{6}\{6}\{20}\{1}INTIALIZE COMPUTER \{20}\{1}STRATEGY\{6}(LEVEL 2)\{20}\{0} 2450 LET H=0:LET H1=H:LET H2=H:DIM H(4):LET H(1)=-1:LET H(2)=1:LET H(PI)=26:LET H(4)=-26 2460 LET T$="ABCDEFGHIJKLMNOPQRSTUVWXYZ":RETURN 9997 REM \{20}\{1}SAVE & VERIFY\{20}\{0} 9998 CLEAR :SAVE "BATTLESHIP" LINE 0 ```