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 <lps...@gmail.com> 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" <kyle.bur...@gmail.com> wrote:
>
> > On Mon, Mar 16, 2009 at 12:31 AM, Scott Fraser <scott.e.fra...@gmail.com> 
> > 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
>
> > --
> > --------------------------------------------------------------------------- 
> > ---
> > kyle.bur...@gmail.com                            
> > 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 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