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 <[email protected]>
>> 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 [email protected]
>> > Note that posts from new members are moderated - please be patient with
>> your
>> > first post.
>> > 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
>>
>>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
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