001 (ns the-great-game.gossip.gossip
002 "Interchange of news events between agents 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 if 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))