Skip to content

Instantly share code, notes, and snippets.

@cgrand
Created November 17, 2009 09:11
Show Gist options
  • Save cgrand/236782 to your computer and use it in GitHub Desktop.
Save cgrand/236782 to your computer and use it in GitHub Desktop.
;; 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