Brownian tree: Difference between revisions

Content added Content deleted
m (→‎{{header|REXX}}: elided a statement.)
m (→‎{{header|REXX}}: tided up some code.)
Line 3,703: Line 3,703:
mote = '·' /*character for a loose mote (of dust).*/
mote = '·' /*character for a loose mote (of dust).*/
hole = ' ' /* " " an empty spot in field.*/
hole = ' ' /* " " an empty spot in field.*/
clearScr = 'CLS' /*(DOS) command to clear the screen. */
seedPos = 0 /*if =0, then use middle of the field.*/
seedPos = 0 /*if =0, then use middle of the field.*/
/* " -1, " " a random placement.*/
/* " -1, " " a random placement.*/
/*otherwise, place the seed at seedPos.*/
/*otherwise, place the seed at seedPos.*/
/*use RANDSEED for RANDOM repeatability*/
/*use RANDSEED for RANDOM repeatability*/
parse arg height width motes tree randSeed . /*obtain optional arguments from the CL*/
parse arg sd sw motes tree randSeed . /*obtain optional arguments from the CL*/
if height=='' | height=="," then height= 0 /*Not specified? Then use the default.*/
if sd=='' | sd=="," then sd= 0 /*Not specified? Then use the default.*/
if width=='' | width=="," then width= 0 /* " " " " " " */
if sw=='' | sw=="," then sw= 0 /* " " " " " " */
if motes=='' | motes=="," then motes= '21%' /*The % dust motes in the field, */
if motes=='' | motes=="," then motes= '18%' /*The % dust motes in the field, */
/* [↑] either a # ─or─ a # with a %.*/
/* [↑] either a # ─or─ a # with a %.*/
if tree=='' | tree==mote then tree= "*" /*the character used to show the tree. */
if tree=='' | tree==mote then tree= "*" /*the character used to show the tree. */
if length(tree)==2 then tree=x2c(tree) /*tree character was specified in hex. */
if length(tree)==2 then tree=x2c(tree) /*tree character was specified in hex. */
if datatype(randSeed,'W') then call random ,,randSeed /*if an integer, use the seed.*/
if datatype(randSeed,'W') then call random ,,randSeed /*if an integer, use the seed.*/
/* [↑] set the first random number. */
/* [↑] set the first random number. */
if height==0 | width==0 then _= scrsize() /*Note: not all REXXes have SCRSIZE BIF*/
if sd==0 | sw==0 then _= scrsize() /*Note: not all REXXes have SCRSIZE BIF*/
if height==0 then height= word(_,1)-3 /*adjust usable height for the border. */
if sd==0 then sd= word(_, 1) - 2 /*adjust usable depth for the border.*/
if width==0 then width= word(_,2)-1 /* " " width " " " */
if sw==0 then sw= word(_, 2) - 1 /* " " width " " " */
seedAt= seedPos /*assume a seed position (initial pos).*/
seedAt= seedPos /*assume a seed position (initial pos).*/
if seedPos== 0 then seedAt= width%2 height%2 /*if it's a zero, start in the middle.*/
if seedPos== 0 then seedAt= (sw % 2) (sd % 2) /*if it's a zero, start in the middle.*/
if seedPos==-1 then seedAt= random(1, width) random(1,height) /*if negative, use random*/
if seedPos==-1 then seedAt= random(1, sw) random(1,sd) /*if negative, use random.*/
parse var seedAt xs ys . /*obtain the X and Y seed coördinates*/
parse var seedAt xs ys . /*obtain the X and Y seed coördinates*/
/* [↓] if right─most ≡ '%', then use %*/
/* [↓] if right─most ≡ '%', then use %*/
if right(motes, 1)=='%' then motes= height * width * strip(motes, , '%') % 100
if right(motes, 1)=='%' then motes= sd * sw * strip(motes, , '%') % 100
@.= hole /*create the Brownian field, all empty.*/
@.= hole /*create the Brownian field, all empty.*/
do j=1 for motes /*sprinkle a # of dust motes randomly.*/
do j=1 for motes /*sprinkle a # of dust motes randomly.*/
rx= random(1, width); ry= random(1, height); @.rx.ry= mote
rx= random(1, sw); ry= random(1, sd); @.rx.ry= mote
end /*j*/ /* [↑] place a mote at random in field*/
end /*j*/ /* [↑] place a mote at random in field*/
/*plant the seed from which the tree */
/*plant a seed from which the tree will grow from*/
/* will grow from dust motes that */
@.xs.ys= tree /*dust motes that affix themselves to the tree. */
@.xs.ys= tree /* affixed themselves to others. */
call show; loX= 1; hiX= sw /*show field before we mess it up again*/
call show; loX= 1; hiX= width /*show field before we mess it up again*/
loY= 1; hiY= sd /*used to optimize the mote searching.*/
loY= 1; hiY= height /*used to optimize the mote searching.*/
/*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ soooo, this is Brownian motion.*/
/*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ soooo, this is Brownian motion.*/
do winks=1 until \motion /*show Brownion motion until no motion.*/
do Brownian=1 until \motion; call show /*show Brownion motion until no motion.*/
motion= 0; call show /*turn off Brownian motion flag; show.*/
minx= loX; maxX= hiX; loX= sw; hiX= 1 /*as the tree grows, the search for the*/
minX= loX; maxX= hiX /*as the tree grows, the search for */
minY= loY; maxY= hiY; loY= sd; hiy= 1 /*dust motes gets faster due to croping*/
minY= loY; maxY= hiY /* dust motes gets faster. */
call BM /*invoke the Brownian movement routine.*/
loX= width; hiX= 1; loY= height; hiy= 1 /*used to limit the mote searching. */
if loX>1 & hiX<sw & loY>1 & hiY<sd then iterate /*Need cropping? No, then keep moving*/
call crop /*delete motes (moved off petri field).*/

