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
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
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

