# the_great_game/gossip/gossip.clj

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 [the-great-game.gossip.news-items :refer [learn-news-item]]))
005
006 ;; Note that habitual travellers are all gossip agents; specifically, at this
007 ;; stage, that means merchants. When merchants are moved we also need to
008 ;; update the location of the gossip with the same key.
009
010 (defn dialogue
011 "Dialogue between an `enquirer` and an `agent` in this `world`; returns a
012 map identical to `enquirer` except that its `:gossip` collection may have
013 additional entries."
014 ;; TODO: not yet written, this is a stub.
015 [enquirer respondent world]
016 enquirer)
017
018 (defn gather-news
019 ([world]
020 (reduce
021 deep-merge
022 world
023 (map
024 #(gather-news world %)
025 (keys (:gossips world)))))
026 ([world gossip]
027 (let [g (cond (keyword? gossip)
028 (-> world :gossips gossip)
029 (map? gossip)
030 gossip)]
031 {:gossips
032 {(:id g)
033 (reduce
034 deep-merge
035 {}
036 (map
037 #(dialogue g % world)
038 (remove
039 #( = g %)
040 (filter
041 #(= (:location %) (:location g))
042 (vals (:gossips world))))))}})))
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 (gather-news world))