I have not had a chance to merge the parallel updates in to life-
conway.clj in the files section yet, but for now I thought I would
note I did make one fun enhancement, which is to have each thread
color code the cells. So all cells with the same color were processed
by one pmap thread. On my 8-core it is quite colorful and fun.
As always, comments appreciate. Here is it:
-Scott
(import '(javax.swing JFrame JPanel JButton)
'(java.awt BorderLayout Dimension Color)
'(java.awt.event ActionListener))
(def cells (ref {}))
(def running (atom false))
(def x-cells ( * 32 1))
(def y-cells ( * 48 1))
;(def x-cells 32)
;(def y-cells 32)
(def range-cells (for [x (range x-cells) y (range y-cells)] [x y]))
(def length-range-cells (count range-cells))
(def cell-size 10)
(def life-delay 0)
(def life-initial-prob 3)
(def available-procs (.. java.lang.Runtime getRuntime
availableProcessors))
;(def available-procs 8)
(def batch-sets (for [cpu (range available-procs)] (take-nth available-
procs (drop cpu range-cells))))
; some things we will use to give each thread a different color
(def counter (ref 0))
(def color-list [Color/RED Color/ORANGE Color/GREEN Color/YELLOW Color/
BLUE Color/MAGENTA Color/PINK Color/CYAN])
(def num-colors (count color-list))
(def empty-color Color/BLACK)
(defn next-color []
(dosync (if (or (= @counter (dec num-colors)) (= @counter (dec
available-procs)))
(ref-set counter 0)
(alter counter inc))))
(defn determine-initial-state [x y]
(= 0 (rand-int life-initial-prob)))
(defn determine-new-state [x y]
(let [alive (count (for [dx [-1 0 1] dy [-1 0 1]
:when (and (not (= 0 dx dy))
(not (= empty-color (cells [ (mod
(+ x dx) x-cells) (mod (+ y dy) y-cells)]))))]
:alive))]
(if (not (= (cells [x y]) empty-color))
(< 1 alive 4)
(= alive 3))))
(defn update-batch-of-new-cells [new-cells list-of-batches]
(dosync
(dorun (map #(commute new-cells assoc (first %) (second %))
list-of-batches))
))
(defn calc-batch-of-new-cell-states [cell-state batch-cells]
( let [thread-color (nth color-list (next-color))]
doall (map
#(let [new-cell-state (if (cell-state (first %) (second
%)) thread-color empty-color)]
[[(first %) (second %)] new-cell-state])
batch-cells)))
(defn calc-state [cell-state]
(let [new-cells (ref {})]
(dorun (pmap #(update-batch-of-new-cells new-cells %)
(pmap #(calc-batch-of-new-cell-states cell-state %)
batch-sets)))
(dosync (ref-set cells @new-cells))))
(defn paint-cells [#^java.awt.Graphics graphics]
(doseq [[[x,y] state] @cells]
(doto graphics
(.setColor state)
(.fillRect (* cell-size x) (* cell-size y) cell-size cell-
size))))
(defn toggle-thread [#^JPanel panel button]
(if @running
(do (dosync (reset! running false))
(. button (setText "Start")))
(do (dosync (reset! running true))
(. button (setText "Stop"))
(. (Thread.
#(loop []
(calc-state determine-new-state)
(.repaint panel)
(if life-delay (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. (* cell-size x-cells) (+ 60 (*
cell-size 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))))))
On Mar 16, 11:51 am, Larry Sherrill <[email protected]> wrote:
> Hi Kyle,
>
> I added life-conway.clj to the files section last week. It has rand,
> clear, and bounded buttons, and the ability to use your mouse to draw
> the pattern rather than rely on rand. It's a good way to experiment
> with different automata such as gliders.
>
> Larry Sherrill
>
> On Mar 16, 9:33 am, "Kyle R. Burton" <[email protected]> wrote:
>
> > On Mon, Mar 16, 2009 at 12:31 AM, Scott Fraser <[email protected]>
> > wrote:
>
> > > I have taken Larry's "Game of Life" example that he originally posted
> > > here:
>
> > >http://groups.google.com/group/clojure/msg/fdfc88f1ba95bdee
>
> > > ...and updated it to use all the CPU's your JVM has access to...
>
> > Scott,
>
> > Your changes indeed make it run significantly faster for me. Thanks!
>
> > I added a 'reset' button and changed some of the java method calls to
> > be a bit more (I think) idomatic clojure.
>
> > The full file is
> > here:http://asymmetrical-view.com/personal/code/clojure/life.clj
>
> > And a patch is attached (you also left off the import statements in you
> > email).
>
> > FYI: Scott Fraser is giving a talk on clojure at the Philly Emerging
> > Technologies for the Enterprise conference next week:
>
> > http://phillyemergingtech.com/abstractsTab.php?sessID=39
> > http://phillyemergingtech.com/speakers.php
>
> > Regards,
>
> > Kyle Burton
>
> > --
> > ---------------------------------------------------------------------------
> > ---
> > [email protected]
> > http://asymmetrical-view.com/
> > ---------------------------------------------------------------------------
> > ---
>
> > life.patch
> > 3KViewDownload
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---