1! Inform Randomization Test version 1.0, by David Griffith August 2002
2!
3! Simulates dropping balls through a grid of pegs to test the
4! interpreter's random number generator.  A bellcurve should be the
5! result.
6!
7! Also contains Andrew Hunter's randomization test which is found in the
8! Zoom tarball.  I'm not quite sure how it displays randomness, but I
9! put it in here anyway.
10!
11
12Constant LANES  80;
13Constant PEG_HEIGHT 40;
14
15! For the spread random test
16Constant usualIter = 20000;
17Constant time = 50;
18Global iterations = 0;
19
20Global Granularity = 1;
21Global Height = 0;
22Global Dropcount_curr = 0;
23Global Dropcount_last = 0;
24Array bin --> LANES + 1;
25
26Array count --> 70;
27
28! Drop a ball into a given lane.  Return the number of the bin the ball
29! eventually falls into.  A ball should never have the opportunity to
30! bounce to the left if it's already at the very left of the pegfield.
31! Likewise for the very right.  Therefore, balls should always be
32! dropped into the very middle.
33!
34[ drop initial_lane current_lane x y;
35	Dropcount_curr++;
36	current_lane = initial_lane;
37	for (x = PEG_HEIGHT: x > 0: x--) {
38		y = random(2);
39		if (y == 1) {	! Ball bounces left.
40			if (current_lane == 0) {
41				@set_cursor 3 20;
42				print "ERROR! Ball fell off left side!";
43				quit;
44			} else {
45				current_lane--;
46			}
47		}
48		if (y == 2) {	! Ball bounces right.
49			if (current_lane == LANES) {
50				@set_cursor 3 20;
51				print "ERROR! Ball fell of right side!";
52				quit;
53			} else {
54				current_lane++;
55			}
56		}
57	}
58	return current_lane;
59];
60
61
62[ display_bellcurve x y q top;
63	@split_window Height;
64	@set_window 1;
65	@erase_window 1;
66
67	for (x = 0: x <= LANES: x++) {
68		@set_cursor 1 1;
69		print "prev: ", Dropcount_last;
70		@set_cursor 2 1;
71		print "drops: ", Dropcount_curr;
72		@set_cursor 3 1;
73		print "granularity: ", Granularity;
74		@set_cursor 1 20;
75		print "Press <space> to pause.";
76		@set_cursor 2 20;
77		print "Press 'q' to quit.";
78		top = bin-->x / Granularity;
79		if (top < 0) {
80			top == 0;
81		}
82		if (top >= Height - 2) {
83			return 0;
84		}
85		for (y = 0: y <= top: y++) {
86			q = Height - y;
87			@set_cursor q x;
88			if (x == LANES/2) {
89				print (char) '|';
90			} else {
91				if (y == 0) {
92					print (char) '=';
93				} else {
94					print (char) 'o';
95				}
96			}
97		}
98	}
99	return 1;
100];
101
102
103[ Main_bellcurve x y reps ix num crap;
104
105	@set_window 0;
106	@erase_window -1;
107
108
109	print "^^This program drops ~balls~ from the very top-middle of
110a vertical two-dimensional field filled with pegs.  The balls bounce off
111the pegs either left or right until they drop into one of several slots
112at the bottom where they stack up.  There are one less than half as many
113levels of pegs as there are slots.  This means that if a ball always
114bounces left, it will fall the leftmost slot.  Likewise, a ball always
115bouncing right will fall into the rightmost slot.
116According to the laws of probability, if the bounces are totally random,
117a smooth bellcurve should appear when the balls are counted and put into
118a bar graph.  This program displays such a bar graph.^";
119
120	print "^A ball which settles in the center of the field is
121represented by '|'.^";
122
123	print "A ball which settles to the left or right of the center
124is represented by 'o'.^";
125
126	print "^How many drops (1 through 9) per ball drawn? ";
127
128	@read_char 1 ix;
129	if (ix >= '1' && ix <= '9') {
130		Granularity = ix - '0';
131	} else {
132		Granularity = 1;
133	}
134
135	print "^^Press any key to begin.  ";
136	@read_char 1 crap;
137
138	for (num = 0: num < LANES: num++) {
139		bin-->num = 0;
140	}
141	Height = $24-->0;
142	while (1) {
143		for (reps = 1: reps <= GRANULARITY: reps++) {
144			x = drop(LANES/2);
145		}
146		bin-->x = bin-->x + 1;
147		y = display_bellcurve();
148		if (y == 0) {
149			for (num = 0: num < LANES: num++) {
150				bin-->num = 0;
151			}
152			@erase_window 0;
153			@erase_window 1;
154			dropcount_last = dropcount_curr;
155			dropcount_curr = 0;
156			display_bellcurve();
157		}
158		@read_char 1 1 pause -> crap;
159		if (crap == ' ') {
160			@erase_window 1;
161			@set_cursor 1 20;
162			print "Paused.";
163
164			@read_char 1 pause crap;
165		} else {
166			if (crap == 'q' || crap == 'Q') {
167				@erase_window -1;
168				rtrue;
169			}
170		}
171	}
172];
173
174[ randomize_spread x y z;
175	for (x = 0: x < usualIter: ) {
176		for (z = 0: z < time: z++) {
177			x++;
178			y = random(69);
179			count-->y = count-->y + 1;
180		}
181		iterations = iterations + time;
182		Height = $24-->0;
183		display_spread();
184		@read_char 1 1 pause -> z;
185
186		if (z == ' ') {
187			@read_char 1 z;
188		} else {
189	! This does not exit the test correctly.
190			if (z == 'q' || z == 'Q') {
191				@erase_window -1;
192				rfalse;
193			}
194		}
195	}
196];
197
198[ display_spread x y z q largest;
199	@split_window Height;
200	@set_window 1;
201	@erase_window 1;
202
203	largest = 1;
204	for (x = 0: x < 70: x++) {
205		if (count-->x > largest) {
206			largest = count-->x;
207		}
208	}
209	@set_cursor 1 1;
210	print iterations, " iterations";
211	for (x = 0: x < 70: x++) {
212		z = (count-->x * (Height-2)) / largest;
213		q = 3 + (x % 6);
214		@set_colour q q;
215		for (y = 0: y <= z: y++) {
216			q = Height - y;
217			@set_cursor q x;
218			print (char) '#';
219		}
220	}
221	@set_colour 1 1;
222	@set_cursor 1 1;
223];
224
225[ Main_spread x;
226	for (x = 0: x < 70: x++) {
227		count-->x = 0;
228	}
229
230	Height = $24-->0;
231
232	while (1) {
233		randomize_spread();
234
235
236
237
238
239
240
241
242
243
244
245
246		display_spread();
247		@read_char -> x;
248	}
249];
250
251[ Main mychar;
252	while (1) {
253		print "^Inform Randomization Test version 1.0, by David
254		Griffith August 2002^^";
255		print "1) Bellcurve graph.^";
256		print "2) Spread graph.^";
257		print "q) Quit.^";
258		print "^Please select a test: ";
259		@read_char 1 mychar;
260		switch (mychar) {
261			'1':	Main_bellcurve();
262			'2':	Main_spread();
263			'q':	rtrue;
264			default: print "^";
265		}
266	}
267];
268
269[ pause;
270	rtrue;
271];
272