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.*/ |
||
⚫ | |||
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 |
parse arg sd sw motes tree randSeed . /*obtain optional arguments from the CL*/ |
||
if |
if sd=='' | sd=="," then sd= 0 /*Not specified? Then use the default.*/ |
||
if |
if sw=='' | sw=="," then sw= 0 /* " " " " " " */ |
||
if |
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 |
if tree=='' | tree==mote then tree= "*" /*the character used to show the tree. */ |
||
if length(tree)==2 |
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 |
if sd==0 | sw==0 then _= scrsize() /*Note: not all REXXes have SCRSIZE BIF*/ |
||
if |
if sd==0 then sd= word(_, 1) - 2 /*adjust usable depth for the border.*/ |
||
if |
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= |
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, |
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= |
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.*/ |
|||
rx= random(1, sw); ry= random(1, sd); @.rx.ry= mote |
|||
end /*j*/ /* [↑] place a mote at random in field*/ |
|||
/*plant a seed from which the tree will grow from*/ |
|||
@.xs.ys= tree /*dust motes that affix themselves to the tree. */ |
|||
call show; loX= 1; hiX= sw /*show field before we mess it up again*/ |
|||
loY= 1; hiY= sd /*used to optimize the mote searching.*/ |
|||
⚫ | |||
/*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ soooo, this is Brownian motion.*/ |
/*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ soooo, this is Brownian motion.*/ |
||
do |
do Brownian=1 until \motion; call show /*show Brownion motion until no motion.*/ |
||
minx= loX; maxX= hiX; loX= sw; hiX= 1 /*as the tree grows, the search for the*/ |
|||
minY= loY; maxY= hiY; loY= sd; hiy= 1 /*dust motes gets faster due to croping*/ |
|||
call BM /*invoke the Brownian movement routine.*/ |
|||
loX |
if loX>1 & hiX<sw & loY>1 & hiY<sd then iterate /*Need cropping? No, then keep moving*/ |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
⚫ | |||
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 /* |
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 /* |
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 /* |
if @.x.ym ==tree then do; @.x.y= tree; iterate; end /* " " " " " */ |
||
if @.xm.ym==tree then do; @.x.y= tree; iterate; end /* |
if @.xm.ym==tree then do; @.x.y= tree; iterate; end /* " " " " " */ |
||
if @.xp.ym==tree then do; @.x.y= tree; iterate; end /* |
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 /* |
if @.x.yp ==tree then do; @.x.y= tree; iterate; end /* " " " " " */ |
||
if @.xm.yp==tree then do; @.x.y= tree; iterate; end /* |
if @.xm.yp==tree then do; @.x.y= tree; iterate; end /* " " " " " */ |
||
if @.xp.yp==tree then do; @.x.y= tree; iterate; end /* |
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( |
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( |
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.*/ |
|||
⚫ | |||
call show |
|||
⚫ | |||
⚫ | |||
crop: if loX>1 & hiX<width & loY>1 & hiY<height then return /*are we cropping?*/ |
|||
⚫ | |||
do yc=-1 to height+1 by height+2 |
|||
⚫ | |||
end /*xc*/ |
|||
⚫ | |||
/* [↓] delete motes (moved off field).*/ |
|||
do xc=-1 to width+1 by width+2 |
|||
⚫ | |||
end /*yc*/ |
|||
⚫ | |||
⚫ | |||
show: clearScr /*¬ necessary, but everything speeds up*/ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
say aRow |
|||
end /*ys*/; return</lang> |
|||
This REXX program makes use of '''scrsize''' REXX program (or BIF) which is used to determine the screen size of the terminal (console). |
This REXX program makes use of '''scrsize''' REXX program (or BIF) which is used to determine the screen size of the terminal (console). |
||