@Pixelator
There are two key principles to making a cellular program:
1. The cells in the world act like pixels, they can be switched on/off or given different properties but they do not move. Movement is simulated by transferring properties between cells.
2. In a true cellular program, each cell acts independently and only changes its state based on a set of rules; which usually assess the states of its immediate neighbours.
I'm going to teach you how to make "The Game of Life"; it is the most famous cellular program and will help you understand how cellular rules work.
Here are the rules that will be applied to each cell in our world.
Quote: "
Conway's Rule Set
For a cell that is 'populated':
Each cell with one or no neighbors dies, as if by loneliness.
Each cell with four or more neighbors dies, as if by overpopulation.
Each cell with two or three neighbors survives.
For a cell that is 'empty' or 'unpopulated'
Each cell with three neighbors becomes populated.
"
So our program needs to check the state of the current cell and the states of its immediate neighbours. Once we have analysed the cell and its neighbours we assign the new state to our current cell.
It is at this point that I must explain the importance of a "buffer" world; because we are checking each cell in turn and altering its state, if we only had one version of the world this would corrupt our data. Effectively by changing the state of a cell we are implying that time has passed but all cells are supposed to react at the same time.
To combat this we have two versions of our world: a static buffer world and a display world. The buffer world is analysed and the results are plotted to the display world, once we have completed our analysis the display world is copied to the buffer world and becomes the new buffer.
I'll continue this later, I'm going to write out the whole program first and then dissect it...
[edit]
Here is the program:
`--------------------------
` The Game of Life
` By OBese87
`--------------------------
sync on : sync rate 0
hide mouse
randomize timer()
`We create two versions of our world: a buffer and display world.
`The buffer world is analysed but the results are plotted to the display world.
`This prevents the analysis being corrupted.
MaxX=99 : MaxY=99
Dim world(1,MaxX,MaxY)
buffer=0 : display=1 :`labels
`spawn some cells
For cell = 0 to MaxX
world(buffer,cell,MaxY/2)=1
Next cell
`Colour ink white
ink rgb(255,255,255),0
`--------------------------
` Main Loop
`--------------------------
Do
`Analyse each cell independently
For y = 0 to MaxY
For x = 0 to MaxX
`Get the state of the current cell
CellState = world(buffer,x,y)
`Reset neighbour variable
LiveNeighbours = 0
`Make sure we don't leave the boundaries of our world.
cyMin = y>0 : cyMax = y<MaxY
cxMin = x>0 : cxMax = x<MaxX
`Get the states of the current cell's immediate neighbours
For cy = y-cyMin to y+cyMax
For cx = x-cxMin to x+cxMax
`Don't check the current cell as it isn't a neighbour to itself.
If cx<>x or cy<>y
inc LiveNeighbours,World(buffer,cx,cy)
Endif
Next cx
Next cy
`Apply Conway's rules
rem For a cell that is 'populated':
rem Each cell with two or three neighbors survives.
rem Each cell with one or no neighbors dies, as if by loneliness.
rem Each cell with four or more neighbors dies, as if by overpopulation.
rem
rem For a cell that is 'empty' or 'unpopulated'
rem Each cell with three neighbors becomes populated.
If CellState=1
Select LiveNeighbours
Case 2 : World(display,x,y)=1 : Endcase
Case 3 : World(display,x,y)=1 : Endcase
Case Default : World(display,x,y)=0 : Endcase
EndSelect
Endif
If CellState=0
Select LiveNeighbours
Case 3 : World(display,x,y)=1 : Endcase
Case Default : World(display,x,y)=0 : Endcase
EndSelect
Endif
Next x
Next y
`# Display
For y = 0 to MaxY
For x = 0 to MaxX
if World(display,x,y)=1 then dot x,y
`Copy display to buffer
World(buffer,x,y)=World(display,x,y)
Next x
Next y
Line MaxX+1,0,MaxX+1,MaxY+1
Line 0,MaxY+1,MaxX+1,MaxY+1
inc gen,1
text MaxX+20,MaxY,"Generations: "+str$(gen)
text MaxX+20,MaxY-16,"FPS: "+str$(screen fps() )
sync
if start=0 then wait key : start=1
cls
Loop
The hardest parts to get right are analysing the correct cells and applying the rules.
Have a look through the code and tell me how much of it makes sense to you
Here are some challenges for you:
1. Make a zooming function for the program so we can see the cells up close.
2. Make an editor for the program so the user can select which cells will be "live" at the start.
Once you've got the hang of this we can move on to rules that look at which specific neighbours are "live", then we can have things like gravity