It looks like you're new here. If you want to get involved, click one of these buttons!

Hey everyone Here is my latest project, Conway's Game of Life!

For those who don't know how it works, it is a simulation where each cell is either alive or dead. There are a few rules to it though...

1. If a cell has 2 or less alive cells around it, it dies

2. If a cell has 4 or more alive cells around it, it dies

3. If a cell has 3 cells around it and is dead, it becomes alive

Here is my code:

```
-- Game Of Life
-- Use this function to perform your initial setup
function setup()
gSize = 32
displayMode(FULLSCREEN)
grid = { width = WIDTH / gSize, height = HEIGHT / gSize - 2 }
for x = 1, grid.width do
grid[x] = {}
for y = 1, grid.height do
grid[x][y] = 0
end
end
paused = 0
backingMode(RETAINED)
background(255, 255, 255, 255)
t = 0
c = 1
speed = .25
end
-- This function gets called once every frame
function draw()
local g = { width = WIDTH / gSize, height = HEIGHT / gSize - 2 }
t = t + DeltaTime
if t > c then
c = c + speed
background(255 - 128 * paused)
for x = 1, grid.width do
g[x] = {}
local r = grid[x]
for y = 1, grid.height do
local n = numSurrounding(x, y, grid)
local l = r[y]
g[x][y] = l
fill(0, 255 * l, 0)
--text(n, (x - .5) * gSize + 1, (y - .5) * gSize + 1)
rect((x - 1) * gSize + 1, (y - 1) * gSize + 1, gSize - 2, gSize - 2)
if paused == 0 then
if n < 2 then
g[x][y] = 0
elseif n == 2 then
g[x][y] = grid[x][y]
elseif n == 3 then
g[x][y] = 1
elseif n > 3 then
g[x][y] = 0
end
end
end
end
grid = g
end
end
function touched(touch)
if touch.state == ENDED then
if touch.y < HEIGHT - gSize * 2 then
grid[math.ceil(touch.x / gSize)][math.ceil(touch.y / gSize)] = 1 - grid[math.ceil(touch.x / gSize)][math.ceil(touch.y / 32)]
else
paused = 1-paused
end
end
end
function numSurrounding(x, y, g)
local n = 0
for i = x - 1, x + 1 do
for j = y - 1, y + 1 do
if not (i < 1 or j < 1 or i > grid.width or j > grid.height or (i == x and j == y)) then
n = n + g[i][j]
end
end
end
return n
end
```

And here's a video of it in action:

DEBUG MODE: To enable this, there is a commented line in draw, Uncomment it, and comment the rect call below it

Tagged:

## Comments

This was fun, thanks! And in such a short code listing too.

Your code is correct but your explanation has a minor error:

Not so. If it is alive and has two alive neighbours then it stays alive.

Oh, whoops It should be one or zero, thanks Andrew

Very nice job,@Jordan

Yes, I forgot to say that I also like the simplicity of the code.

Now, I have a suggestion for you @Jordan. I don't know how much you've been following what's happening with the latest beta, so you may already know this. Using beta features (shaders) I recently did a Game-of-Life program. Using shaders means using the GPU which is ridiculously fast at doing the multiple parallel calculations needed for GoL. But the GPU is a waste of time if the events happen linearly. Then, one should use the flexibility of the CPU.

One thing that the "standard" GoL lacks is the ability to see what's happening. Because the whole field changes every time it can be difficult to look at one patch and see why something happens. After showing my version to my kids then we had to resort to pieces of paper to understand

whywe saw what we saw. It would have been great to have a system where we could enter in (as in your case) an initial state and then watch it progress almost tile-by-tile.So my suggestion is that you develop your code to do this: a system where one can specify an initial state and set it going to see what happens (this is what you have) and, just as importantly,

whyit happens. It would have to be possible to see actual decisions and some visual indication of why a particular decision goes the way it does (and it should skip - as in not show the details - "boring" decisions).Anyway, there's a suggestion for you - which you are, of course, free to ignore!

Thanks Andrew, what do you think about a animation controlled by you with a button which simply goes to the next generation, with a few steps in between?

That'd be a good start - particularly if you could run it backward!, but I'd also like something where you could somehow

seeit doing the computation.Here is a version of The Game of Life to the extreme. If this is too slow for you, change the value of size to 4, 8, or 16 in setup(). At a size of 2, the initial screen takes about 5 seconds to show, with about 5 seconds between generations. I don't know how long it will take to reach a stable generation. At least not yet. Each initial run is a random mix with about half set. I did everything I could think of to max out the speed.

I found that the DeltaTime on your code got less as it went on. It seemed to stabilise at around 3.3s per frame. The code below outperforms that by a factor of about 2.

For reference, the GLSL shader version (with the same density, but also rendering to a torus) outperforms your code by a factor of 100 - but then that's due to using the GPU instead of the CPU. Having optimised your code a little, I'm now wondering if it is possible to optimise that code a bit more in a similar vein.

Not sure if this is actually faster, but it shortens one loop.

Thanks @Andrew_Stacey. Your first example is just over 2 times faster and the second about 1.5 times faster. The bad thing is, apparently I don't know Lua well enough to know how to get the most speed out of it. The good thing is, I have something new to figure out. I guess I'll have to lookup Lua optimization and see what they say. And, I'll have to look through your code to see what you did to speed it up that much.

The real curiosity is why the second is slower than the first.

The secret to the initial speed-up is that I didn't optimise the lua code, I optimised the mathematics. So although there are a few lua optimisations (such as using local very aggressively), the biggest gain comes from thinking of GoL slighly differently.