Generates a symmetrical, multi-colored arc pattern on screen using the DRAW command with arc (angle) parameters. The program first calculates a series of random line segments and arc angles, storing them in a two-dimensional array, then renders the complete path four times using reflections across both axes (all four sign combinations of ±1) to produce a fourfold-symmetric figure. After drawing, it directly POKEs the display-file attribute bytes at address 22895 to colorize the image in random INK values, bypassing PAPER/INK BASIC statements for speed and granularity. A short two-note BEEP fanfare plays before the image pauses for display, then the program loops via RUN.
Program Structure
The program is organized into four logical phases:
- Initialization (lines 5–30): Sets display attributes, dimensions an array
a(d,3)to holdd=15line segments, and sets a starting plot position of (123, 84). - Path generation (lines 50–100): Randomly generates 15 displacement vectors and arc angles, validates them against screen bounds, and stores them.
- Drawing (lines 120–170): Renders the stored path four times with all combinations of ±1 scale factors, producing fourfold symmetry.
- Colorization and display (lines 190–510): POKEs random INK attribute values into the display file, plays a brief fanfare, pauses, then restarts.
Path Generation and Validation
Lines 60–90 generate each segment’s displacement (x, y) uniformly from ±212 and ±174 respectively, then reject any candidate that would push the accumulated position (x1, y1) outside the drawable area (38–213 horizontally, 1–168 vertically) via a GO TO 60 retry loop. This is a standard rejection-sampling idiom in BASIC graphics programs.
The arc angle c is computed on line 80 with a two-step formula. The first step initializes c as a value in [−6, 6] with a sign flip based on whether the current direction crosses the horizontal or vertical midline — this tends to keep arcs curving inward rather than spiraling outward. The second step dampens large arcs for short segments, dividing by up to 5 when both displacement components are large, which prevents visually chaotic tight spirals on long strokes.
Fourfold Symmetry Drawing
Lines 120–170 use nested FOR loops over a and c ranging from −1 to 1 step 2, giving the four sign pairs (−1,−1), (−1,+1), (+1,−1), (+1,+1). Each pass starts from the center point (123, 84) and replays the stored path with DRAW a*a(b,1), c*a(b,2), a*c*a(b,3). Multiplying the arc angle by both a and c ensures the arc curvature is correctly mirrored (reversing one axis alone would flip the arc direction, so the product maintains geometric consistency). OVER 1 is set at initialization so overlapping strokes XOR the pixel data rather than overwriting, creating additional visual complexity at intersections.
Attribute Colorization via POKE
Lines 190–230 directly write to the Spectrum attribute file. The base address c=22895 is close to the center of the attribute area (the full attribute file starts at 22528). The loops iterate with a from 0 to 352 in steps of 32 (i.e., row offsets) and b from 0 to 13 (column offsets within a row), POKEing all four symmetric attribute cells simultaneously:
c+b+a,c+b-a,c-b+a,c-b-a
This mirrors the fourfold symmetry of the drawn image in the color attributes. The attribute byte value is computed on lines 200–210: a random integer 0–7 is generated, values below 2 are bumped up by 5 (avoiding very dark colors 0 and 1), and then 64 is added to set the BRIGHT bit, ensuring vivid colors throughout.
Notable Techniques
- Reusing loop variable names (
a,b,c) across different phases saves memory on a RAM-constrained machine. - The arc angle sign heuristic on line 80 uses a compact boolean arithmetic expression:
(y1>84 AND x<0 OR y1<84 AND x>0)evaluates to 1 or 0, then is multiplied by −2 and added to 1, giving a sign factor without anIFbranch. RUNat line 510 restarts the program completely, re-executingRANDOMIZEto seed a new pattern each cycle.- The “THINKING” message printed at line 30 provides user feedback during the path-generation phase, which involves repeated rejection sampling and could otherwise appear frozen.
Potential Anomalies
The base POKE address 22895 is offset 367 bytes into the attribute file (22528 + 367), placing the center of the colorization at approximately row 15, column 15 of the attribute grid. This is not precisely the screen center (which would be row 11, col 16 = offset 368), but the difference is negligible visually. The colorization loops using ±a offsets up to 352 can reach addresses outside the 768-byte attribute file, potentially POKEing into the printer buffer area above address 23295, though this is unlikely to cause a crash in normal operation.
Source Code
5 REM "RAINBOW RIOT"
10 RANDOMIZE : BORDER 0: PAPER 0: INK 7: OVER 1
20 LET d=15: DIM a(d,3)
30 LET y1=84: LET x1=123: PRINT AT 10,12;"THINKING"
50 FOR b=1 TO d
60 LET x=213-INT (RND*426): LET y=175-INT (RND*350)
70 IF x1+x>213 OR y1+y>168 OR x1+x<38 OR y1+y<=0 THEN GO TO 60
80 LET c=6*RND*(1-2*(y1>84 AND x<0 OR y1<84 AND x>0)): LET c=c*2/(2+(ABS c>4)*(ABS x>20 OR ABS y>20)+2*(ABS x>50 OR ABS y>50))
90 LET x1=x1+x: LET y1=y1+y: LET a(b,1)=x: LET a(b,2)=y: LET a(b,3)=c
100 NEXT b
120 CLS : FOR a=-1 TO 1 STEP 2: FOR c=-1 TO 1 STEP 2
130 PLOT 123,84
140 FOR b=1 TO d
150 DRAW a*a(b,1),c*a(b,2),a*c*a(b,3)
160 NEXT b
170 NEXT c: NEXT a
190 LET p=0: LET c=22895: FOR a=0 TO 352 STEP 32: FOR b=0 TO 13
200 LET at=INT (RND*8)
210 LET at=at+5*(at<2)+64
220 POKE c+b+a,at: POKE c+b-a,at: POKE c-b+a,at: POKE c-b-a,at
230 NEXT b: NEXT a
235 BEEP .5,10: BEEP .5,5
500 PAUSE 180: CLS
510 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
