001  (ns cc.journeyman.the-great-game.gossip.gossip
002    "Interchange of news events between gossip agents.
003     
004     Note that habitual travellers are all gossip agents; specifically, at this
005     stage, that means merchants. When merchants are moved we also need to
006     update the location of the gossip with the same key.
007     
008     Innkeepers are also gossip agents but do not typically move."
009    (:require [cc.journeyman.the-great-game.utils :refer [deep-merge]]
010              [cc.journeyman.the-great-game.gossip.news-items :refer [learn-news-item]]
011              ))
012  
013  
014  (defn dialogue
015    "Dialogue between an `enquirer` and an `agent` in this `world`; returns a
016    map identical to `enquirer` except that its `:gossip` collection may have
017    additional entries."
018    ;; TODO: not yet written, this is a stub.
019    [enquirer respondent world]
020    enquirer)
021  
022  (defn gather-news
023    "Gather news for the specified `gossip` in this `world`."
024    [world gossip]
025    (let [g (cond (keyword? gossip)
026                  (-> world :gossips gossip)
027                  (map? gossip)
028                  gossip)]
029      (if g
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  
044  (defn move-gossip
045    "Return a world like this `world` but with this `gossip` moved to this
046    `new-location`. Many gossips are essentially shadow-records of agents of
047    other types, and the movement of the gossip should be controlled by the
048    run function of the type of the record they shadow. The [[#run]] function
049    below does NOT call this function."
050    [gossip world new-location]
051    (let [id (cond
052              (map? gossip)
053              (-> world :gossips gossip :id)
054              (keyword? gossip)
055              gossip)]
056    (deep-merge
057      world
058      {:gossips
059       {id
060        {:location new-location}}})))
061  
062  (defn run
063    "Return a world like this `world`, with news items exchanged between gossip
064    agents."
065    [world]
066    (reduce
067     deep-merge
068     world
069     (map
070      #(gather-news world %)
071      (keys (:gossips world)))))
072  
073