A new control structure.
A "safe" randomizer.
Now if only it weren't so damned slow!
The probability input is a little weird.
But this is the way I got tow rok. :)
519(1)03:16 AM:lsys 0> cat
sol.ps
%!
%Reference:
%
http://algorithmicbotany.org/papers/#abop Section 1.7
%
%"Safe" seed randomizer
{ 0 4{ 8 bitshift (/dev/random)(r)file read pop add }repeat srand } stopped
{ usertime 10 { %can't open file, chop some vegetables
save 128 string 99 2 getinterval 1 vmreclaim pop restore
} repeat usertime 8 bitshift add srand } if
/setrandcolor {
rand 100 mod 400 div %red to green
rand 100 mod 300 div .4 add % .4 .. .73 medium sat
rand 100 mod 300 div .2 add % .2 .. .53 dark to medium
sethsbcolor
} def
%Stochastic control structure "randif-block"
%eg. laboriously simulate a 4-sided die
% false .25 { 1 } randif % 25% chance
% .33 { 2 } randif % 25/75% = 33% chance remaining
% .5 { 3 } randif % 25/50% = 50% chance remaining
% 1 { 4 } randif % if all else fails, 100% chance
% pop % randif yields a bool indicating if anything executed
%
% bool prob proc randif bool
/randif {
3 2 roll { %ifelse a previous proc has already executed
pop pop true
}{
exch % proc prob
1 exch div cvi % invert prob to number of "chances"
rand exch mod % chop random int by chances
0 eq {
exec true
}{
pop false
} ifelse
} ifelse
} def
<< %start constructing a dictionary
/DDOLstep { [ exch {
dup type /arraytype eq {
DDOLstep
}{
currentdict exch
2 copy known {
get exec
}{
exch pop
} ifelse
} ifelse
} forall ]
%dup ==
} bind def
/DDOL { //DDOLstep repeat }
/Dexec {
{
dup type /arraytype eq {
Dexec
}{
exec
} ifelse
} forall
} bind
%transformations (Productions)
/F {
false .33 {{F[+ F]F[- F]F}} randif
.5 {{F[+ F]F}} randif
1 {{F[- F]F}} randif
pop %true one of these has executed
}
>>begin %define DOL and transformations
/graphics << % graphical interpretation of expanded proc
([){gsave %narrower, lighter branches
currentlinewidth .8 mul setlinewidth
currenthsbcolor .05 add dup .9 le {sethsbcolor}
{pop pop pop}ifelse
} bind
(]){%currentpoint r 0 180 arc stroke
grestore} bind
/X{}
/F{0 r rlineto currentpoint stroke moveto} bind
/G 1 index
/r .5
/a 25
/-{a rotate} bind
/+{a neg rotate} bind
>> def
{ %showpage loop
/Courier 10 selectfont 50 750 moveto rrand 12 string cvs show
rand 20 mod 20 add { %repeat 20 .. 40 "weeds"
matrix defaultmatrix setmatrix
{F} % seed-proc
rand 4 mod 5 add % 5 .. 8 iterations
DDOL % expanded-proc
graphics begin %define interpretation
%300 40 moveto %establish currentpoint
100 rand 400 mod add
100 rand 200 mod add moveto % (100,100) .. (500,300)
1 rand 10 mod 10 div add setlinewidth % 1 .. 2
setrandcolor
Dexec %execute the proc
end
}repeat
showpage
}
% select finite or infinite loop
%20 exch repeat
loop