In my experience, life is a bit more interesting if the field wraps
and it is square.

Here are some mods to your most recent version that does this. I've
also parameterized the field size, the delay, and the initial
probability of a cell being occupied.

Thanks for sharing this - it's fun.

((import '(javax.swing JFrame JPanel JButton)
        '(java.awt BorderLayout Dimension Color)
        '(java.awt.event ActionListener))

(def cells (ref {}))

(def running (ref false))

(def x-cells 32)

(def y-cells 32)

(def life-delay 10)

(def life-initial-prob 3)

(defn determine-initial-state [x y]
  (= 0 (rand-int life-initial-prob)))

(defn determine-new-state [x y]
  (let [neighbor-count
         (count (for [dx [-1 0 1] dy [-1 0 1]
                  :when (and (not (= 0 dx dy))
                             (cells [(mod (+ x dx) x-cells)
                                     (mod (+ y dy) y-cells)]))]
                  :alive))]
    (if (cells [x y])
        (< 1 neighbor-count 4)
        (= neighbor-count 3))))

(defn calc-state [cell-state]
  (dosync
    (ref-set cells
      (reduce conj {}
        (for [x (range x-cells) y (range y-cells)]
          [[x y] (cell-state x y)])))))

(defn paint-cells [graphics]
     (doseq [[[x, y] state] @cells]
       (doto graphics
         (. setColor (if state Color/RED Color/WHITE))
         (. fillRect (* 10 x) (* 10 y) 10 10))))

(defn toggle-thread [panel button]
    (if @running
      (do (dosync (ref-set running false))
          (. button (setText "Start")))
      (do (dosync (ref-set running true))
          (. button (setText "Stop"))
          (. (Thread.
                 #(loop []
                    (calc-state determine-new-state)
                    (. panel repaint)
                    (Thread/sleep life-delay)
                    (if @running (recur))))
                 start))))

(defn main[]
  (calc-state determine-initial-state)
  (let [f (JFrame.)
        b (JButton. "Start")
        panel (proxy [JPanel] [] (paint [graphics] (paint-cells
                                                    graphics)))]
    (doto f
      (. setLayout (BorderLayout.))
      (. setLocation 100 100)
      (. setPreferredSize (Dimension. (* 10 x-cells) (+ 60 (* 10 y-
cells))))
      (. add b BorderLayout/SOUTH)
      (. add panel BorderLayout/CENTER)
      (. setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
      (. pack)
      (. setVisible true))
    (. b addActionListener
       (proxy [ActionListener] []
         (actionPerformed [evt] (toggle-thread panel b))))))

(comment
  (main))
--~--~---------~--~----~------------~-------~--~----~
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
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to