Hi,

far from being a good design or whatever, but maybe this gets you started:

(def fauna
  (ref
    {"Fighter 1" {:movement 3 :location [1 2]}
     "Troll 2"   {:movement 1 :location [2 2]}}))

(def world
  (ref
    {[1 1] #{}
     [1 2] #{"Fighter 1"}
     [2 1] #{}
     [2 2] #{"Troll 2"}}))

(defn move-unit-from-to
  [w unit from to]
  (-> w
    (update-in [from] disj unit)
    (update-in [to]   conj unit)))

(defn update-unit-position
  [f unit new-location cost]
  (-> f
    (update-in [unit :movement] - cost)
    (assoc-in  [unit :location] new-location)))

; For sake of demonstration
(def calculate-movement-cost (constantly 1))

(defn move-unit-to
  [unit new-location]
  (dosync
    (let [old-location (get-in @fauna [unit :location])
          cost         (calculate-movement-cost old-location new-location)]
      (alter world move-unit-from-to unit old-location new-location)
      (alter fauna update-unit-position unit new-location cost))))

First write the necessary functions which are pure. They will update your 
data structures. I would indeed give some unique name to each unit, so it 
can be addressed. Then have a map from unit to its state. If you also need 
the reverse lookup: location to list of units, keep a map from locations to 
a set (not sequence or vector) of units at that location. "unit" here means 
the unique id. Then stitch things together using reference types. Moving a 
unit involves updating the world as well as updating the units state. If you 
keep these separate, you'll need refs. If you put everything in a map 
({:world ... :fauna ...}), you can use an atom again.

Again: I have no clue how feasible this design is, but it should serve as an 
example how this could be handled in Clojure.

A short demo:

user=> @world @fauna
{[1 1] #{}, [1 2] #{"Fighter 1"}, [2 1] #{}, [2 2] #{"Troll 2"}}
{"Troll 2" {:movement 1, :location [2 2]}, "Fighter 1" {:movement 3, 
:location [1 2]}}
user=> (move-unit-to "Fighter 1" [2 2])
{"Troll 2" {:movement 1, :location [2 2]}, "Fighter 1" {:movement 2, 
:location [2 2]}}
user=> @world @fauna
{[1 1] #{}, [1 2] #{}, [2 1] #{}, [2 2] #{"Troll 2" "Fighter 1"}}
{"Troll 2" {:movement 1, :location [2 2]}, "Fighter 1" {:movement 2, 
:location [2 2]}}

Hope this helps.

Sincerely
Meikel

-- 
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