Thanks for all the comments. Cellular automata can also be used to simulate air flow (which can be used to simulate realistic explosions going around corners when in a confined space), heat transfer (conduction, convection, and radiation), and fire.
Just by removing the gravity and changing the code a bit, you have air/air pressure simulation:
sync on
sync rate 0
cls
`hide mouse
global grid_width
global grid_height
global cell_size as float
cell_size=8
grid_width = screen width()/cell_size
grid_height = screen height()/cell_size
type xy_type
x as float
y as float
endtype
type cell_type
flow as xy_type
oldflow as xy_type
mass as float
solid
endtype
dim cell(grid_width,grid_height) as cell_type
for x=1 to grid_width-2
for y=1 to grid_height-2
cell(x,y).solid=0
cell(x,y).mass=0.0
next y
next x
for x=0 to grid_width-1
cell(x,0).solid=1
cell(x,grid_height-1).solid=1
next x
for y=0 to grid_height-1
cell(0,y).solid=1
cell(grid_width-1,y).solid=1
next y
for x=18 to 48
for y=1 to grid_height-2
cell(x,y).solid=0
cell(x,y).mass=1.0
cell(x,y).flow.x=0
next y
next x
global lasttimer=timer()
lasttimer=timer()
running=0
global rendermode=1
do
cls
if spacekey()=1 and spkey=0
running=1-running
endif
spkey=spacekey()
t#=FrameTime()
`if running=1
process_cells(t#*running)
`process_cells(t#*running)
`process_cells(t#*running)
`endif
if mouseclick()=1 and mc=0
x=mousex()/cell_size
y=mousey()/cell_size
draw=1-cell(x,y).solid
endif
if mouseclick()=2
x=mousex()/cell_size
y=mousey()/cell_size
for nx=x-1 to x+1
if nx>=0 and nx<grid_width
for ny=y-1 to y+1
if ny>=0 and ny<grid_height
cell(nx,ny).mass=7
endif
next ny
endif
next nx
endif
mc=mouseclick()
if mouseclick()=1
x=mousex()/cell_size
y=mousey()/cell_size
for nx=x-1 to x+1
if nx>=0 and nx<grid_width
for ny=y-1 to y+1
if ny>=0 and ny<grid_height
cell(nx,ny).solid=draw
endif
next ny
endif
next nx
endif
sync
loop
function FrameTime()
t#=(timer()-lasttimer)*0.001
lasttimer=timer()
endfunction t#
function process_cells(time#)
for l=1 to 1
totalmass#=0
for x=0 to grid_width-1
for y=0 to grid_height-1
totalmass#=totalmass#+cell(x,y).mass
if cell(x,y).solid=0
if time#>0
if cell(x,y+1).solid=0
diff#=-(cell(x,y+1).mass-cell(x,y).mass)
` if (cell(x,y).mass>1 or cell(x,y+1).mass>1) and (cell(x,y+1).mass>cell(x,y).mass+0.01 or cell(x,y).mass>cell(x,y+1).mass+0.01)
cell(x,y).flow.y=curvevalue(diff#,cell(x,y).flow.y,128)
cell(x,y).flow.y=cell(x,y).flow.y+diff#*time#*5
` else
` cell(x,y).flow.y=curvevalue(diff#,cell(x,y).flow.y,160)
` endif
endif
if cell(x+1,y).solid=0
diff#=-(cell(x+1,y).mass-cell(x,y).mass)
` if (cell(x,y).mass>1 or cell(x+1,y).mass>1) and (cell(x+1,y).mass>cell(x,y).mass+0.01 or cell(x,y).mass>cell(x+1,y).mass+0.01)
cell(x,y).flow.x=curvevalue(diff#,cell(x,y).flow.x,128)
cell(x,y).flow.x=cell(x,y).flow.x+diff#*time#*5
` else
` cell(x,y).flow.x=curvevalue(diff#,cell(x,y).flow.x,160)
` endif
endif
endif
endif
next y
next x
for x=0 to grid_width-1
for y=0 to grid_height-1
cell(x,y).oldflow.x=cell(x,y).flow.x
cell(x,y).oldflow.y=cell(x,y).flow.y
next y
next x
for x=0 to grid_width-1
for y=0 to grid_height-1
if time#>0
if cell(x,y).mass-cell(x,y).oldflow.x<0
cell(x,y).oldflow.x=cell(x,y).mass
endif
if cell(x+1,y).mass+cell(x,y).oldflow.x<0
cell(x,y).oldflow.x=-cell(x+1,y).mass
endif
if cell(x,y).solid=1
if cell(x,y).oldflow.x<0 then cell(x,y).oldflow.x=0
endif
if cell(x+1,y).solid=1
if cell(x,y).oldflow.x>0 then cell(x,y).oldflow.x=0
endif
cell(x,y).mass=cell(x,y).mass-cell(x,y).oldflow.x
cell(x+1,y).mass=cell(x+1,y).mass+cell(x,y).oldflow.x
if cell(x,y).mass-cell(x,y).oldflow.y<0
cell(x,y).oldflow.y=cell(x,y).mass
endif
if cell(x,y+1).mass+cell(x,y).oldflow.y<0
cell(x,y).oldflow.y=-cell(x,y+1).mass
endif
if cell(x,y).solid=1
if cell(x,y).oldflow.y<0 then cell(x,y).oldflow.y=0
endif
if cell(x,y+1).solid=1
if cell(x,y).oldflow.y>0 then cell(x,y).oldflow.y=0
endif
cell(x,y).mass=cell(x,y).mass-(cell(x,y).oldflow.y)
cell(x,y+1).mass=cell(x,y+1).mass+(cell(x,y).oldflow.y)
if cell(x,y).solid=0
a#=1-cell(x-1,y).solid
b#=1-cell(x,y-1).solid
c#=1-cell(x+1,y).solid
d#=1-cell(x,y+1).solid
fx#=(cell(x-1,y).oldflow.x*a#+cell(x,y).oldflow.x*32+cell(x+1,y).oldflow.x*c#+cell(x,y-1).oldflow.x*b#+cell(x,y+1).oldflow.x*d#)/(32+a#+b#+c#+d#)
fy#=(cell(x,y-1).oldflow.y*b#+cell(x,y).oldflow.y*32+cell(x,y+1).oldflow.y*d#+cell(x-1,y).oldflow.y*a#+cell(x+1,y).oldflow.y*c#)/(32+a#+b#+c#+d#)
cell(x,y).flow.x=fx#
cell(x,y).flow.y=fy#
if cell(x,y+1).solid=0
` cell(x,y).flow.y=cell(x,y).flow.y+time#*0.1
endif
endif
cell(x,y).flow.x=cell(x,y).flow.x*0.999
cell(x,y).flow.y=cell(x,y).flow.y*0.999
cell(x,y).mass=cell(x,y).mass*0.995
endif
next y
next x
next l
if rendermode=1
for x=0 to grid_width-1
for y=0 to grid_height-1
if cell(x,y).solid=0
if cell(x,y).mass>0
m#=cell(x,y).mass
if m#>1 then m#=1
g#=cell(x,y).mass-1
if g#<0 then g#=0
if g#>1 then g#=1
r#=cell(x,y).mass-2
if r#<0 then r#=0
if r#>1 then r#=1
ink rgb((1-(m#)/1.0+r#)*255,(1-(m#)/1.0+g#-r#)*255,(1-g#)*255),0
else
ink -1,0
endif
else
ink 0,0
endif
box x*cell_size,y*cell_size,(x+1)*cell_size,(y+1)*cell_size
ink 0,0
` if abs(cell(x,y).flow.x)>0.1 or abs( cell(x,y).flow.y)>0.1
` line (x+0.5)*cell_size,(y+0.5)*cell_size,(x+0.5)*cell_size+cell(x,y).flow.x*60,(y+0.5)*cell_size+cell(x,y).flow.y*60
` endif
next y
next x
endif
if rendermode=2
for x=0 to grid_width-1
for y=0 to grid_height-1
if cell(x,y).solid=0
if cell(x,y).mass>0
vx#=cell(x,y).flow.x*60
vy#=cell(x,y).flow.y*60
if vx#>1 then vx#=1
if vx#<-1 then vx#=-1
if vy#>1 then vy#=1
if vy#<-1 then vy#=-1
ink rgb(255.0*(1-abs(vx#)),255.0*(1-abs(vy#)),255),0
else
ink -1,0
endif
else
ink 0,0
endif
box x*cell_size,y*cell_size,(x+1)*cell_size,(y+1)*cell_size
ink 0,0
` if abs(cell(x,y).flow.x)>0.1 or abs( cell(x,y).flow.y)>0.1
` line (x+0.5)*cell_size,(y+0.5)*cell_size,(x+0.5)*cell_size+cell(x,y).flow.x*60,(y+0.5)*cell_size+cell(x,y).flow.y*60
` endif
next y
next x
endif
endfunction
Changes between this snippet and the first snippet include:
-Removed gravity
-Removed water specific interaction
-Amplified the air sort of interaction (so waves last longer, but waves can also be tuned down or completely removed if wanted)
-Changed the right mouse click so that now increased the air pressure (waves propagate in all directions until they hit walls).
-Air eventually drains out of the system so the pressure can return to normal after a while.
An explosion going down a hallway:
A wall protecting the area behind it from the explosion, simulating realistic cover: