The chart is more useful when you can ask another question without typing RUN. Compare a fresh batch with the previous one, or add rolls to the sample already on screen.
Continue from Watch the distribution. This completes the experiment: four batch sizes, a previous-result column and controls for fresh and accumulated samples.
Replace lines 20, 30, 460, 750, 1030. Add lines 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 300, 310, 320, 330, 340, 350, 360, 400, 410, 420, 425, 730, 740, 1010, 1060, 1070, 8000, 8010, 8020, 8030, 8040. There are no lines to delete.
20 RANDOMIZE : DIM t(6): DIM p(6)
30 LET n=0: LET pn=0: LET b=60: LET h$="####################": LET z$=" "
100 CLS : PRINT AT 2,8; INK 5; BRIGHT 1;"DICE ROLLER"
110 PRINT AT 5,2;"Explore a six-sided die."
120 PRINT AT 7,2;"Choose a fresh batch:"
130 PRINT AT 9,5;"1 12 rolls"
140 PRINT AT 10,5;"2 60 rolls"
150 PRINT AT 11,5;"3 300 rolls"
160 PRINT AT 12,5;"4 1200 rolls"
170 PRINT AT 15,2;"Then repeat, or add more."
180 PRINT AT 17,2;"Samples vary. Compare shares."
190 PRINT AT 20,2;"1-4 chooses. Q quits."
200 GO SUB 8000
210 IF k$="q" THEN STOP
220 IF k$<"1" OR k$>"4" THEN GO TO 200
230 LET b=12
240 IF k$="2" THEN LET b=60
250 IF k$="3" THEN LET b=300
260 IF k$="4" THEN LET b=1200
270 LET add=0: GO TO 400
300 GO SUB 8000
310 IF k$="q" THEN STOP
320 IF k$="n" THEN GO TO 100
330 IF k$="r" THEN LET add=0: GO TO 400
340 IF k$="a" AND n+b<=9600 THEN LET add=1: GO TO 400
350 IF k$="a" THEN PRINT AT 19,1;"9600 limit. R starts fresh. "
360 GO TO 300
400 LET pn=n: FOR j=1 TO 6: LET p(j)=t(j): NEXT j
410 IF add=0 THEN DIM t(6): LET n=0
420 LET target=n+b: LET done=0
425 LET pace=1: IF b>=300 THEN LET pace=10
460 IF i/pace=INT (i/pace) OR i=1 THEN GO SUB 1100
730 PRINT AT 20,1;"R new ";b;" A +";b;" N sizes"
740 PRINT AT 21,1;"Q quits."
750 GO TO 300
1010 PRINT AT 1,14;"Prev ";pn
1030 PRINT AT 4,1; INK 5;"FACE COUNT NOW% PREV%"
1060 IF pn>0 THEN PRINT AT row,24;INT (1000*p(j)/pn+0.5)/10
1070 IF pn=0 THEN PRINT AT row,24;"--"
8000 LET k$=INKEY$
8010 IF INKEY$<>"" THEN GO TO 8010
8020 LET k$=INKEY$: IF k$="" THEN GO TO 8020
8030 IF CODE k$>=65 AND CODE k$<=90 THEN LET k$=CHR$ (CODE k$+32)
8040 RETURNComplete program at this stage
10 BORDER 0: PAPER 0: INK 7: BRIGHT 0: CLS
20 RANDOMIZE : DIM t(6): DIM p(6)
30 LET n=0: LET pn=0: LET b=60: LET h$="####################": LET z$=" "
100 CLS : PRINT AT 2,8; INK 5; BRIGHT 1;"DICE ROLLER"
110 PRINT AT 5,2;"Explore a six-sided die."
120 PRINT AT 7,2;"Choose a fresh batch:"
130 PRINT AT 9,5;"1 12 rolls"
140 PRINT AT 10,5;"2 60 rolls"
150 PRINT AT 11,5;"3 300 rolls"
160 PRINT AT 12,5;"4 1200 rolls"
170 PRINT AT 15,2;"Then repeat, or add more."
180 PRINT AT 17,2;"Samples vary. Compare shares."
190 PRINT AT 20,2;"1-4 chooses. Q quits."
200 GO SUB 8000
210 IF k$="q" THEN STOP
220 IF k$<"1" OR k$>"4" THEN GO TO 200
230 LET b=12
240 IF k$="2" THEN LET b=60
250 IF k$="3" THEN LET b=300
260 IF k$="4" THEN LET b=1200
270 LET add=0: GO TO 400
300 GO SUB 8000
310 IF k$="q" THEN STOP
320 IF k$="n" THEN GO TO 100
330 IF k$="r" THEN LET add=0: GO TO 400
340 IF k$="a" AND n+b<=9600 THEN LET add=1: GO TO 400
350 IF k$="a" THEN PRINT AT 19,1;"9600 limit. R starts fresh. "
360 GO TO 300
400 LET pn=n: FOR j=1 TO 6: LET p(j)=t(j): NEXT j
410 IF add=0 THEN DIM t(6): LET n=0
420 LET target=n+b: LET done=0
425 LET pace=1: IF b>=300 THEN LET pace=10
430 GO SUB 1000
435 PRINT AT 19,1;"Rolling... Q stops this batch."
440 FOR i=1 TO b
450 LET d=INT (RND*6)+1: LET t(d)=t(d)+1: LET n=n+1: LET done=done+1
460 IF i/pace=INT (i/pace) OR i=1 THEN GO SUB 1100
470 LET k$=INKEY$
480 IF k$="q" OR k$="Q" THEN GO TO 600
490 NEXT i
600 GO SUB 1000: GO SUB 1100
720 PRINT AT 19,1;"Samples vary; no fairness proof."
725 IF done<b THEN PRINT AT 19,1;"Stopped early. Counts kept. "
730 PRINT AT 20,1;"R new ";b;" A +";b;" N sizes"
740 PRINT AT 21,1;"Q quits."
750 GO TO 300
1000 CLS : PRINT AT 0,9; INK 5; BRIGHT 1;"DICE ROLLER"
1010 PRINT AT 1,14;"Prev ";pn
1020 PRINT AT 2,1;"Bars 0-100%; rounded to 5%."
1030 PRINT AT 4,1; INK 5;"FACE COUNT NOW% PREV%"
1040 FOR j=1 TO 6: LET row=5+2*(j-1)
1050 PRINT AT row,2;j;AT row+1,5;CHR$ 91;AT row+1,26;CHR$ 93
1060 IF pn>0 THEN PRINT AT row,24;INT (1000*p(j)/pn+0.5)/10
1070 IF pn=0 THEN PRINT AT row,24;"--"
1080 NEXT j: PRINT AT 18,1;"Fair model: about 16.7% each."
1090 RETURN
1100 PRINT AT 1,1;"Rolls ";n;" "
1110 FOR j=1 TO 6
1120 LET row=5+2*(j-1): LET pc=INT (1000*t(j)/n+0.5)/10
1130 PRINT AT row,7;t(j);" ";AT row,15;pc;" "
1140 LET width=INT (20*t(j)/n+0.5)
1150 PRINT AT row+1,6; INK 5;h$( TO width);z$( TO 20-width)
1160 NEXT j
1170 PRINT AT 20,1;"Batch ";done;" / ";b;" "
1180 RETURN
8000 LET k$=INKEY$
8010 IF INKEY$<>"" THEN GO TO 8010
8020 LET k$=INKEY$: IF k$="" THEN GO TO 8020
8030 IF CODE k$>=65 AND CODE k$<=90 THEN LET k$=CHR$ (CODE k$+32)
8040 RETURNRUN. Choose 1–4 for 12, 60, 300 or 1,200 rolls. At a result, R starts a fresh batch of the same size, A adds that many rolls, and N returns to size selection. Q stops a running batch early; at a result or size menu it quits to BASIC.
Keep the old result before changing it
The new p() array stores the previous six tallies, while pn stores their total. At line 400, copy the current sample into those variables. Only afterwards may line 410 clear t() and n for a fresh run.
The variable add chooses which operation happens: zero means start fresh; one means keep the current counts. DIM t(6) clears all six entries together. It does not clear the separate p() array.
The header routine prints the previous shares once. It divides each p(j) by pn, rather than by the changing current total. On the first run pn is zero, so it prints dashes instead of attempting division. Both totals stay visible at the top; the previous percentages remain fixed while the current chart develops.
You finish twelve rolls, then press A. Why are the resulting samples of twelve and twenty-four not independent experiments?
Show the explanation
The twenty-four-roll sample contains all twelve rolls from its predecessor, plus twelve new ones. The two results overlap. R instead clears the current sample before drawing a fresh batch from the continuing pseudorandom sequence.
Make each press one choice
The subroutine at 8000 first waits for every key to be released, then waits for a new key. CODE reads its character code. Codes 65 through 90 are uppercase letters. Adding 32 and using CHR$ produces the lowercase equivalent. Digits are left unchanged.
The release gate prevents a held R from repeatedly starting batches. It also keeps a held Q from stopping a batch and immediately quitting its result. Release the key, then press again for another action.
The size menu rejects anything outside the strings "1" through "4". Line 230 begins with twelve; the next three lines change b for the other choices. Choosing a size sets add to zero, so it always starts fresh. At a result, unknown keys loop back without altering either sample. GO TO selects a different part of the program; unlike GO SUB, it does not arrange a return.
Count every roll, print less often
Before each batch, line 420 records its intended target and resets done to zero. n is the whole current sample; done is only this batch’s progress. After adding twelve rolls to a sample of twelve, n is twenty-four but done is twelve.
The variable pace is one for batches of twelve and sixty, ten for the larger choices. At line 460, i/pace=INT (i/pace) is true when i is an exact multiple of pace. The extra OR i=1 shows the first roll immediately. Every roll still updates the counts. Only display calls are spaced out, giving BASIC less printing to do. The result at 600 always redraws the exact final or stopped state.
Line 340 permits an addition only when n+b<=9600. At the limit, A displays a message and changes neither sample. R starts fresh. This limit keeps the experiment bounded; it does not mark a statistical threshold where randomness becomes trustworthy.
Try several twelve-roll batches, then compare larger ones. Larger samples often have shares closer to the fair-model reference, but a particular larger sample need not look more balanced than the preceding smaller one. No screen in this program proves fairness.
Keep a copy
Quit with Q at a result or the size menu. Enter this direct command without a line number:
SAVE "dice" LINE 10Press Enter at the tape prompt and wait for 0 OK. In Emu198x, export the recording to a new .tap file using Cmd/Ctrl+Shift+E. The saving guide explains how recording inside the Spectrum differs from keeping a host file.
Load the exported tape in a fresh 48K machine using LOAD "" and tape playback, or tape autoload. The size menu should appear. Initialisation clears both arrays, so this saves the reusable program rather than resuming the comparison you were viewing.
Check a complete cycle: choose twelve, add twelve, repeat fresh, select another size, stop it early, release Q and quit from the result. Counts should always add up to the displayed current total. The previous column should describe the result you just left, including a stopped partial result.
Keyboard notes
CODE uses I in extended mode; AND is Symbol Shift with Y. SAVE uses S in keyword mode. For LINE, enter extended mode, then Symbol Shift with 3. The SAVE command has no line number because you want to execute it now, not store it as part of the experiment.
Sources
Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapter 5, chapter 6, chapter 11, chapter 12, chapter 14, chapter 20.