Make generation no longer a pure function master
authorJC <dev@jacobcasper.com>
Mon, 31 Jul 2023 16:10:05 +0000 (11:10 -0500)
committerJC <dev@jacobcasper.com>
Mon, 31 Jul 2023 16:10:05 +0000 (11:10 -0500)
GC pauses made the framerate on a real playdate incredibly choppy, so
store 2 generations of liveness inside each cell.

source/main.lua
source/pdxinfo

index 481a0eb..cdfc9bb 100644 (file)
@@ -36,14 +36,14 @@ function neighbors(g1, x, y)
     end
 
     -- edge cases
-    ne = { live = false }
-    n  = { live = false }
-    nw = { live = false }
-    e  = { live = false }
-    w  = { live = false }
-    se = { live = false }
-    s  = { live = false }
-    sw = { live = false }
+    ne = { live = false, live2 = false }
+    n  = { live = false, live2 = false }
+    nw = { live = false, live2 = false }
+    e  = { live = false, live2 = false }
+    w  = { live = false, live2 = false }
+    se = { live = false, live2 = false }
+    s  = { live = false, live2 = false }
+    sw = { live = false, live2 = false }
     if g1[x-1] then
         e = g1[x-1][y]
         if g1[y-1] then
@@ -69,41 +69,42 @@ function neighbors(g1, x, y)
     return ipairs({ne, n, nw, e, w, se, s, sw})
 end
 
-function generation(g1)
-    local g2 = {}
+function generation(g1, gen)
     for i,row in ipairs(g1) do
-        g2[i] = {}
         for j,cell in ipairs(row) do
             liveNeighbors = 0
             for r,neighbor in neighbors(g1, i, j) do
-                if neighbor.live then
+                if live(neighbor, gen) then
                     liveNeighbors = liveNeighbors + 1
                 end
             end
 
             -- All other live cells die in the next generation. Similarly, all other dead cells stay dead.
-            live = false
-            if cell.live then
+            l = false
+            if live(cell, gen) then
                 -- Any live cell with two or three live neighbours survives.
                 if liveNeighbors == 2 or liveNeighbors == 3 then
-                    live = true
+                    l = true
                 end
-            elseif not cell.live then
+            elseif not live(cell, gen) then
                 -- Any dead cell with three live neighbours becomes a live cell.
                 if liveNeighbors == 3 then
-                    live = true
+                    l = true
                 end
             end
-            g2[i][j] = { cell = cell.cell, live = live }
+            if gen % 2 == 0 then
+                cell.live2 = l
+            else
+                cell.live = l
+            end
         end
     end
-    return g2
 end
 
-function draw(cells)
+function draw(cells, generation)
     for i,row in ipairs(cells) do
         for j,r in ipairs(row) do
-            if r.live then
+            if live(r, generation) then
                 gfx.setColor(gfx.kColorBlack)
             else
                 gfx.setColor(gfx.kColorWhite)
@@ -117,17 +118,27 @@ function draw(cells)
     end
 end
 
+-- every other generation uses a different liveness value
+function live(cell, generation)
+    if generation % 2 == 0 then
+        return cell.live
+    else
+        return cell.live2
+    end
+end
+
 local cells = {}
 for i=1, WIDTH do
     cells[i] = {}
       for j=1, HEIGHT do
           r = pd.geometry.rect.new(CELL_SIZE * (i-1), CELL_SIZE * (j-1), CELL_SIZE, CELL_SIZE)
-          cells[i][j] = { cell = r, live = false }
+          cells[i][j] = { cell = r, live = false, live2 = false }
       end
 end
 
 local x = 1
 local y = 1
+local gen = 0
 
 local running = false
 
@@ -138,7 +149,7 @@ function playdate.update()
     if not running then
         -- automata state setup
         pd.display.setRefreshRate(30)
-        draw(cells)
+        draw(cells, gen)
 
         if playdate.buttonJustPressed("right") then
             x = math.min(WIDTH, x + 1)
@@ -149,13 +160,18 @@ function playdate.update()
         elseif playdate.buttonJustPressed("down") then
             y = math.min(HEIGHT, y + 1)
         elseif playdate.buttonJustPressed("a") then
-            cells[x][y].live = not cells[x][y].live
+            if gen % 2 == 0 then
+                cells[x][y].live = not cells[x][y].live
+            else
+                cells[x][y].live2 = not cells[x][y].live2
+            end
         end
     else
         -- running
         -- Make running less epileptic while letting interaction remain smooth
         pd.display.setRefreshRate(refreshRate)
-        draw(cells)
-        cells = generation(cells)
+        draw(cells, gen)
+        generation(cells, gen)
+        gen = gen + 1
     end
 end
index 2339b21..2ed1c88 100644 (file)
@@ -1,4 +1,4 @@
-name=Play Life
+name=Conplay's Game of Life
 author=Jacob Casper
 bundleID=com.jacobcasper.life
-version=0.1
+version=0.2