This repository has been archived by the owner on Nov 23, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
faster.cljs
78 lines (72 loc) · 2.15 KB
/
faster.cljs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
(ns ex01.faster
(:require-macros
[thi.ng.math.macros :as mm])
(:require
[ex01.state :as state]
[ex01.utils :as utils]
[thi.ng.typedarrays.core :as ta]
[reagent.core :as r]))
(defn sum-neighbors
"Returns number of active neighbours for a cell at x;y using
thi.ng.math macro to compute sum."
[grid idx stride]
(let [t (- idx stride)
b (+ idx stride)]
(mm/add
(nth grid (- t 1))
(nth grid t)
(nth grid (+ t 1))
(nth grid (- idx 1))
(nth grid (+ idx 1))
(nth grid (- b 1))
(nth grid b)
(nth grid (+ b 1)))))
(defn life-step
"Computes new state for a single cell."
[grid idx stride]
(let [neighbors (sum-neighbors grid idx stride)]
(if (pos? (nth grid idx))
(if (or (== neighbors 2) (== neighbors 3)) 1 0)
(if (== 3 neighbors) 1 0))))
(defn life
"Computes next generation of entire cell grid."
[w h grid]
(let [w' (- w 1)
h' (- h 2)]
(loop [grid' grid, idx (+ w 1), x 1, y 1]
(if (< x w')
(recur (assoc grid' idx (life-step grid idx w)) (inc idx) (inc x) y)
(if (< y h')
(recur grid' (+ idx 2) 1 (inc y))
grid')))))
(defn draw
"Visualizes grid state in given canvas context."
[ctx w h grid]
(let [w' (- w 1)
h' (- h 2)]
(set! (.-fillStyle ctx) "#000")
(.fillRect ctx 0 0 w h)
(set! (.-fillStyle ctx) "#0ff")
(loop [i 0, x 1, y 1]
(if (< x w')
(do (when (pos? (nth grid i))
(.fillRect ctx x y 1 1))
(recur (inc i) (inc x) y))
(if (< y h')
(recur (+ i 2) 1 (inc y))
grid)))))
(defn init
[this props]
(swap! state/app merge
{:grid (->> #(if (< (rand) 0.25) 1 0)
(repeatedly (* (:width props) (:height props)))
vec)}))
(defn redraw
[this props]
(let [{:keys [width height]} props
ctx (.getContext (r/dom-node this) "2d")]
(let [[avg grid] (utils/run-with-timer
#(->> (:grid @state/app)
(life width height)
(draw ctx width height)))]
(swap! state/app assoc :grid grid :avg avg))))