Working on unit tests.
This commit is contained in:
parent
2461319e57
commit
23032c586c
28 changed files with 6602 additions and 207 deletions
40
src/cc/journeyman/architecture.md
Normal file
40
src/cc/journeyman/architecture.md
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
OK, the basic idea is this
|
||||
|
||||
Everything (every game object, including the world) is a map.
|
||||
|
||||
Every object as an :id property; every :id property is distinct.
|
||||
|
||||
There is a master map - the `oblist` which contains every object, keyed by its :id.
|
||||
|
||||
Every object has a :run function, which returns either a new copy of itself or nil, and does not have side effects.
|
||||
|
||||
Every object has a :location function, which takes one argument, the object, and returns its location as a coordinate pair (or coordinate triple, probably) (this may involve fetching the location from the container in which it is contained, which implies that a contained object must hold a handle to its container).
|
||||
|
||||
Every collection of things in the world is represented as a list of :id values, by which the actual objects can be fetched from the `oblist`.
|
||||
|
||||
## Circles
|
||||
|
||||
Among those collections are the circles. The circles include, at minimum
|
||||
|
||||
1. Those objects in audible/visual range of the player; these have their run method invoked avery game loop. Weather, is always in this circle. The sun and moon are in this circle from shortly becore they rise to shortly after they set.
|
||||
2. Those objects which might come into audible/visual range within a short period; these have their run method invoked every N game loops, where N is probably variable depending on overall system load
|
||||
3. Those objects (actors) which are necessary to maintain the gossip system, etc. These should each have their run method invoked once per game day, but that is done by invoking the run method of a share of them each game loop.
|
||||
|
||||
So `run` takes three arguments - the object, the world and the circle; and returns nil if it makes no change, or a new copy of itself; and probably each of the main functions that run calls have the same behaviour. So, for example, a hierarchy of needs can be represented by
|
||||
|
||||
|
||||
(defn run [character world circle]
|
||||
(first
|
||||
(handle-immediate-threat character world circle) ;; if being attacked, deal with it
|
||||
(complete-current-action character world circle) ;; otherwise, continue the current
|
||||
;; short-term unless completed
|
||||
(handle-thirst character world circle) ;; perhaps adjust tactical plan to find water
|
||||
(handle-hunger character world circle) ;; perhaps adjust tactical plan to find food
|
||||
(handle-fatigue character world circle) ;; perhaps rest if safe to do so
|
||||
(advance-current-plan character world circle) ;; select next step of current strategic plan
|
||||
(select-next-plan character world circle) ;; plan new strategic objective
|
||||
(return-home character world circle))) ;; if no other strategic objective, return
|
||||
;; to home location
|
||||
|
||||
|
||||
Atoms? Background threads?
|
||||
|
|
@ -115,36 +115,6 @@
|
|||
:cultures #{:coastal}
|
||||
:modules []}})
|
||||
|
||||
;; TODO: So, modules need to contain
|
||||
;;
|
||||
;; 1. Ground floor modules, having external doors;
|
||||
;; 2. Craft modules -- workshops -- which will normally be ground floor (except
|
||||
;; weavers) and may have the constraint that no upper floor module can cover them;
|
||||
;; 3. Upper floor modules, having NO external doors (but linking internal doors);
|
||||
;; 4. Roof modules
|
||||
;;
|
||||
;; There also needs to be an undercroft or platform module, such that the area of
|
||||
;; the top of the platform is identical with the footprint of the building, and
|
||||
;; the altitude of the top of the platform is equal to the altitude of the
|
||||
;; terrain at the heighest corner of the building; so that the actual
|
||||
;; building doesn't float in the air, and also so that none of the doors or windows
|
||||
;; are partly underground.
|
||||
;;
|
||||
;; Each module needs to wrap an actual 3d model created in Blender or whatever,
|
||||
;; and have a list of optional textures with which that model can be rendered.
|
||||
;; So an upper floor bedroom module might have the following renders:
|
||||
;;
|
||||
;; 1. Bare masonry - constrained to upland or plateau terrain, and to coastal culture
|
||||
;; 2. Painted masonry - constrained to upland or plateau terrain, and to coastal culture
|
||||
;; 3. Half-timbered - not available on plateau terrain
|
||||
;; 4. Weatherboarded - constrained to forest terrain
|
||||
;; 5. Brick - constrained to arable or arid terrain
|
||||
;;
|
||||
;; of course these are only examples, and also, it's entirely possible to have
|
||||
;; for example multiple different weatherboard renders for the same module.
|
||||
;; There needs to be a way of rendering what can be built above what: for
|
||||
;; example, you can't have a masonry clad module over a half timbered one,
|
||||
;; but you can have a half-timbered one over a masonry one
|
||||
|
||||
(defn building-family
|
||||
"A building family is essentially a collection of models of building modules
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
(ns cc.journeyman.the-great-game.gossip.news-items
|
||||
"Categories of news events interesting to gossip agents.
|
||||
"Using news items (propositions) to transfer knowledge between gossip agents.
|
||||
|
||||
The ideas here are based on the essay [The spread of knowledge in a large
|
||||
game world](The-spread-of-knowledge-in-a-large-game-world.html), q.v.;
|
||||
|
|
@ -22,7 +22,8 @@
|
|||
list of propositions, each of which must be checked every time any new
|
||||
proposition is offered. This is woefully inefficient. "
|
||||
(:require [cc.journeyman.the-great-game.world.location :refer [distance-between]]
|
||||
[cc.journeyman.the-great-game.time :refer [game-time]]))
|
||||
[cc.journeyman.the-great-game.time :refer [game-time]]
|
||||
[taoensso.timbre :as l]))
|
||||
|
||||
|
||||
(def news-topics
|
||||
|
|
@ -155,8 +156,8 @@
|
|||
|
||||
(defn interesting-location?
|
||||
"True if the location of this news `item` is interesting to this `gossip`."
|
||||
[gossip item]
|
||||
(> (interest-in-location gossip (:location item)) 0))
|
||||
[gossip location]
|
||||
(> (interest-in-location gossip location) 0))
|
||||
|
||||
(defn interesting-object?
|
||||
[gossip object]
|
||||
|
|
@ -190,13 +191,16 @@
|
|||
learning that 'someone killed Sweet Daisy', but there is point in learning
|
||||
'someone killed Sweet Daisy _with poison_'."
|
||||
[new-item known-item]
|
||||
(reduce
|
||||
#(and %1 %2)
|
||||
(map #(if
|
||||
(known-item %) ;; if known-item has this key
|
||||
(compatible-value? (new-item %) (known-item %))
|
||||
true)
|
||||
(remove #{:nth-hand :confidence :learned-from} (keys new-item)))))
|
||||
(if
|
||||
(reduce
|
||||
#(and %1 %2)
|
||||
(map #(if
|
||||
(known-item %) ;; if known-item has this key
|
||||
(compatible-value? (new-item %) (known-item %))
|
||||
true)
|
||||
(remove #{:nth-hand :confidence :learned-from} (keys new-item))))
|
||||
true
|
||||
false))
|
||||
|
||||
(defn known-item?
|
||||
"True if this news `item` is already known to this `gossip`.
|
||||
|
|
@ -205,9 +209,13 @@
|
|||
the same _or more specific_ values for all the keys of this `item` except
|
||||
`:nth-hand`, `:confidence` and `:learned-from`."
|
||||
[gossip item]
|
||||
(reduce
|
||||
#(or %1 %2)
|
||||
(filter true? (map #(compatible-item? item %) (:knowledge gossip)))))
|
||||
(if
|
||||
(reduce
|
||||
#(or %1 %2)
|
||||
false
|
||||
(filter true? (map #(compatible-item? item %) (:knowledge gossip))))
|
||||
true
|
||||
false))
|
||||
|
||||
(defn interesting-item?
|
||||
"True if anything about this news `item` is interesting to this `gossip`."
|
||||
|
|
@ -220,30 +228,39 @@
|
|||
(interesting-object? gossip (:object item))
|
||||
(interesting-topic? gossip (:verb item)))))
|
||||
|
||||
(defn inc-or-one
|
||||
"If this `val` is a number, return that number incremented by one; otherwise,
|
||||
return 1. TODO: should probably be in `utils`."
|
||||
[val]
|
||||
(if
|
||||
(number? val)
|
||||
(inc val)
|
||||
1))
|
||||
|
||||
(defn infer
|
||||
"Infer a new knowledge item from this `item`, following this `rule`"
|
||||
"Infer a new knowledge item from this `item`, following this `rule`."
|
||||
[item rule]
|
||||
;; (l/info "Applying rule '" rule "' to item '" item "'")
|
||||
(reduce merge
|
||||
item
|
||||
(cons
|
||||
{:verb (:verb rule)}
|
||||
(map (fn [k] {k (apply (k rule) (list item))})
|
||||
{:verb (:verb rule)
|
||||
:nth-hand (inc-or-one (:nth-hand item))}
|
||||
(map (fn [k] {k (item (rule k))})
|
||||
(remove
|
||||
#{:verb}
|
||||
#{:verb :nth-hand}
|
||||
(keys rule))))))
|
||||
|
||||
(declare learn-news-item)
|
||||
|
||||
(defn make-all-inferences
|
||||
"Return a list of knowledge entries that can be inferred from this news
|
||||
"Return a set of knowledge entries that can be inferred from this news
|
||||
`item`."
|
||||
[item]
|
||||
(set
|
||||
(reduce
|
||||
concat
|
||||
(map
|
||||
#(:knowledge (learn-news-item {} (infer item %) false))
|
||||
(:inferences (news-topics (:verb item)))))))
|
||||
#(infer item %)
|
||||
(:inferences (news-topics (:verb item))))))
|
||||
|
||||
(defn degrade-character
|
||||
"Return a character specification like this `character`, but comprising
|
||||
|
|
@ -264,15 +281,6 @@
|
|||
location))]
|
||||
(when-not (empty? l) l)))
|
||||
|
||||
(defn inc-or-one
|
||||
"If this `val` is a number, return that number incremented by one; otherwise,
|
||||
return 1. TODO: should probably be in `utils`."
|
||||
[val]
|
||||
(if
|
||||
(number? val)
|
||||
(inc val)
|
||||
1))
|
||||
|
||||
(defn learn-news-item
|
||||
"Return a gossip like this `gossip`, which has learned this news `item` if
|
||||
it is of interest to them."
|
||||
|
|
|
|||
|
|
@ -43,5 +43,3 @@
|
|||
|
||||
;; (.settlement (OrientedLocation. 123.45 543.76 12.34 0.00 {}))
|
||||
|
||||
|
||||
;; (OrientedLocation. 123.45 543.76 12.34 0.00 {})
|
||||
Loading…
Add table
Add a link
Reference in a new issue