I've incorporated everyone's suggestions and thought I would post the
resulting smaller code. I refactored init-cells away and just pass in
an init or new function to calc-state to reuse the for loop. I made
determine-next-state a little more verbose than technically necessary
to make conway's rules more obvious to me. The refs "cells" and
"running" don't feel very functional but I don't know how to get rid
of them.
(import '(javax.swing JFrame JPanel JButton)
'(java.awt BorderLayout Dimension Color)
'(java.awt.event ActionListener))
(def cells (ref {}))
(def running (ref false))
(defn determine-initial-state [x y]
(= 0 (rand-int 5)))
(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 [(+ x dx) (+ y dy)]))]
: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 32) y (range 48)]
[[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 100)
(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. 320 540))
(. 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))))))
(main)
Thanks for everyone. Very good learning experience.
Larry
http://lpsherrill.blogspot.com
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---