It seems to be working okay except I get vertical pairs of dots popping in and out of existence. I can't figure out what is causing this.
remstart
== Conway's Game of Life ==
== By Oli Burt ==
Rules:
Any live cell with fewer than two live neighbours dies, as if caused by under-population.
Any live cell with two or three live neighbours lives on to the next generation.
Any live cell with more than three live neighbours dies, as if by overcrowding.
Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
/Rules
I will store the entire ruleset in a single binary number, using it as a sort of stack. I will use
bitwise manipulation, using the number of neighbouring cells as a parameter, to push the ruleset value
along to the appropriate bit for that number of neighbours, then applying &&1 will give the correct output.
The rules are slightly different for live and dead cells, so I will have to examine this.
If I cannot resolve the difference I will use two ruleset values, one for live and one for dead.
Live Cell Neighbours:
876543210
000001100
Dead Cell Neighbours:
876543210
000001000
I can't figure out how to resolve the difference so I'll use two values.
It has occured to me that copying the entire world at once is uneconomic. By making a third world array
I could update one buffer while using the other to update the world.
remend
set display mode 1024,768,32
global surviverule =12
global birthrule =8
rem create world
global xmax = 799
global ymax = 699
dim grid(xmax,ymax)
dim gbuff(xmax,ymax) :`gbuff stores a copy of the world for reference when updating, so that grid can be changed without effecting the results.
populate()
rem colours
dim colour(1)
colour(0) = 120
colour(1) = rgb(255,255,255)
delay = 0
time = timer()
set text font "verdana",1
set text size 14
rem == Main ==
do
gosub inputs
cls
gosub display_text
display_world()
rem Update world after delay
if time+delay < timer()
time=timer()
inc gen
copy_world()
update_world()
endif
loop
end
rem == Subroutines ==
display_text:
ink colour(1),0
text xmax+10,0,"Generations: "+str$(gen)
text xmax+10,20,"Delay: " + str$(delay)+"ms"
text xmax+10,40,"SHIFT/CTRL adjusts delay"
text xmax+10,81,"Survival Ruleset: "+str$(surviverule)
text xmax+10,100,"BIN: "+right$(bin$(surviverule),9)
text xmax+10,120,"L/R to change"
text xmax+10,160,"Birth Ruleset: "+str$(birthrule)
text xmax+10,182,"BIN: "+right$(bin$(birthrule),9)
text xmax+10,200,"UP/DOWN to change"
text xmax+10,240,"Press ENTER to re-populate"
return
`//
inputs:
delay = delay + (shiftkey() - controlkey())*10
if delay <0 then delay=0
surviverule = surviverule + rightkey() - leftkey()
if surviverule <1 then surviverule = 1
if surviverule >511 then surviverule = 511
birthrule = birthrule + upkey() - downkey()
if birthrule <1 then birthrule = 1
if birthrule >511 then birthrule = 511
if returnkey() = 1 then populate() : gen=0
return
rem == Functions ==
function populate()
for y = 0 to ymax
for x = 0 to xmax
grid(x,y) = rnd(1)
next x
next y
endfunction
`//
function copy_world()
for y = 0 to ymax
for x = 0 to xmax
gbuff(x,y) = grid(x,y)
next x
next y
endfunction
`//
function update_world()
for y = 0 to ymax
for x = 0 to xmax
rem prepare check-boundaries for cell x,y
rem (these assignments use logic to make sure they stay in bounds)
vmin = 0-(y>0)
vmax = y < ymax
umin = 0-(x>0)
umax = x < xmax
rem check for neighbours of x,y
nbrs = 0
for v = vmin to vmax
for u = umin to umax
if u<>0 or v<>0 then nbrs = nbrs + gbuff(x+u,y+v) :`check we don't include x,y as its own neighbour.
next u
next v
rem update cell x,y
if gbuff(x,y) = 0
grid(x,y) = (birthrule >> nbrs) && 1
else
grid(x,y) = (surviverule >> nbrs) && 1
endif
next x
next y
endfunction
`//
function display_world()
lock pixels
for y = 0 to ymax
for x = 0 to xmax
ink colour(grid(x,y)),0
dot x,y
next x
next y
unlock pixels
endfunction
`//