001  (ns the-great-game.gossip.gossip
002    "Interchange of news events between gossip agents"
003    (:require [the-great-game.utils :refer [deep-merge]]))
004  
005  ;; Note that habitual travellers are all gossip agents; specifically, at this
006  ;; stage, that means merchants. When merchants are moved we also need to
007  ;; update the location of the gossip with the same key.
008  
009  (defn dialogue
010    "Dialogue between an `enquirer` and an `agent` in this `world`; returns a
011    map identical to `enquirer` except that its `:gossip` collection may have
012    additional entries."
013    ;; TODO: not yet written, this is a stub.
014    [enquirer respondent world]
015    enquirer)
016  
017  (defn gather-news
018    ([world]
019     (reduce
020       deep-merge
021       world
022       (map
023         #(gather-news world %)
024         (keys (:gossips world)))))
025    ([world gossip]
026     (let [g (cond (keyword? gossip)
027                   (-> world :gossips gossip)
028                   (map? gossip)
029                   gossip)]
030       {:gossips
031        {(:id g)
032         (reduce
033           deep-merge
034           {}
035           (map
036             #(dialogue g % world)
037             (remove
038               #( = g %)
039               (filter
040                 #(= (:location %) (:location g))
041                 (vals (:gossips world))))))}})))
042  
043  (defn move-gossip
044    "Return a world like this `world` but with this `gossip` moved to this
045    `new-location`. Many gossips are essentially shadow-records of agents of
046    other types, and the movement of the gossip should be controlled by the
047    run function of the type of the record they shadow. The [[#run]] function
048    below does NOT call this function."
049    [gossip world new-location]
050    (let [id (cond
051              (map? gossip)
052              (-> world :gossips gossip :id)
053              (keyword? gossip)
054              gossip)]
055    (deep-merge
056      world
057      {:gossips
058       {id
059        {:location new-location}}})))
060  
061  (defn run
062    "Return a world like this `world`, with news items exchanged between gossip
063    agents."
064    [world]
065    (gather-news world))