end /*Brownian*/ /*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒*/
do x =minX to maxX; xm= x - 1; xp= x + 1 /*two handy─dandy values. */
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
crop: do yc=-1 to sd+1 by sd+2; do xc=-1 to sw+1; @.xc.yc= hole; end /*xc*/
end /*yc*/
do xc=-1 to sw+1 by sw+2; do yc=-1 to sd+1; @.xc.yc= hole; end /*yc*/
end /*xc*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: 'CLS'; motion= 0; do ys=sd for sd by -1; aRow=
do xs=1 for sw; aRow= aRow || @.xs.ys
end /*xs*/
say aRow
end /*ys*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
BM: do x =minX to maxX; xm= x - 1; xp= x + 1 /*two handy─dandy values. */
do y=minY to maxY; if @.x.y\==mote then iterate /*Not a mote: keep looking.*/
do y=minY to maxY; if @.x.y\==mote then iterate /*Not a mote: keep looking.*/
if x<loX then loX=x; if x>hiX then hiX=x /*faster than hiX=max(X,hiX)*/
if x<loX then loX=x; if x>hiX then hiX=x /*faster than hiX=max(X,hiX)*/
if y<loY then loY=y; if y>hiY then hiY=y /*faster than hiY=max(y,hiY)*/
if y<loY then loY=y; if y>hiY then hiY=y /* " " hiY=max(y,hiY)*/
if @.xm.y ==tree then do; @.x.y= tree; iterate; end /*there a neighbor of tree? */
if @.xm.y ==tree then do; @.x.y= tree; iterate; end /*there a neighbor of tree? */
if @.xp.y ==tree then do; @.x.y= tree; iterate; end /*there a neighbor of tree? */
if @.xp.y ==tree then do; @.x.y= tree; iterate; end /* " " " " " */
ym= y - 1
ym= y - 1
if @.x.ym ==tree then do; @.x.y= tree; iterate; end /*there a neighbor of tree? */
if @.x.ym ==tree then do; @.x.y= tree; iterate; end /* " " " " " */
if @.xm.ym==tree then do; @.x.y= tree; iterate; end /*there a neighbor of tree? */
if @.xm.ym==tree then do; @.x.y= tree; iterate; end /* " " " " " */
if @.xp.ym==tree then do; @.x.y= tree; iterate; end /*there a neighbor of tree? */
if @.xp.ym==tree then do; @.x.y= tree; iterate; end /* " " " " " */
yp = y + 1
yp = y + 1
if @.x.yp ==tree then do; @.x.y= tree; iterate; end /*there a neighbor of tree? */
if @.x.yp ==tree then do; @.x.y= tree; iterate; end /* " " " " " */
if @.xm.yp==tree then do; @.x.y= tree; iterate; end /*there a neighbor of tree? */
if @.xm.yp==tree then do; @.x.y= tree; iterate; end /* " " " " " */
if @.xp.yp==tree then do; @.x.y= tree; iterate; end /*there a neighbor of tree? */
if @.xp.yp==tree then do; @.x.y= tree; iterate; end /* " " " " " */
motion= 1 /* [↓] Brownian motion is coming. */
motion= 1 /* [↓] Brownian motion is coming. */
xb= x + random(1, 3) - 2 /* apply Brownian motion for X. */
xb= x + random(1, 3) - 2 /* apply Brownian motion for X. */
Line 3,762: Line 3,774:
@.x.y= hole /*"empty out" the old mote position. */
@.x.y= hole /*"empty out" the old mote position. */
@.xb.yb= mote /*move the mote (or possibly not). */
@.xb.yb= mote /*move the mote (or possibly not). */
if xb<loX then loX= max(1, xb); if xb>hiX then hiX= min( width, xb)
if xb<loX then loX= max(1, xb); if xb>hiX then hiX= min(sw, xb)
if yb<loY then loY= max(1, yb); if yb>hiY then hiY= min(height, yb)
if yb<loY then loY= max(1, yb); if yb>hiY then hiY= min(sd, yb)
end /*y*/ /* [↑] limit mote's movement to field.*/
end /*y*/ /* [↑] limit mote's movement to field.*/
end /*x*/
end /*x*/; return</lang>

call crop /*crops (or truncates) the mote field.*/
end /*winks*/ /*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒*/

call show
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
crop: if loX>1 & hiX<width & loY>1 & hiY<height then return /*are we cropping?*/
/* [↓] delete motes (moved off field).*/
do yc=-1 to height+1 by height+2
do xc=-1 to width+1; if @.xc.yc==hole then iterate; @.xc.yc= hole
end /*xc*/
end /*yc*/
/* [↓] delete motes (moved off field).*/
do xc=-1 to width+1 by width+2
do yc=-1 to height+1; if @.xc.yc==hole then iterate; @.xc.yc= hole
end /*yc*/
end /*xc*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: clearScr /*¬ necessary, but everything speeds up*/
do ys=height for height by -1; aRow=
do xs=1 for width; aRow= aRow || @.xs.ys
end /*xs*/
say aRow
end /*ys*/; return</lang>
This REXX program makes use of &nbsp; '''scrsize''' &nbsp; REXX program (or BIF) which is used to determine the screen size of the terminal (console).
This REXX program makes use of &nbsp; '''scrsize''' &nbsp; REXX program (or BIF) which is used to determine the screen size of the terminal (console).