(local cell (require :lib.cell)) (local music-state (require :lib.music-state)) (local neighbors [{:x -1 :y -1} {:x -1 :y 0} {:x -1 :y 1} {:x 0 :y -1} {:x 0 :y 1} {:x 1 :y -1} {:x 1 :y 0} {:x 1 :y 1}]) (fn neighbors> [f threshold] (var x 0) ;; nnn this could be faster maybe (for [k 1 8] (when (> (cell.aliveness (f (. neighbors k))) threshold) (set x (+ x 1)))) x) (fn neighbors< [f threshold] (var x 0) ;; nnn this could be faster maybe (for [k 1 8] (when (< (cell.aliveness (f (. neighbors k))) threshold) (set x (+ x 1)))) x) (local life {cell.init (fn [self] (setmetatable {} self)) cell.birth (fn [self get] (if (= (neighbors> get 0.5) 3) self nil)) cell.update (fn [self get] (let [n (neighbors> get 0.5)] (if (or (= n 3) (= n 2)) self nil))) cell.aliveness #1 cell.color #[0.4 0.4 0.7] }) (local brain {cell.init (fn [self] (setmetatable {:stage 0} self)) cell.birth (fn [self get] (if (= (neighbors> get 0.8) 2) (do (setmetatable {:stage 0} (getmetatable self))) nil)) cell.update (fn [self get] (if (= self.stage 0) (setmetatable {:stage 1} (getmetatable self)) nil)) cell.aliveness #(- 1 (* 0.5 $.stage)) cell.color #(if (= $.stage 0) [0.7 0.4 0.3] (= $.stage 1) [0.2 0.2 0.3]) }) (local boom {cell.init (fn [self x] (setmetatable {:life (or x 1)} self)) cell.birth (fn [self get] (if (and (> self.life 0.08) (> (neighbors< get (* (if (> self.life 0.9) -0.3 -0.1) (math.random 7))) 0)) (do (setmetatable {:life (* self.life 0.8)} (getmetatable self))) nil)) cell.update (fn [self get] (set music-state.fire (math.max music-state.fire self.life)) (if (> self.life 0.3) (setmetatable {:life (* self.life (+ 0.5 (* (math.random 5) 0.1)))} (getmetatable self)) nil)) cell.aliveness #(- $.life) cell.color #[(+ 0.4 (* 0.6 $.life)) (math.max 0 (- 0.8 (* 0.9 (- 1 $.life)))) (+ 0.1 )]}) {: life : brain : boom}