;; vector of arrays version | |
(import '(javax.swing JFrame JPanel) | |
'(java.awt Color Graphics2D)) | |
(defn neighbours-count [[above current below] i w] | |
(let [j (mod (inc i) w) | |
k (mod (dec i) w) | |
s #(if (= (aget #^objects %1 (int %2)) :on) 1 0)] | |
(+ (+ (+ (s above j) (s above i)) | |
(+ (s above k) (s current j))) | |
(+ (+ (s current k) (s below j)) | |
(+ (s below i) (s below k)))))) | |
(defn step1 [rows] | |
(let [#^objects current (second rows) | |
w (count current)] | |
(loop [i (int (dec w)), #^objects row (aclone current)] | |
(if (neg? i) | |
row | |
(let [c (aget current i)] | |
(cond | |
(= c :on) | |
(recur (dec i) (doto row (aset i :dying))) | |
(= c :dying) | |
(recur (dec i) (doto row (aset i :off))) | |
(= 2 (neighbours-count rows i w)) | |
(recur (dec i) (doto row (aset i :on))) | |
:else | |
(recur (dec i) row))))))) | |
;; non parallel step | |
(defn step [board] | |
(vec (map step1 | |
(partition 3 1 (concat [(peek board)] board [(first board)]))))) | |
(defn step [board] | |
(let [n (.availableProcessors (Runtime/getRuntime)) | |
l (count board) | |
bounds (map int (range 0 (inc l) (/ l n)))] | |
(apply into | |
(pmap #(vec (map step1 (partition 3 1 | |
(concat [(board (mod (dec %1) l))] | |
(subvec board %1 %2) | |
[(board (mod %2 l))])))) | |
bounds (rest bounds))))) | |
;; utilities and frontend | |
(defn rand-board [w h] | |
(vec (map #(into-array Object %) (partition w (take (* w h) (repeatedly #(if (zero? (rand-int 3)) :on :off))))))) | |
(defn dims [[row :as board]] [(count row) (count board)]) | |
(defn render-board [board #^Graphics2D g cell-size] | |
(let [[w h] (dims board)] | |
(doto g | |
(.setColor Color/BLACK) | |
(.scale cell-size cell-size) | |
(.fillRect 0 0 w h)) | |
(doseq [i (range h) j (range w)] | |
(when-let [color ({:on Color/WHITE :dying Color/GRAY} (aget #^objects (board i) (int j)))] | |
(doto g | |
(.setColor color) | |
(.fillRect j i 1 1)))))) | |
(defn start-brian [board cell-size] | |
(let [[w h] (dims board) | |
switch (atom true) | |
board (atom board) | |
panel (doto (proxy [JPanel] [] | |
(paint [g] (render-board @board g cell-size))) | |
(.setDoubleBuffered true))] | |
(doto (JFrame.) | |
(.addWindowListener (proxy [java.awt.event.WindowAdapter] [] | |
(windowClosing [_] (reset! switch false)))) | |
(.setSize (* w cell-size) (* h cell-size)) | |
(.add panel) | |
.show) | |
(future (while @switch (swap! board step))) | |
(future (while @switch (.repaint panel) (Thread/sleep 40))))) | |
(start-brian (rand-board 200 200) 5) | |
;; vector of vector version | |
(import '(javax.swing JFrame JPanel) | |
'(java.awt Color Graphics2D)) | |
;; non unrolled version | |
(defn neighbours-count [rows i w] | |
(count (for [j [(mod (inc i) w) i (mod (dec i) w)] | |
r rows :when (= :on (r j))] r))) | |
(defn neighbours-count [[above current below] i w] | |
(let [j (mod (inc i) w) | |
k (mod (dec i) w) | |
s #(if (= (%1 %2) :on) 1 0)] | |
(+ (+ (+ (s above j) (s above i)) | |
(+ (s above k) (s current j))) | |
(+ (+ (s current k) (s below j)) | |
(+ (s below i) (s below k)))))) | |
(defn step1 [rows] | |
(let [current (second rows) | |
w (count current)] | |
(loop [i (dec w), row (transient current)] | |
(if (neg? i) | |
(persistent! row) | |
(let [c (current i)] | |
(cond | |
(= c :on) | |
(recur (dec i) (assoc! row i :dying)) | |
(= c :dying) | |
(recur (dec i) (assoc! row i :off)) | |
(= 2 (neighbours-count rows i w)) | |
(recur (dec i) (assoc! row i :on)) | |
:else | |
(recur (dec i) row))))))) | |
;; non parallel step | |
(defn step [board] | |
(vec (map step1 | |
(partition 3 1 (concat [(peek board)] board [(first board)]))))) | |
(defn step [board] | |
(let [n (.availableProcessors (Runtime/getRuntime)) | |
l (count board) | |
bounds (map int (range 0 (inc l) (/ l n)))] | |
(apply into | |
(pmap #(vec (map step1 (partition 3 1 | |
(concat [(board (mod (dec %1) l))] | |
(subvec board %1 %2) | |
[(board (mod %2 l))])))) | |
bounds (rest bounds))))) | |
;; utilities and frontend | |
(defn rand-board [w h] | |
(vec (map vec (partition w (take (* w h) (repeatedly #(if (zero? (rand-int 3)) :on :off))))))) | |
(defn dims [[row :as board]] [(count row) (count board)]) | |
(defn render-board [board #^Graphics2D g cell-size] | |
(let [[w h] (dims board)] | |
(doto g | |
(.setColor Color/BLACK) | |
(.scale cell-size cell-size) | |
(.fillRect 0 0 w h)) | |
(doseq [i (range h) j (range w)] | |
(when-let [color ({:on Color/WHITE :dying Color/GRAY} ((board i) j))] | |
(doto g | |
(.setColor color) | |
(.fillRect j i 1 1)))))) | |
(defn start-brian [board cell-size] | |
(let [[w h] (dims board) | |
switch (atom true) | |
board (atom board) | |
panel (doto (proxy [JPanel] [] | |
(paint [g] (render-board @board g cell-size))) | |
(.setDoubleBuffered true))] | |
(doto (JFrame.) | |
(.addWindowListener (proxy [java.awt.event.WindowAdapter] [] | |
(windowClosing [_] (reset! switch false)))) | |
(.setSize (* w cell-size) (* h cell-size)) | |
(.add panel) | |
.show) | |
(future (while @switch (swap! board step))) | |
(future (while @switch (.repaint panel) (Thread/sleep 40))))) | |
(start-brian (rand-board 200 200) 5) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment