«Confetti 3» by henklass

on 14 May'15 11:33 in randomgraphics1bit music

Confetti 3 converts random patterns of blocks to more or less structured images. Every block will adapt to the predominant color in its surroundings, taking its upper, lower, left and right neighbour into account. Sound, corresponding to the location on the board, makes for some interesting melodies. This program can easily be converted to John Conway's Game of Life: http://sccode.org/1-4YV .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
s.boot;
(
var maxWidth=30, maxHeight = 30;
var z=20, ready = false;
var newValues=Array2D.new(maxWidth + 2, maxHeight + 2);
var oldValues=Array2D.new(maxWidth + 2, maxHeight + 2);
var go;


/*There is a decreasing linear connection between log(freq) and location in array: h+(maxWidth*v).
Highest location-value in array = maxWidth*maxHeight
log(freq)=log(maxfreq)-((log(maxfreq)-log(minfreq))*(h+(maxWidth*v))/(maxWidth*maxHeight), so
freq=exp(log(maxfreq)-((log(maxfreq)-log(minfreq))*(h+(maxWidth*v))/(maxWidth*maxHeight)
Furthermore freq depends on value, which is either 0 or 1. 
freq=freq+(freq*value) or freq=(1+value)*freq
Combining those 2:
freq=(exp(log(maxfreq)-((log(maxfreq)-log(minfreq))*(h+(maxWidth*v))/(maxWidth*maxHeight))*(1+value)

*/

SynthDef(\beeper, { arg h, v, p, maxWidth, maxHeight;
	var maxfreq=5000, minfreq=50;
	Out.ar(
		0, 
		Pan2.ar(
			Pulse.ar(exp(log(maxfreq)-((log(maxfreq)-log(minfreq))*(h+(maxWidth*v))/(maxWidth*maxHeight)))*(1+p), 0.5, 0.3), 
			2*h/maxWidth-1, //pan depends on column in array
			1
		)
	);
	
}).add;

w=Window("Confetti3", Rect(400, 300, z*(maxWidth+2), z*(maxHeight+2))).front;
w.view.background_(Color.white);
w.front;

w.drawFunc = {
		for (1, maxHeight, {arg v;
			for (1, maxWidth, {arg h;
				if (newValues[h,v]==1, 
					{Pen.fillColor=Color.white},
					{Pen.fillColor=Color.black}
				);
				Pen.addRect(Rect(h*z, v*z, z, z));
				Pen.fill;
			});
		});
};
												
//initialise
for (0, maxWidth+1,{arg h;
	for (0, maxHeight+1, {arg v;
		newValues[h,v]=0.5;
		oldValues[h,v]=0.5;
	})
});

go=Routine({
	//make random pattern
	for (1, maxWidth, {arg h;
		for (1, maxHeight, {arg v;
			newValues[h,v]=[0, 1].choose;
			{w.refresh}.defer;
			p=newValues[h,v];
			b=Synth("beeper",[p: p, h: h, v: v, maxWidth: maxWidth, maxHeight: maxHeight]);
			0.1.wait;
			b.free;
		})
	});
	while ({ready==false},{
		//copy newValues to oldValues (ignore the edges)
		for (1, maxWidth, {arg h;
			for (1, maxHeight, {arg v;
				oldValues[h,v]=newValues[h,v];
			})
		});
		//adapt
		for (1, maxWidth,{arg h;
			for (1, maxHeight, {arg v;
				if(
					oldValues[h, v-1]+oldValues[h+1, v]+oldValues[h-1, v]+oldValues[h, v+1] < 2, 					{newValues[h,v]=0}
				);
				if(
					oldValues[h, v-1]+oldValues[h+1, v]+oldValues[h-1, v]+oldValues[h, v+1] > 2, 
					{newValues[h,v]=1}
				);
				{w.refresh}.defer;
				if (newValues[h,v]!=oldValues[h,v],{
					p=newValues[h,v];
					b=Synth("beeper",[p: p, h: h, v: v, maxWidth: maxWidth, maxHeight: maxHeight]);
					0.1.wait;
					b.free;
				});
			})
		});
		//check if ready
		ready=true;
		for (1, maxWidth,{arg h;
			for (1, maxHeight, {arg v;
				if (oldValues[h,v]!=newValues[h,v], {ready=false});
			})
		});
	});
});


go.play;
)
raw 2844 chars (focus & ctrl+a+c to copy)
reception
comments