You could start with pure functions to handle the game logic, e.g.:

(defn new-game []
  [[\- \- \-]
   [\- \- \-]
   [\- \- \-]])

(defn print-game [game]
  (doseq [row game]
    (println (apply str row))))

(defn move [game mark pos]
  (assoc-in game pos mark))

(print-game (new-game))
(print-game (move (new-game) \x [1 1]))
(print-game (-> (new-game) (move \x [1 1]) (move \o [0 2])))

On Friday, April 20, 2012 3:30:59 PM UTC+2, Craig Ching wrote:
>
> Thanks for the help to both of you!  Question, does it seem heavy handed 
> to do it this way?  I mean, atoms are more for thread-safety, aren't they? 
>  I don't have threads so it seems a bit much to use atoms for this.  Am I 
> better off using recur and trying to loop?  Or is this considered an 
> idiomatic way to handle mutable data in Clojure?  I always found wrapping 
> up mutable data in a closure as we did in Scheme to be pretty elegant, but 
> maybe something like that goes against the desire of Clojure to protect 
> against concurrent modification, is that about right?
>
> Thanks again!
>
> On Thursday, April 19, 2012 10:01:23 PM UTC-5, Gaz wrote:
>>
>> to answer your question directly, you would need to do something like
>> this to make it work the way your example is set up:
>>
>> (defn new-game []
>>   (let [board (atom (into [] (repeat 9 nil)))]
>>     (fn [n & [i]]
>>       (cond
>>        (= n :x) (swap! board assoc i 'x)
>>        (= n :o) (swap! board assoc i 'o)
>>        (= n :print) (println @board)))))
>>
>> (def g1 (new-game))
>>
>> (g1 :x 0)
>> (g1 :print)
>>
>> On Thu, Apr 19, 2012 at 9:58 PM, Armando Blancas <abm221...@gmail.com> 
>> wrote:
>> > You could keep the board in an atom so it can mutate; then try to find 
>> maybe
>> > two good places for mutation to happen, your move and the program's. 
>> With
>> > the rest being functional you'll avoid the problems of global state 
>> while
>> > not being forced to fit your logic into a loop of some re-binding that
>> > simulates mutation.
>> >
>> >
>> > On Thursday, April 19, 2012 3:21:56 PM UTC-7, Craig Ching wrote:
>> >>
>> >> Ok, I've read that what I want to do is a no no.  But this is the sort 
>> of
>> >> thing I did in Scheme about 20 years ago (and because of that I'm 
>> probably
>> >> misremembering ;-)).
>> >>
>> >> Basically I'm learning clojure and thought I'd write a tic tac toe 
>> game.
>> >>  But not any tic tac toe, I want to write one where I can have multiple
>> >> games going simultaneously.  Something like:
>> >>
>> >> (def g1 (new-game))
>> >> (def g2 (new-game))
>> >>
>> >> (g1 :x 0)
>> >> (g1 :print)
>> >> (g2 :x 5)
>> >> (g2 :print)
>> >>
>> >> So the schemer in me (and probably the imperative programmer as well)
>> >> thought I could return a clojure that encapsulates the board value,
>> >> something like this:
>> >>
>> >> (defn new-game []
>> >>
>> >>   (let [board (into [] (repeat 9 nil))]
>> >>
>> >>     (fn [n i]
>> >>
>> >>       (cond
>> >>
>> >>         (= n :x)(set! board (assoc board i 'x))
>> >>
>> >>         (= n :o)(set! board (assoc board i 'o))
>> >>
>> >>         (= n :print) (println board)))))
>> >>
>> >>
>> >> Of course I get an error saying I can't bind to the non-mutable board.
>> >>
>> >> I'm really new to Clojure, so apologies if this is really basic for 
>> this
>> >> list.  Can I do what I want or can someone point me in the right 
>> direction?
>> >>  I've seen some other tic tac toe implementations on github, but they 
>> use
>> >> recur to track state and I was hoping there was a cleaner idiomatic 
>> way than
>> >> that.
>> >>
>> >> Thanks!
>> >>
>> > --
>> > 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 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

Reply via email to