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