(local state (require :lib.state)) (local cell (require :lib.cell)) (local cells (require :lib.cells)) (local fv (require :fennel.view)) (fn lerp* [a b c d x] (+ c (* (/ (- x a) (- b a)) (- d c)))) (fn vec-lerp* [a b c d x] {:x (lerp* a.x b.x c.x d.x x.x) :y (lerp* a.y b.y c.y d.y x.y)}) (fn new-grid [w h f] (var t {}) (for [x 0 (- w 1)] (tset t x {}) (for [y 0 (- h 1)] (tset (. t x) y (f x y)))) t) (fn update [self] (set self.ship.x (+ self.ship.x 0.02)) (set self.ship.y (+ self.ship.y 0.005)) (when (= self.tick 0) (for [x 0 (- self.width 1)] (for [y 0 (- self.height 1)] (fn get [v] (. self.grid (% (+ v.x x) self.width) (% (+ v.y y) self.height))) (if (. self.grid x y) ;; check if alive (tset self.grid-alt x y (cell.update (. self.grid x y) get)) ;; check for neighbors and then use one at random (do (var neighbors []) (for [x -1 1] (for [y -1 1] (table.insert neighbors (get {: x : y})))) (if (. neighbors 1) (tset self.grid-alt x y (cell.birth (. neighbors (math.random (length neighbors))) get)) (tset self.grid-alt x y nil)))))) (set (self.grid self.grid-alt) (values self.grid-alt self.grid))) ;; TODO (set self.tick (% (+ self.tick 1) self.rate))) (fn id [x] x) (fn draw [self] (local (width height) (love.graphics.getDimensions)) (love.graphics.scale width height) (local camera-size (math.max width height)) (let [camera-size (math.max width height) camera-box {:x width :y height} camera-box {:x 1 :y 1} radius-x (* self.radius (/ width camera-size)) radius-y (* self.radius (/ height camera-size)) camera-a {:x (- self.ship.x radius-x) :y (- self.ship.y radius-y)} camera-b {:x (+ self.ship.x radius-x) :y (+ self.ship.y radius-y)} cell-box (vec-lerp* {:x 0 :y 0} {:x (* 2 radius-x) :y (* 2 radius-y)} {:x 0 :y 0} camera-box {:x 1 :y 1})] (for [x (math.floor camera-a.x) (math.floor camera-b.x)] (for [y (math.floor camera-a.y) (math.floor camera-b.y)] (let [vec {:x (% x self.width) :y (% y self.height)} render-a (vec-lerp* camera-a camera-b {:x 0 :y 0} camera-box {: x : y}) render-b (vec-lerp* camera-a camera-b {:x 0 :y 0} camera-box {:x (+ x 1) :y (+ y 1)}) the (. self.grid vec.x vec.y) color (and the (cell.color the))] (when color (love.graphics.setColor (unpack color)) (love.graphics.rectangle :fill (id render-a.x) (id render-a.y) (id cell-box.x) (id cell-box.y)))))))) ;; (love.graphics.setLineWidth 0.1) ;; (love.graphics.line 0 0 0.3 0.3) ;; (love.graphics.polygon :line 0.3 0.3 0.6 0.3 0.4 0.6) ;; (love.graphics.line 0.4 0.8 0.4 0.8) ;; (love.graphics.print :Gaming)) (fn init [self] (setmetatable {:width 64 :height 64 :ship {:x 31 :y 31} :radius 32 :tick 0 :rate 6 :grid (new-grid 64 64 #(if (= (math.random 6) 1) (if (< $1 52) (cell.init cells.life) (cell.init cells.brain)) nil)) :grid-alt (new-grid 64 64 #nil) } self)) {state.draw draw state.init init state.update update}