--- title: "Crossword" id: 58365 type: "computer_media" slug: "crossword" url: "http://localhost/computer_media/crossword/" markdown_url: "http://localhost/computer_media/crossword.md" published_at: "2024-11-17T03:31:03+00:00" modified_at: "2026-04-03T07:58:05+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/11/XWord.bmp" excerpt: "A full crossword construction kit in pure BASIC — define your grid, write clues, validate answers, and even save your puzzle to tape, all in under 200 lines." 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: "Mindware" slug: "mindware" taxonomy: "post_tag" url: "http://localhost/tag/mindware/" - 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_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Crossword%20%281982%29%28Mindware%29%28TS1000%29%28US%29%28Program%29.zip" mediadate: "1982" producer_company: - id: 11120 title: "Mindware, Inc." type: "company" url: "http://localhost/company/mindware/" images: - url: "http://localhost/wp-content/uploads/2024/11/XWord.bmp" - url: "http://localhost/wp-content/uploads/2024/11/Tape-2.jpg" related_products: - id: 12272 title: "Crossword" type: "product" url: "http://localhost/product/crossword/" media_type_tags: "Game" --- This program is a complete crossword puzzle authoring and solving tool written in BASIC. It allows a user to define a grid (5–15 squares), enter the puzzle layout, write across and down clues with letter counts, and then interactively solve the puzzle by entering answers that are validated against the stored grid. The program uses a two-dimensional string array `A$(A,A)` to hold the grid, parallel arrays `P(20,2)` and `Q(20,2)` to record starting coordinates of across and down answers, and further string arrays `P$`, `Q$`, `X$`, `Y$` to store clues and letter-count hints. Block-graphic characters are used to draw the grid border, and coordinate labels are generated with `CHR$` arithmetic rather than stored lookup tables. *** ## Program Structure The code is organised as a collection of subroutines invoked from a central menu at line `5000`. The main menu dispatches to four paths: 1. **Solve a puzzle** – line `3200` 2. **Save to tape** – line `4950` 3. **Write a new puzzle** – line `2500` 4. **See the answers** – line `490` The puzzle-creation flow (line `2500`) chains four subroutines: `GOSUB 290` (grid size), `GOSUB 50` (draw frame), `GOSUB 350` (enter grid content), `GOSUB 550` (count clue starts), then `GOSUB 750` (enter clues). ## Key Subroutines | Lines | Purpose | | --- | --- | | 10–40 | Keypress capture: waits for key-up then key-down; returns `W = CODE(INKEY$) − 28` | | 50–210 | Draw grid border using block-graphic characters and CHR$-arithmetic coordinate labels | | 220–280 | Render blank squares (cells containing `"% "`) into the grid display | | 290–340 | Input grid size `A` (5–15), allocate `DIM A$(A,A)` | | 350–480 | Row-by-row entry of grid content; spaces are replaced with `"% "` to mark black squares | | 481–489 | Micro-subroutines that append a coordinate to `P()` (across) or `Q()` (down) | | 550–740 | Scan grid for answer starts: across (lines 570–630), down (lines 650–730) | | 750–1150 | Prompt for and store clue text and letter-count strings | | 1160–1280 | Look up and display the clue for a given row/column coordinate | | 1300–1340 | Clear lines 18–21 (status area) | | 1350–1400 | Validate and display an across answer | | 1410–1460 | Validate and display a down answer | | 1500–1740 | “Cheat” reveal: print the stored answer for the selected word | | 2000–2040 | Accept user’s answer string, delegate to across or down validator | | 3200–3420 | Interactive solve loop: choose direction, row, column; show clue; act on A/B/C | | 4950–4995 | Save puzzle to tape with `SAVE "XWOR%D"` | | 5000–5150 | Main menu | ## Notable BASIC Idioms - **Debounced keypress routine** (lines 10–40): line `10` spins until `INKEY$=""`, line `30` spins until a key is held, then `W = CODE(INKEY$) − 28` maps the character code to a small integer used throughout for branching. This is the standard Sinclair key-wait pattern. - **Black-square sentinel**: spaces entered by the user are immediately converted to the two-character string `"% "` (a percent sign followed by a space) so that they can be distinguished from empty (unsolved) white cells when stored in the fixed-length string array `A$(A,A)`. - **CHR$ arithmetic for labels**: column headers use `CHR$(X+30)` (columns 8…A+7 → characters `'&'…`) and row labels use `CHR$(X+28)` (rows 1…A → characters `'!'…`). The solve loop reverses this: line `3340` sets `N = W − 9` to convert the received code back to a 1-based column index. - **Parallel coordinate arrays**: `P(20,2)` / `Q(20,2)` store (row, col) of each answer start; the companion string arrays `P$(AA,64)` / `Q$(DA,64)` and `X$(AA,7)` / `Y$(DA,7)` are dimensioned *after*`AA` and `DA` are known, saving memory. - **Block-graphic border**: the frame drawn in lines 60–130 uses zmakebas escapes `\ .`, `\ '`, `\..`, `\''`, `\.`, `\'`, `\ :`, `\:` for corners, top/bottom edges, and side edges respectively. ## Clue Detection Algorithm Across clue starts (lines 570–630) iterate every cell; a cell at `(X,Y)` starts a word if either `Y=1` or the cell to its left is a black square (`"% "`), *and* both `A$(X,Y)` and `A$(X,Y+1)` are white. Down detection (lines 650–730) mirrors this logic over rows. Both routines cap answers at 20 via the fixed `DIM P(20,2)` / `DIM Q(20,2)`. ## Source Code ``` 5 REM **%C%R%O%S%S%W%O%R%D** 6 REM COPYRIGHT: C.J.JONES 7 REM MARCH 1982 10 IF INKEY$<>"" THEN GOTO 10 30 IF INKEY$="" THEN GOTO 30 35 LET W=(CODE INKEY$)-28 40 RETURN 50 REM DRAW DIAGRAM 60 PRINT AT 1,7;" .";AT 2+A,7;" '" 70 FOR X=8 TO A+7 80 PRINT AT 1,X;".." 90 PRINT AT 2+A,X;"''" 100 NEXT X 105 PRINT AT 1,A+8;". ";AT 2+A,A+8;"' " 110 FOR X=2 TO A+1 120 PRINT AT X,7;" :";AT X,A+8;": " 130 NEXT X 140 REM COORDINATES 150 FOR X=8 TO A+7 160 PRINT AT 0,X;CHR$ (X+30) 170 NEXT X 180 FOR X=1 TO A 190 PRINT AT X+1,6;CHR$ (X+28) 200 NEXT X 210 RETURN 220 REM DRAW BLANKS 230 FOR X=1 TO A 240 FOR Y=1 TO A 250 IF A$(X,Y)="% " THEN PRINT AT X+1,Y+7;A$(X,Y) 260 NEXT Y 270 NEXT X 280 RETURN 290 REM GRID SIZE 300 CLS 305 PRINT "ENTER REFERENCE (E.G. BOOK,UNIT,NEWSPAPER,DATE)" 306 INPUT R$ 310 PRINT AT 5,0;R$;AT 8,0;"ENTER GRID SIZE" 320 INPUT A 330 IF (A<5 OR A>15) THEN GOTO 310 333 CLS 335 DIM A$(A,A) 340 RETURN 350 REM ENTER COMPLETE DIAGRAM 360 FOR X=1 TO A 370 PRINT AT 21,0;" ";AT 21,0;"ENTER LINE ";X 380 INPUT A$(X) 390 FOR Y=1 TO A 400 IF A$(X,Y)=" " THEN LET A$(X,Y)="% " 405 NEXT Y 410 PRINT AT X+1,8;A$(X) 420 PRINT AT 21,0;"IS THIS OK?(Y/N)" 430 GOSUB 10 450 IF W=23 THEN GOTO 370 460 IF W<>34 THEN GOTO 430 470 NEXT X 480 RETURN 481 LET AA=AA+1 482 LET P(AA,1)=X 483 LET P(AA,2)=Y 484 RETURN 486 LET DA=DA+1 487 LET Q(DA,1)=X 488 LET Q(DA,2)=Y 489 RETURN 490 REM PRINT ALL DATA 495 CLS 496 GOSUB 50 500 FOR X=1 TO A 510 PRINT AT X+1,8;A$(X) 520 NEXT X 525 PRINT AT 18,0;R$;AT 21,11;"M = MENU" 526 IF INKEY$<>"M" THEN GOTO 526 530 GOTO 5000 550 REM COUNT ACROSS ANS 552 PRINT AT 18,0;"PLEASE WAIT" 553 PRINT AT 21,0;"CLUE WRITING COMING UP " 555 DIM P(20,2) 560 LET AA=0 570 FOR X=1 TO A 580 FOR Y=1 TO (A-1) 590 IF Y=1 THEN GOTO 610 600 IF A$(X,Y-1)<>"% " THEN GOTO 620 610 IF (A$(X,Y)<>"% " AND A$(X,Y+1)<>"% ") THEN GOSUB 481 620 NEXT Y 630 NEXT X 640 REM COUNT DOWN ANS 650 LET DA=0 655 DIM Q(20,2) 660 LET DA=0 670 FOR Y=1 TO A 680 FOR X=1 TO A-1 690 IF X=1 THEN GOTO 710 700 IF A$(X-1,Y)<>"% " THEN GOTO 720 710 IF (A$(X,Y)<>"% " AND A$(X+1,Y)<>"% ") THEN GOSUB 486 720 NEXT X 730 NEXT Y 740 RETURN 750 REM WRITE ACROSS CLUES 760 DIM P$(AA,64) 765 DIM X$(AA,7) 770 FOR X=1 TO AA 780 FOR Y=P(X,2) TO A 790 IF Y=A THEN GOTO 810 795 IF A$(P(X,1),Y+1)="% " THEN GOTO 810 800 NEXT Y 810 PRINT AT 18,0;"ENTER CLUE FOR: ";A$(P(X,1),P(X,2) TO Y) 820 INPUT P$(X) 830 PRINT AT 19,0;P$(X) 840 PRINT AT 18,0;"IS THIS OK?(Y/N) " 850 GOSUB 10 870 IF INKEY$=CHR$ 51 THEN GOTO 810 880 IF INKEY$<>CHR$ 62 THEN GOTO 840 890 PRINT AT 18,0;"ENTER NO. OF LETTERS" 900 INPUT X$(X) 905 GOSUB 1300 910 NEXT X 920 REM WRITE DOWN CLUES 930 DIM Q$(DA,64) 940 DIM Y$(DA,7) 950 FOR Y=1 TO DA 960 FOR X=Q(Y,1) TO A 970 IF X=A THEN GOTO 1000 980 IF A$(X+1,Q(Y,2))="% " THEN GOTO 1000 990 NEXT X 1000 PRINT AT 18,0;"ENTER CLUE FOR: "; 1010 FOR Z=Q(Y,1) TO X 1020 PRINT A$(Z,Q(Y,2)); 1030 NEXT Z 1040 INPUT Q$(Y) 1050 PRINT AT 19,0;Q$(Y) 1060 PRINT AT 18,0;"IS THIS OK?(Y/N) " 1070 GOSUB 10 1090 IF INKEY$=CHR$ 51 THEN GOTO 1000 1100 IF INKEY$<>CHR$ 62 THEN GOTO 1060 1120 PRINT AT 18,0;"ENTER NO.OF LETTERS" 1130 INPUT Y$(Y) 1135 GOSUB 1300 1140 NEXT Y 1150 RETURN 1160 REM FIND ACROSS CLUE 1170 FOR J=1 TO AA 1180 IF (P(J,1)=M AND P(J,2)=N) THEN GOTO 1200 1190 NEXT J 1195 IF (P(J,1)<>M OR P(J,2)<>N) THEN GOTO 3250 1200 PRINT AT 18,0;P$(J) 1210 PRINT "LETTERS: ";X$(J);" " 1220 RETURN 1230 REM FIND DOWN CLUE 1240 FOR J=1 TO DA 1250 IF (Q(J,1)=M AND Q(J,2)=N) THEN GOTO 1260 1255 NEXT J 1256 IF (Q(J,1)<>M OR Q(J,2)<>N) THEN GOTO 3250 1260 PRINT AT 18,0;Q$(J) 1270 PRINT "LETTERS: ";Y$(J);" " 1280 RETURN 1300 REM BLANK LAST LINES 1310 FOR F=18 TO 21 1320 PRINT AT F,0;" " 1330 NEXT F 1340 RETURN 1350 FOR X=1 TO LEN (U$) 1351 IF N-1+X>A THEN GOTO 3380 1352 IF U$(X)<>A$(M,N-1+X) THEN GOTO 3380 1353 NEXT X 1355 GOSUB 1300 1360 FOR X=1 TO LEN (U$) 1370 IF N-1+X>A THEN GOTO 1400 1371 IF A$(M,N-1+X)="% " THEN GOTO 1400 1380 PRINT AT M+1,N+6+X;U$(X) 1390 NEXT X 1400 RETURN 1410 FOR X=1 TO LEN (U$) 1411 IF M-1+X>A THEN GOTO 3380 1412 IF U$(X)<>A$(M-1+X,N) THEN GOTO 3380 1413 NEXT X 1415 GOSUB 1300 1420 FOR X=1 TO LEN (U$) 1430 IF M+X-1>A THEN GOTO 1460 1431 IF A$(M+X-1,N)="% " THEN GOTO 1460 1440 PRINT AT M+X,N+7;U$(X) 1450 NEXT X 1460 RETURN 1500 GOSUB 1300 1505 IF IK=38 THEN GOSUB 1600 1510 IF IK=41 THEN GOSUB 1700 1520 GOTO 3250 1600 FOR X=N TO A 1610 PRINT AT M+1,X+7;A$(M,X) 1620 IF A$(M,X)="% " THEN GOTO 1640 1630 NEXT X 1640 RETURN 1700 FOR X=M TO A 1710 PRINT AT X+1,N+7;A$(X,N) 1720 IF A$(X,N)="% " THEN GOTO 1740 1730 NEXT X 1740 RETURN 2000 PRINT AT 21,0;"ENTER ANSWER " 2010 INPUT U$ 2020 IF IK=38 THEN GOSUB 1350 2030 IF IK=41 THEN GOSUB 1410 2040 GOTO 3250 2500 CLS 2501 PRINT AT 11,0;"YOU WANT TO WRITE A NEW PUZZLE" 2502 PRINT AT 13,5;"IS THAT RIGHT? (Y/N)" 2503 GOSUB 10 2505 IF INKEY$<>CHR$ 62 THEN GOTO 5000 2510 GOSUB 290 2520 GOSUB 50 2530 GOSUB 350 2540 GOSUB 550 2545 GOSUB 1300 2550 GOSUB 750 2560 GOTO 5000 3200 CLS 3201 PRINT AT 19,0;R$ 3203 GOSUB 50 3210 GOSUB 220 3250 GOSUB 1300 3260 PRINT AT 14,26;" ";AT 15,26;" " 3265 PRINT AT 18,0;"ACROSS OR DOWN CLUE?(A/D) X = EXIT" 3270 GOSUB 30 3280 IF W=33 THEN GOTO 5000 3285 LET IK=W+28 3290 IF IK<>38 AND IK<>41 THEN GOTO 3260 3291 IF IK=38 THEN PRINT AT 14,26;"%A%C%R%O%S%S" 3292 IF IK=41 THEN PRINT AT 14,26;"%D%O%W%N" 3300 PRINT AT 19,0;" ";AT 18,0;"LINE NUMBER? " 3301 GOSUB 10 3310 LET M=W 3311 IF (M<1 OR M>A) THEN GOTO 3300 3315 PRINT AT 15,26;CHR$ (M+28);"," 3320 PRINT AT 18,0;"COLUMN LETTER? " 3321 GOSUB 10 3340 LET N=W-9 3345 GOSUB 1300 3350 IF (N<1 OR N>A) THEN GOTO 3320 3355 PRINT AT 15,28;CHR$ (N+37) 3360 IF IK=38 THEN GOSUB 1160 3370 IF IK=41 THEN GOSUB 1230 3380 PRINT AT 21,0;"% A = ANSWER% B = BACK% C = CHEAT% " 3390 GOSUB 10 3400 IF W=10 THEN GOTO 2000 3405 IF W=12 THEN GOTO 1500 3410 IF W<>11 THEN GOTO 3380 3420 GOTO 3250 4950 CLS 4960 PRINT "START TAPE AND THEN PRESS S" 4965 PRINT AT 5,0;"M = MENU" 4970 GOSUB 10 4976 IF INKEY$=CHR$ 50 THEN GOTO 5000 4980 IF INKEY$<>CHR$ 56 THEN GOTO 4970 4990 SAVE "XWOR%D" 4995 SLOW 5000 CLS 5010 PRINT AT 3,4;"% W% " 5020 PRINT AT 4,3;"CROSS (C) C. JONES" 5030 PRINT AT 5,4;"% R% " 5040 PRINT AT 6,5;"DO YOU WANT TO...." 5050 PRINT AT 8,5;"1 - SOLVE A PUZZLE?" 5060 PRINT AT 10,5;"2 - SAVE A PUZZLE?" 5070 PRINT AT 12,5;"3 - WRITE A NEW PUZZLE?" 5080 PRINT AT 14,5;"4 - SEE THE ANSWERS?" 5085 GOSUB 10 5110 IF W=1 THEN GOTO 3200 5120 IF W=2 THEN GOTO 4950 5130 IF W=3 THEN GOTO 2500 5140 IF W=4 THEN GOTO 490 5150 GOTO 5085 ```