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:
- Solve a puzzle – line
3200 - Save to tape – line
4950 - Write a new puzzle – line
2500 - 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
10spins untilINKEY$="", line30spins until a key is held, thenW = CODE(INKEY$) − 28maps 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 arrayA$(A,A). - CHR$ arithmetic for labels: column headers use
CHR$(X+30)(columns 8…A+7 → characters'&'…) and row labels useCHR$(X+28)(rows 1…A → characters'!'…). The solve loop reverses this: line3340setsN = W − 9to 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 arraysP$(AA,64)/Q$(DA,64)andX$(AA,7)/Y$(DA,7)are dimensioned afterAAandDAare 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).
Content
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
\n1000 PRINT AT 18,0;"ENTER CLUE FOR: ";
\n1010 FOR Z=Q(Y,1) TO X
\n1020 PRINT A$(Z,Q(Y,2));
\n1030 NEXT Z
\n1040 INPUT Q$(Y)
\n1050 PRINT AT 19,0;Q$(Y)
\n1060 PRINT AT 18,0;"IS THIS OK?(Y/N) "
\n1070 GOSUB 10
\n1090 IF INKEY$=CHR$ 51 THEN GOTO 1000
\n1100 IF INKEY$<>CHR$ 62 THEN GOTO 1060
\n1120 PRINT AT 18,0;"ENTER NO.OF LETTERS"
\n1130 INPUT Y$(Y)
\n1135 GOSUB 1300
\n1140 NEXT Y
\n1150 RETURN
\n1160 REM FIND ACROSS CLUE
\n1170 FOR J=1 TO AA
\n1180 IF (P(J,1)=M AND P(J,2)=N) THEN GOTO 1200
\n1190 NEXT J
\n1195 IF (P(J,1)<>M OR P(J,2)<>N) THEN GOTO 3250
\n1200 PRINT AT 18,0;P$(J)
\n1210 PRINT "LETTERS: ";X$(J);" "
\n1220 RETURN
\n1230 REM FIND DOWN CLUE
\n1240 FOR J=1 TO DA
\n1250 IF (Q(J,1)=M AND Q(J,2)=N) THEN GOTO 1260
\n1255 NEXT J
\n1256 IF (Q(J,1)<>M OR Q(J,2)<>N) THEN GOTO 3250
\n1260 PRINT AT 18,0;Q$(J)
\n1270 PRINT "LETTERS: ";Y$(J);" "
\n1280 RETURN
\n1300 REM BLANK LAST LINES
\n1310 FOR F=18 TO 21
\n1320 PRINT AT F,0;" "
\n1330 NEXT F
\n1340 RETURN
\n1350 FOR X=1 TO LEN (U$)
\n1351 IF N-1+X>A THEN GOTO 3380
\n1352 IF U$(X)<>A$(M,N-1+X) THEN GOTO 3380
\n1353 NEXT X
\n1355 GOSUB 1300
\n1360 FOR X=1 TO LEN (U$)
\n1370 IF N-1+X>A THEN GOTO 1400
\n1371 IF A$(M,N-1+X)="% " THEN GOTO 1400
\n1380 PRINT AT M+1,N+6+X;U$(X)
\n1390 NEXT X
\n1400 RETURN
\n1410 FOR X=1 TO LEN (U$)
\n1411 IF M-1+X>A THEN GOTO 3380
\n1412 IF U$(X)<>A$(M-1+X,N) THEN GOTO 3380
\n1413 NEXT X
\n1415 GOSUB 1300
\n1420 FOR X=1 TO LEN (U$)
\n1430 IF M+X-1>A THEN GOTO 1460
\n1431 IF A$(M+X-1,N)="% " THEN GOTO 1460
\n1440 PRINT AT M+X,N+7;U$(X)
\n1450 NEXT X
\n1460 RETURN
\n1500 GOSUB 1300
\n1505 IF IK=38 THEN GOSUB 1600
\n1510 IF IK=41 THEN GOSUB 1700
\n1520 GOTO 3250
\n1600 FOR X=N TO A
\n1610 PRINT AT M+1,X+7;A$(M,X)
\n1620 IF A$(M,X)="% " THEN GOTO 1640
\n1630 NEXT X
\n1640 RETURN
\n1700 FOR X=M TO A
\n1710 PRINT AT X+1,N+7;A$(X,N)
\n1720 IF A$(X,N)="% " THEN GOTO 1740
\n1730 NEXT X
\n1740 RETURN
\n2000 PRINT AT 21,0;"ENTER ANSWER "
\n2010 INPUT U$
\n2020 IF IK=38 THEN GOSUB 1350
\n2030 IF IK=41 THEN GOSUB 1410
\n2040 GOTO 3250
\n2500 CLS
\n2501 PRINT AT 11,0;"YOU WANT TO WRITE A NEW PUZZLE"
\n2502 PRINT AT 13,5;"IS THAT RIGHT? (Y/N)"
\n2503 GOSUB 10
\n2505 IF INKEY$<>CHR$ 62 THEN GOTO 5000
\n2510 GOSUB 290
\n2520 GOSUB 50
\n2530 GOSUB 350
\n2540 GOSUB 550
\n2545 GOSUB 1300
\n2550 GOSUB 750
\n2560 GOTO 5000
\n3200 CLS
\n3201 PRINT AT 19,0;R$
\n3203 GOSUB 50
\n3210 GOSUB 220
\n3250 GOSUB 1300
\n3260 PRINT AT 14,26;" ";AT 15,26;" "
\n3265 PRINT AT 18,0;"ACROSS OR DOWN CLUE?(A/D) X = EXIT"
\n3270 GOSUB 30
\n3280 IF W=33 THEN GOTO 5000
\n3285 LET IK=W+28
\n3290 IF IK<>38 AND IK<>41 THEN GOTO 3260
\n3291 IF IK=38 THEN PRINT AT 14,26;"%A%C%R%O%S%S"
\n3292 IF IK=41 THEN PRINT AT 14,26;"%D%O%W%N"
\n3300 PRINT AT 19,0;" ";AT 18,0;"LINE NUMBER? "
\n3301 GOSUB 10
\n3310 LET M=W
\n3311 IF (M<1 OR M>A) THEN GOTO 3300
\n3315 PRINT AT 15,26;CHR$ (M+28);","
\n3320 PRINT AT 18,0;"COLUMN LETTER? "
\n3321 GOSUB 10
\n3340 LET N=W-9
\n3345 GOSUB 1300
\n3350 IF (N<1 OR N>A) THEN GOTO 3320
\n3355 PRINT AT 15,28;CHR$ (N+37)
\n3360 IF IK=38 THEN GOSUB 1160
\n3370 IF IK=41 THEN GOSUB 1230
\n3380 PRINT AT 21,0;"% A = ANSWER% B = BACK% C = CHEAT% "
\n3390 GOSUB 10
\n3400 IF W=10 THEN GOTO 2000
\n3405 IF W=12 THEN GOTO 1500
\n3410 IF W<>11 THEN GOTO 3380
\n3420 GOTO 3250
\n4950 CLS
\n4960 PRINT "START TAPE AND THEN PRESS S"
\n4965 PRINT AT 5,0;"M = MENU"
\n4970 GOSUB 10
\n4976 IF INKEY$=CHR$ 50 THEN GOTO 5000
\n4980 IF INKEY$<>CHR$ 56 THEN GOTO 4970
\n4990 SAVE "XWOR%D"
\n4995 SLOW
\n5000 CLS
\n5010 PRINT AT 3,4;"% W% "
\n5020 PRINT AT 4,3;"CROSS (C) C. JONES"
\n5030 PRINT AT 5,4;"% R% "
\n5040 PRINT AT 6,5;"DO YOU WANT TO...."
\n5050 PRINT AT 8,5;"1 - SOLVE A PUZZLE?"
\n5060 PRINT AT 10,5;"2 - SAVE A PUZZLE?"
\n5070 PRINT AT 12,5;"3 - WRITE A NEW PUZZLE?"
\n5080 PRINT AT 14,5;"4 - SEE THE ANSWERS?"
\n5085 GOSUB 10
\n5110 IF W=1 THEN GOTO 3200
\n5120 IF W=2 THEN GOTO 4950
\n5130 IF W=3 THEN GOTO 2500
\n5140 IF W=4 THEN GOTO 490
\n5150 GOTO 5085
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

