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