remstart
~~~~~~~~~~~~~~~~~~~~~~~~~
   Sand Simulation
~~~~~~~~~~~~~~~~~~~~~~~~~
There are 4 different cell types:
* Empty Cells
* Tap Cells
   Taps produce sand cells in the square below (if empty)
* Sand Cells
   Sand falls to the square below, if it comes into contact with a foreign
   cell type it will remain there, if it collides with another sand cell it will try to
   move off diagonally down to one side (right has priority), if neither side is open it will stay where it is
* Wall Cells
   Wall cells stop sand from spilling out
~~~~~~~~~~~~~~~~~~~~~~~~~
remend
 
`Setup
sync on
 
`Define Active Screen Position
sx=100 : sy=100
 
`Make Cell Array
DIM cell(1,49,49)
active=0
empty=0 : sand=1 : solid=2 : tap=3
 
`colours
DIM colour(3)
colour(0)=rgb(40,40,40)
colour(1)=rgb(255,255,100)
colour(2)=rgb(128,0,128)
colour(3)=rgb(255,0,0)
 
`square scale
scale=5
 
`~~~~~~~~~~~~~~~~~~~~
` EDITOR
`~~~~~~~~~~~~~~~~~~~~
`blank
ink colour(empty),0
box sx,sy,sx+(49*scale),sy+(49*scale)
 
`make solid frame
ink colour(solid),0
for a = 0 to 1
   for s = 0 to 49
      cell(a,s,49)=solid
      cell(a,0,s)=solid
      cell(a,49,s)=solid
      box sx+(s*scale),sy+(49*scale),sx+(s*scale)+scale,sy+(49*scale)+scale
      box sx+(0*scale),sy+(s*scale),sx+(0*scale)+scale,sy+(s*scale)+scale
      box sx+(49*scale),sy+(s*scale),sx+(49*scale)+scale,sy+(s*scale)+scale
   next s
next a
 
DO
   mx=(mousex()-sx)/scale : my=(mousey()-sy)/scale : mc=mouseclick()
 
   if mc>0 and mc<3
      if mx>=0 and mx<50
         if my>=0 and my<50
            cell(0,mx,my)=mc+1
            if mc=1 then cell(1,mx,my)=mc+1
            `draw cell
            ink colour( cell(0,mx,my) ),0
            box sx+(mx*scale),sy+(my*scale),sx+(mx*scale)+scale,sy+(my*scale)+scale
         endif
      endif
   endif
 
   if returnkey()=1 then exit
 
   text 0,0,"Left Click to place solid cells, Right click to place a sand tap."
   text 0,20,"PRESS RETURN TO BEGIN SIMULATION"
 
   sync
LOOP
 
`~~~~~~~~~~~~~~~~~~~~
` Main Loop
`~~~~~~~~~~~~~~~~~~~~
hide mouse
do
   for y = 0 to 49
      for x = 0 to 49
         `Tap
         if cell(active,x,y)=tap
            if y<49
               if cell(active,x,y+1)=empty then cell(active,x,y+1)=sand
            endif
         endif
 
         `Sand
         if cell(active,x,y)=sand
            if y<49
               `drop sand
               if cell(active,x,y+1)=empty
                  cell(1-active,x,y)=empty : cell(1-active,x,y+1)=sand
               else
                  if x<49
                     if cell(active,x+1,y+1)=empty
                        cell(1-active,x,y)=empty : cell(1-active,x+1,y+1)=sand
                     else
                        if x>0
                           if cell(active,x-1,y+1)=empty
                              cell(1-active,x,y)=empty : cell(1-active,x-1,y+1)=sand
                           else
                              cell(1-active,x,y)=sand
                           endif
                       endif
                     endif
                  endif
               endif
            endif
         endif
 
         `*DISPLAY
         ink colour( cell(active,x,y) ),0
         box sx+(x*scale),sy+(y*scale),sx+(x*scale)+scale,sy+(y*scale)+scale
      next x
   next y
 
   active=1-active
 
   sync
loop