Thanks all.

Just to close this off, this is my (now working!) code, still needs some 
re-factoring (especially given Jim's last note re not needing watches in 
seesaw). It's basically a gui wrapped around the implementation of Life 
from Clojure Programming, with a few functions to add gliders, guns etc in 
the repl.

(ns conways-life.core
  (:use seesaw.core
        seesaw.graphics
        seesaw.color))

; Conway's Life
(defn neighbours
[[x y]]
  (for [dx [-1 0 1] dy [-1 0 1] :when (not= 0 dx dy)]
  [(+ dx x) (+ dy y)]))

(defn step
"Yields the next state of the world"
  [cells]
  (set (for [[loc n] (frequencies (mapcat neighbours cells))
  :when (or (= n 3) (and (= n 2) (cells loc)))]
              loc)))

  (def starting-live-cells #{})
  (def current-live-cells (atom starting-live-cells))
  
  (defn paint [c g]  
    (let [w (.getWidth c)
          h (.getHeight c)]
      (doseq [{:as cell} @current-live-cells]
        (let [cell-x (* 10(cell 0))
              cell-y (* 10(cell 1))]
          (when (and (< cell-x w) (< cell-y h))
            (draw g          
            (ellipse  (mod cell-x w)
                    (mod cell-y h) 10 10)
              (style :background (color 255 255 255 255))))))))

  (defn cells-changed
    ; called when current-live-cells changes
    [fr _ _ _ _]
    (repaint! (select fr [:#canvas])))

(defn -main [& args]
  (life))  
  
(defn life []

  (native!)
  
  (def f (frame 
    :title "Conway's Life" 
    :width 500 :height 300
    :content 
    (border-panel :hgap 5 :vgap 5 :border 5
                  ; Create the canvas with initial nil paint function, i.e. 
just canvas
                  ; will be filled with it's background color and that's it.
                  :center (canvas :id :canvas :background "#BBBBDD" :paint 
paint))))

  (add-watch current-live-cells :log (partial cells-changed f))

  (show! f)

  (def evolve-delay 100) ; delay in milliseconds
  
  (defn evolve []
    (Thread/sleep evolve-delay)
    (swap! current-live-cells step)
    (recur)
    )
  
  (future (evolve)))

(defn add-glider
  [x y cells]
  (conj cells [(+ x 2) y][(+ 2 x) (+ y 1)][(+ 2 x) (+ y 2)][(+ x 1)(+ y 
2)][x (+ y 1)]))

(defn add-blinker
  [x y cells]
  (conj cells [0 0][0 1][0 2]))

(defn add-gosper-gun
  [x y cells]
  (conj cells
        [0 4][0 5]
        [1 4][1 5]
        [10 4][10 5][10 6]
        [11 3][11 7]
        [12 2][12 8]
        [13 2][13 8]
        [14 5]
        [15 3][15 7]
        [16 4][16 5][16 6]
        [17 5]
        [20 2][20 3][20 4]
        [21 2][21 3][21 4]
        [22 1][22 5]
        [24 0][24 1][24 5][24 6]
        [34 2][34 3]
        [35 2][35 3]))

(defn reset []
  (swap! current-live-cells (fn [_] #{})))

(defn gosper-gun []
  (swap! current-live-cells (partial add-gosper-gun 0 0)))

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to