This program manages and prints a Druidical spell list for Dungeons and Dragons, collecting up to 16 spells each for levels 1–3, and 12 spells each for levels 4–7, then formatting them onto a printed listing via LPRINT. Spell names are entered interactively in triplets or pairs, packed into fixed-length string arrays (A$, B$, C$) of 64 characters each by concatenating 20-character sub-strings. An 80-column printer is required, as each packed row spans three or two 20-character spell names side by side. The program requires manual entry via GO TO 610 rather than RUN, as noted in the REM at line 3. Clearing buffers by assigning E$(1) (an empty string array row) back to the input variables between iterations is an efficient way to blank working strings without re-dimensioning.
Program Analysis
Program Structure
The program is divided into three phases: data entry, a pause/menu stub, and printing. Lines 5–100 declare all working arrays. Lines 200–590 handle interactive input in three loops. Lines 600–605 present a brief stop with instructions. Lines 610–800 perform the actual LPRINT output. Line 9905 contains a SAVE command and line 9910 loops back to the print routine.
- Initialisation (5–100): Declares single-row 20-character working strings and three multi-row packed arrays.
- Level 1–3 input loop (200–320): 16 iterations; packs three 20-char spell names into one 64-char row of
A$. - Level 4–5 input loop (350–440): 12 iterations; packs two 20-char names into one 40-char row of
B$(declared as 64 chars). - Level 6–7 input loop (500–590): 12 iterations; packs two 20-char names into one 40-char row of
C$. - Menu stub (600–605): Prints GO TO instructions and STOPs; user must manually GO TO 610.
- Print section (610–800): Dumps all three arrays to the printer with spacing.
- Save/restart (9905–9910): SAVEs the program, then GO TO 610.
Array Layout
| Array | Dimensions | Contents | Spell levels packed |
|---|---|---|---|
A$(16,64) | 16 rows × 64 chars | Three 20-char spell names per row | 1st, 2nd, 3rd |
B$(12,64) | 12 rows × 64 chars | Two 20-char spell names per row | 4th, 5th |
C$(12,64) | 12 rows × 64 chars | Two 20-char spell names per row | 6th, 7th |
Key BASIC Idioms
- Single-row working arrays as input buffers:
F$(1,20),S$(1,20), etc. are dimensioned as 1-row arrays so thatINPUT F$(1)fills the entire row as a fixed-length string. This ensures consistent 20-character strings for concatenation. - Buffer clearing via E$: After packing each row, variables are reset by assigning
E$(1)(which is always a blank 20-character string sinceE$is never written to). This is a clean zero-without-retyping technique. - String concatenation into packed rows:
LET A$(Z)=F$(1)+S$(1)+T$(1)at line 270 concatenates three 20-character strings into a single 60-character value stored in a 64-character row, relying on string assignment padding the remainder with spaces. - PAUSE 4E4: Line 620 uses
PAUSE 4E4(40,000 frames ≈ 11 minutes on a 50 Hz machine) as an extended wait before printing, effectively pausing until the user presses a key. - Manual GO TO entry point: REM at line 3 explicitly warns not to RUN the program but to GO TO 610 to reach the print section after the STOP at line 605. This is required because RUN would restart data entry.
Notable Techniques
The use of DIM E$(1,20) as a permanent blank-string source is economical: rather than assigning a string literal of spaces, the program exploits the fact that a freshly dimensioned string array is initialised to all spaces, and E$ is never overwritten, so it always holds 20 spaces.
Packing multiple spell names side-by-side into a single array row (rather than using separate arrays per level) reduces the number of array variables needed and produces columnar output when LPRINTed on an 80-column printer — three 20-character columns fit neatly in 60 characters with room to spare.
Bugs and Anomalies
- Loop variable collision: The outer FOR loop at lines 500–590 iterates on
Z, butZis also the name of a declared string array (Z$(1,20)) used as an input buffer inside the same loop (line 540). This is legal because the numeric variableZand the string arrayZ$are distinct, but it is confusing style. - B$ and C$ packing mismatch:
B$(12,64)andC$(12,64)are declared 64 characters wide, but only 40 characters (two 20-char names) are packed into each row. The trailing 24 characters will always be spaces, wasting approximately 288 bytes per array. - No input length validation: If a user enters a spell name longer than 20 characters, the INPUT into a 20-char array row will either truncate or cause an error, depending on the interpreter’s behaviour.
- SAVE at line 9905 then GO TO 610: After saving, the program jumps directly to the print routine at line 9910, which may be intentional to confirm data is intact, but could confuse users who expect the program to terminate after saving.
Content
Source Code
0 REM %D%R%U%I%D%I%C%A%L% %S%P%E%L%L% %L%I%S%T FOR DUNGEONS AND DRAGONS BY ANTHONY WILLING 3-2-86 80 COLUMN PRINTER REQUIRED
3 REM %N%E%V%E%R% %R%U%N%,% %U%S%E% %G%O%T%O% %6%1%0
5 DIM E$(1,20)
10 DIM F$(1,20)
20 DIM S$(1,20)
30 DIM T$(1,20)
40 DIM U$(1,20)
50 DIM V$(1,20)
60 DIM X$(1,20)
70 DIM Z$(1,20)
80 DIM A$(16,64)
90 DIM B$(12,64)
100 DIM C$(12,64)
200 FOR Z=1 TO 16
210 PRINT "INPUT 1ST LEVEL SPELL ";Z
220 INPUT F$(1)
230 PRINT "INPUT 2ND LEVEL SPELL ";Z
240 INPUT S$(1)
250 PRINT "INPUT 3RD LEVEL SPELL ";Z
260 INPUT T$(1)
270 LET A$(Z)=F$(1)+S$(1)+T$(1)
280 LET F$(1)=E$(1)
290 LET S$(1)=E$(1)
300 LET T$(1)=E$(1)
310 CLS
320 NEXT Z
350 FOR Z=1 TO 12
360 PRINT "INPUT 4TH LEVEL SPELL ";Z
370 INPUT U$(1)
380 PRINT "INPUT 5TH LEVEL SPELL ";Z
390 INPUT V$(1)
400 LET B$(Z)=U$(1)+V$(1)
410 LET U$(1)=E$(1)
420 LET V$(1)=E$(1)
430 CLS
440 NEXT Z
500 FOR Z=1 TO 12
510 PRINT "INPUT 6TH LEVEL SPELL ";Z
520 INPUT X$(1)
530 PRINT "INPUT 7TH LEVEL SPELL ";Z
540 INPUT Z$(1)
550 LET C$(Z)=X$(1)+Z$(1)
560 LET X$(1)=E$(1)
570 LET Z$(1)=E$(1)
580 CLS
590 NEXT Z
600 CLS
603 PRINT "GOTO 610 FOR SPELL LIST"
604 PRINT "GOTO 9900 TO SAVE"
605 STOP
610 PRINT "PRESS ANY KEY",,"TO PRINT SPELL LISTS"
620 PAUSE 4E4
630 LPRINT "DRUIDICAL SPELLS"
650 LPRINT
660 LPRINT
670 FOR Z=1 TO 16
680 LPRINT A$(Z)
690 NEXT Z
700 LPRINT
710 LPRINT
720 FOR Z=1 TO 12
730 LPRINT B$(Z)
740 NEXT Z
750 LPRINT
760 LPRINT
770 FOR Z=1 TO 12
780 LPRINT C$(Z)
790 NEXT Z
800 STOP
9905 SAVE "1020%5"
9910 GOTO 610
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
