PAINTING is a color-by-number game that displays a 22-row by 32-column scene encoded as digit characters, then lets the player fill in each digit’s cells with its corresponding PAPER color. The subroutine at line 120 uses PRINT statements to render the entire scene as a grid of digit characters (0–7), with each digit representing a Spectrum PAPER color. The main loop polls INKEY$ to get the player’s color choice, scans the screen with SCREEN$ to find all matching characters, and replaces them with a PAPER-colored space, effectively “painting” that region. The game tracks which colors have been used by replacing the chosen digit in the string a$ with an asterisk, ending when all eight colors have been selected.
Program Structure
The program is divided into two logical sections: the drawing subroutine (lines 120–340) and the interactive game loop (lines 10–110). Execution begins at line 10 with a GO SUB 120 to render the scene, then enters a key-polling loop that processes color selections until all eight colors have been painted.
- Lines 10: Call the drawing subroutine.
- Lines 20–110: Main game loop — initialize the available-color string, wait for a valid digit key, paint matching cells, mark the color used, and check for completion.
- Lines 120–340: Subroutine that clears the screen and prints 22 rows of 32-character digit strings to form the encoded image.
- Line 350:
SAVEstatement with auto-start.
Scene Encoding
The picture is stored as plain PRINT statements, each outputting a 32-character string of digits 0–7. Each digit corresponds directly to a Spectrum PAPER color (0 = black, 1 = blue, 2 = red, 3 = magenta, 4 = green, 5 = cyan, 6 = yellow, 7 = white). This is a compact, purely BASIC encoding of a 22×32 color map — no DATA statements or arrays are needed. The bottom rows (lines 280–330) show a strong horizontal band of 4s (green) and 1s (blue), suggesting a landscape with sky.
Key-Polling and Validation
Line 40 waits for a keypress using INKEY$ in a tight loop, rejecting any key that is "*" (already-used color sentinel). Lines 50–60 scan the string a$ for a match, so only digits that remain unpainted are accepted. If no match is found by the end of the FOR loop, control falls through to GO TO 40 to try again.
SCREEN$ Flood Detection
Rather than using a flood-fill algorithm, the painting step (lines 70–90) performs a full-screen scan using SCREEN$. For every cell in the 22×32 grid, if the character matches the selected digit i$, it is overwritten with PRINT AT j,k; PAPER VAL i$;" ". This is an O(n) scan over all 704 cells and is simple but not instantaneous; the BEEP .1,50 at line 70 provides audible feedback while the scan proceeds.
Completion Tracking
Line 100 uses the string a$ as a bitmask: the chosen color’s position p is overwritten with "*". When all eight positions are "*" (i.e., a$="********"), the program halts with STOP. This avoids any separate counter variable.
Notable Techniques
SCREEN$(j,k)is used to read back the character at each screen position, making the scene data do double duty: it is both the display and the data store.PAPER VAL i$converts the digit character directly to a color number without an intermediate variable.- The initial
BEEP .1,20at line 30 serves as a “ready” cue before each selection, whileBEEP .1,50at line 70 signals a valid choice. - Storing the available colors in
a$and using string comparison for completion is a concise one-variable state machine.
Potential Issues
- The
FOR p=1 TO 8loop at line 50 uses 1-based indexing ona$, which is correct for Spectrum BASIC’s 1-based string subscripting. However,a$is initialized as"01234567"(characters, not the digit 0–7 numerically), soa$(p)returns the character at positionp, matching againsti$correctly. - Color 0 (black) is included in
a$, so the player can paint black cells — but painting black on the default black background produces invisible results unless the border or other context makes cells distinguishable. - Line 40 explicitly rejects
"*"as a keypress, but a player could theoretically press a non-digit key (e.g., a letter) that also does not match any entry ina$; the loop at lines 50–60 handles this gracefully by falling back toGO TO 40.
Content
Source Code
10 GO SUB 120
20 LET a$="01234567"
30 BEEP .1,20
40 LET i$= INKEY$:IF i$="*" THEN GO TO 40
50 FOR p=1 TO 8:IF i$=a$(p) THEN GO TO 70
60 NEXT p:GO TO 40
70 BEEP .1,50:FOR j=0 TO 21:FOR k=0 TO 31
80 IF SCREEN$ (j,k)=i$ THEN PRINT AT j,k; PAPER VAL i$;" "
90 NEXT k:NEXT j
100 LET a$(p)="*":IF a$="********" THEN STOP
110 GO TO 30
120 CLS :PRINT "55555775555555555555555565555556"
130 PRINT "55557777555555555557777556566565"
140 PRINT "22222777775555555577775555666655"
150 PRINT "66666277755577755557755666666666"
160 PRINT "44444625555777755555555555666655"
170 PRINT "11111462577777555555555556566565"
180 PRINT "33333146255775445555775565555556"
190 PRINT "55555314625555424477777555555445"
200 PRINT "55424531462555544244777755544244"
210 PRINT "54444553146254454445427755554442"
220 PRINT "44245555314624240504244555545244"
230 PRINT "24444555314625445054445542444050"
240 PRINT "44454455314625555055555554424405"
250 PRINT "05044245314625555055555445444204"
260 PRINT "50544444314625555055555444050405"
270 PRINT "50552555314625555055555525505505"
280 PRINT "40444444444444444044444444404404"
290 PRINT "40444444444444444044444444404404"
300 PRINT "40444441111114444444444444404404"
310 PRINT "40444111111111114444444444404444"
320 PRINT "40441111111111111114444444404444"
330 PRINT "40111111111111111111114444404444"
340 RETURN
350 SAVE "PAINTING" LINE 0
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
