Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
42a2792539
12
.gitignore
vendored
12
.gitignore
vendored
|
@ -38,3 +38,15 @@ libopenal64.so
|
||||||
.settings/
|
.settings/
|
||||||
.classpath
|
.classpath
|
||||||
.project
|
.project
|
||||||
|
|
||||||
|
.calva/
|
||||||
|
.lsp/
|
||||||
|
|
||||||
|
|
||||||
|
*.so
|
||||||
|
|
||||||
|
docs/cloverage/codecov.json
|
||||||
|
|
||||||
|
docs/cloverage/coverage.xml
|
||||||
|
|
||||||
|
src/cc/journeyman/the_great_game/cloverage.clj
|
||||||
|
|
|
@ -0,0 +1,251 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<link rel="stylesheet" href="../../../../coverage.css"/> <title> cc/journeyman/the_great_game/buildings/module.clj </title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
001 (ns cc.journeyman.the-great-game.buildings.module
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
002
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
003 "A module of a building; essentially something like a portacabin, which can be
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
004 assembled together with other modules to make a complete building.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
005
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
006 Modules need to include
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
007
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
008 1. Ground floor modules, having external doors;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
009 2. Craft modules -- workshops -- which will normally be ground floor (except
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
010 weavers) and may have the constraint that no upper floor module can cover them;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
011 3. Upper floor modules, having NO external doors (but linking internal doors);
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
012 4. Roof modules
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
013
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
014 **Role** must be one of:
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
015
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
016 1. `:primary` a ground floor main entrance module
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
017 2. `:secondary` a module which can be upper or ground floor
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
018 3. `:upper` a module which can only be on an upper floor, for example one
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
019 with a projecting gallery, balcony or overhang.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
020
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
021 Other values for `role` will emerge.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
022
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
023 **Exits** must be a sequence of keywords taken from the following list:
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
024
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
025 1. `:left` an exit in the centre of the left wall
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
026 2. `:left-front` an exit in the centre of the left half of the front wall
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
027 3. `:front` an exit in the centre of the front wall
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
028 4. `:right-front` an exit in the centre of the right half of the front wall
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
029 5. `:right` an exit in the centre of the right wall
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
030 6. `:right-back` an exit in the centre of the right half of the back wall
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
031 7. `:left-back` an exit in the centre of the back wall
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
032
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
033 A module placed on an upper floor must have no exit which opens beyond the
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
034 footprint of the floor below - no doors into mid air! However, it is allowable
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
035 (and indeed is necessary) to allow doors into roof spaces if the adjacent
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
036 module on the same floor does not yet exist, since otherwise it would be
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
037 impossible to access a new room which might later be built there.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
038
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
039 **Load** must be a small integer indicating both the weight of the module and
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
040 the total amount of weight it can support. So for example a stone-built module
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
041 might have a `load` value of 4, a brick built one of 3, and a half-timbered one
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
042 of 2, and a tent of 0. This means a stone ground floor module could support one
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
043 further floor of stone or brick, or two further floors of half timbered
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
044 construction; while a brick built ground floor could support a single brick or
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
045 half-timbered upper floor but not a stone one, and a half-timbered ground floor
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
046 could only support a half timbered upper floor.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
047
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
048 There also needs to be an undercroft or platform module, such that the area of
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
049 the top of the platform is identical with the footprint of the building, and
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
050 the altitude of the top of the platform is equal to the altitude of the
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
051 terrain at the heighest corner of the building; so that the actual
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
052 building doesn't float in the air, and also so that none of the doors or windows
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
053 are partly underground.
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
054
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
055 Each module needs to wrap an actual 3d model created in Blender or whatever,
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
056 and have a list of optional **textures** with which that model can be rendered.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
057 So an upper floor bedroom module might have the following renders:
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
058
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
059 1. Bare masonry - constrained to upland or plateau terrain, and to coastal culture
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
060 2. Painted masonry - constrained to upland or plateau terrain, and to coastal culture
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
061 3. Half-timbered - not available on plateau terrain
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
062 4. Weatherboarded - constrained to forest terrain
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
063 5. Brick - constrained to arable or arid terrain
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
064
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
065 of course these are only examples, and also, it's entirely possible to have
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
066 for example multiple different weatherboard renders for the same module.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
067 There needs to be a way of rendering what can be built above what: for
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
068 example, you can't have a masonry clad module over a half timbered one,
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
069 but you can have a half-timbered one over a masonry one.")
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
070
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
071 (defrecord BuildingModule
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
072 [model
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
073 ^Double length
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
074 ^Double width
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
075 ^Double height
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
076 ^Integer load
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
077 ^clojure.lang.Keyword role
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
078 ^clojure.lang.IPersistentCollection textures
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
079 ^clojure.lang.IPersistentCollection exits
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
080 ]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
081 )
|
||||||
|
</span><br/>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -355,194 +355,104 @@
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
117
|
117
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
118 ;; TODO: So, modules need to contain
|
118
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
119 (defn building-family
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
119 ;;
|
120 "A building family is essentially a collection of models of building modules
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
120 ;; 1. Ground floor modules, having external doors;
|
121 which can be assembled to create buildings of a particular structural and
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
121 ;; 2. Craft modules -- workshops -- which will normally be ground floor (except
|
122 architectural style."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
122 ;; weavers) and may have the constraint that no upper floor module can cover them;
|
123 [terrain culture craft gene]
|
||||||
|
</span><br/>
|
||||||
|
<span class="partial" title="12 out of 13 forms covered">
|
||||||
|
124 (let [candidates (filter #(and
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
|
125 ((:terrains %) terrain)
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
|
126 ((:crafts %) craft)
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
|
127 ((:cultures %) culture))
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
128 (vals *building-families*))]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="8 out of 8 forms covered">
|
||||||
|
129 (nth candidates (mod (Math/abs (.nextInt gene)) (count candidates)))))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
130
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="7 out of 7 forms covered">
|
||||||
|
131 (building-family :arable :coastal :baker (MersenneTwister. 5))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
132
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
133 (defn build!
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
123 ;; 3. Upper floor modules, having NO external doors (but linking internal doors);
|
134 "Builds a building, and returns a data structure which represents it. In
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
124 ;; 4. Roof modules
|
135 building the building, it adds a model of the building to the representation
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
125 ;;
|
136 of the world, so it does have a side effect."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
126 ;; There also needs to be an undercroft or platform module, such that the area of
|
137 [holding terrain culture craft size]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 6 forms covered">
|
||||||
|
138 (if (satisfies? ProtoHolding holding)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
139 (let [location (.building-origin holding)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 7 forms covered">
|
||||||
|
140 gene (MersenneTwister. (int (+ (* (.easting location) 1000000) (.northing location))))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 6 forms covered">
|
||||||
|
141 family (building-family terrain culture craft gene)]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
142 (if
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 11 forms covered">
|
||||||
|
143 (and (instance? ProtoLocation location) (:orientation location))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
127 ;; the top of the platform is identical with the footprint of the building, and
|
144 :stuff
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
128 ;; the altitude of the top of the platform is equal to the altitude of the
|
145 :nonsense
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
129 ;; terrain at the heighest corner of the building; so that the actual
|
146 ))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
130 ;; building doesn't float in the air, and also so that none of the doors or windows
|
147 :froboz))
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
131 ;; are partly underground.
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
132 ;;
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
133 ;; Each module needs to wrap an actual 3d model created in Blender or whatever,
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
134 ;; and have a list of optional textures with which that model can be rendered.
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
135 ;; So an upper floor bedroom module might have the following renders:
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
136 ;;
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
137 ;; 1. Bare masonry - constrained to upland or plateau terrain, and to coastal culture
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
138 ;; 2. Painted masonry - constrained to upland or plateau terrain, and to coastal culture
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
139 ;; 3. Half-timbered - not available on plateau terrain
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
140 ;; 4. Weatherboarded - constrained to forest terrain
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
141 ;; 5. Brick - constrained to arable or arid terrain
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
142 ;;
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
143 ;; of course these are only examples, and also, it's entirely possible to have
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
144 ;; for example multiple different weatherboard renders for the same module.
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
145 ;; There needs to be a way of rendering what can be built above what: for
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
146 ;; example, you can't have a masonry clad module over a half timbered one,
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
147 ;; but you can have a half-timbered one over a masonry one
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
148
|
148
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
|
||||||
149 (defn building-family
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
150 "A building family is essentially a collection of models of building modules
|
149 ;; (def ol (cc.journeyman.the-great-game.location.location/OrientedLocation. 123.45 543.76 12.34 0.00 {}))
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
151 which can be assembled to create buildings of a particular structural and
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
152 architectural style."
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
153 [terrain culture craft gene]
|
|
||||||
</span><br/>
|
|
||||||
<span class="partial" title="12 out of 13 forms covered">
|
|
||||||
154 (let [candidates (filter #(and
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
|
||||||
155 ((:terrains %) terrain)
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
|
||||||
156 ((:crafts %) craft)
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
|
||||||
157 ((:cultures %) culture))
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
|
||||||
158 (vals *building-families*))]
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="8 out of 8 forms covered">
|
|
||||||
159 (nth candidates (mod (Math/abs (.nextInt gene)) (count candidates)))))
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
160
|
150
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="7 out of 7 forms covered">
|
|
||||||
161 (building-family :arable :coastal :baker (MersenneTwister. 5))
|
|
||||||
</span><br/>
|
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
162
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
|
||||||
163 (defn build!
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
164 "Builds a building, and returns a data structure which represents it. In
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
165 building the building, it adds a model of the building to the representation
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
166 of the world, so it does have a side effect."
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
167 [holding terrain culture craft size]
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 6 forms covered">
|
|
||||||
168 (if (satisfies? ProtoHolding holding)
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
|
||||||
169 (let [location (.building-origin holding)
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 7 forms covered">
|
|
||||||
170 gene (MersenneTwister. (int (+ (* (.easting location) 1000000) (.northing location))))
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 6 forms covered">
|
|
||||||
171 family (building-family terrain culture craft gene)]
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
|
||||||
172 (if
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 11 forms covered">
|
|
||||||
173 (and (instance? ProtoLocation location) (:orientation location))
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
174 :stuff
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
175 :nonsense
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
176 ))
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
177 :froboz))
|
|
||||||
</span><br/>
|
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
178
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
179 ;; (def ol (cc.journeyman.the-great-game.location.location/OrientedLocation. 123.45 543.76 12.34 0.00 {}))
|
|
||||||
</span><br/>
|
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
180
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -139,11 +139,5 @@
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
045
|
045
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
046
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
047 ;; (OrientedLocation. 123.45 543.76 12.34 0.00 {})
|
|
||||||
</span><br/>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -37,22 +37,22 @@
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
011 (defn init []
|
011 (defn init []
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="9 out of 9 forms covered">
|
<span class="not-covered" title="0 out of 9 forms covered">
|
||||||
012 (let [cube (geo "jMonkey cube" (box 1 1 1))
|
012 (let [cube (geo "jMonkey cube" (box 1 1 1))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
013 mat (unshaded-mat)]
|
013 mat (unshaded-mat)]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="11 out of 11 forms covered">
|
<span class="not-covered" title="0 out of 11 forms covered">
|
||||||
014 (set* mat :texture "ColorMap" (load-texture "textures/Monkey.jpg"))
|
014 (set* mat :texture "ColorMap" (load-texture "textures/Monkey.jpg"))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="8 out of 8 forms covered">
|
<span class="not-covered" title="0 out of 8 forms covered">
|
||||||
015 (set* cube :material mat)
|
015 (set* cube :material mat)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
016 (add-to-root cube)
|
016 (add-to-root cube)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
017 {:cube cube}))
|
017 {:cube cube}))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
028 ;; We define the `app` var.
|
028 ;; We define the `app` var.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="170 out of 215 forms covered">
|
<span class="partial" title="115 out of 215 forms covered">
|
||||||
029 (defsimpleapp app
|
029 (defsimpleapp app
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="36 out of 42 forms covered">
|
<span class="partial" title="36 out of 42 forms covered">
|
||||||
|
@ -112,17 +112,17 @@
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
036 :height 600}}
|
036 :height 600}}
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="1 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
037 :init init
|
037 :init init
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="1 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
038 :update simple-update)
|
038 :update simple-update)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
039
|
039
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
040 (start app)
|
040 ;; (start app)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
041
|
041
|
||||||
|
@ -145,11 +145,11 @@
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
047 ;; Let's increase its movement speed. Now, you fly faster :)
|
047 ;; Let's increase its movement speed. Now, you fly faster :)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="16 out of 16 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
048 (run app
|
048 ;; (run app
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="9 out of 9 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
049 (set* (fly-cam) :move-speed 15))
|
049 ;; (set* (fly-cam) :move-speed 15))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
050
|
050
|
||||||
|
@ -160,14 +160,14 @@
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
052 ;; Updates the app
|
052 ;; Updates the app
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="16 out of 16 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
053 (run app
|
053 ;; (run app
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
054 (let [{:keys [cube]} (get-state)]
|
054 ;; (let [{:keys [cube]} (get-state)]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="13 out of 13 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
055 (set* cube :local-translation (add (get* cube :local-translation) 1 1 1))))
|
055 ;; (set* cube :local-translation (add (get* cube :local-translation) 1 1 1))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
056
|
056
|
||||||
|
@ -175,32 +175,32 @@
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
057 ;; Updates the app adding a second cube
|
057 ;; Updates the app adding a second cube
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="16 out of 16 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
058 (run app
|
058 ;; (run app
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="9 out of 9 forms covered">
|
|
||||||
059 (let [cube (geo "jMonkey cube" (box 1 1 1))
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
|
||||||
060 mat (unshaded-mat)]
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="11 out of 11 forms covered">
|
|
||||||
061 (set* mat :texture "ColorMap" (load-texture "textures/Monkey.jpg"))
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="22 out of 22 forms covered">
|
|
||||||
062 (setc cube
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
|
||||||
063 :material mat
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
064 :local-translation [-3 0 0])
|
059 ;; (let [cube (geo "jMonkey cube" (box 1 1 1))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
065 (add-to-root cube)
|
060 ;; mat (unshaded-mat)]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
066 (set-state :cube2 cube)))
|
061 ;; (set* mat :texture "ColorMap" (load-texture "textures/Monkey.jpg"))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
062 ;; (setc cube
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
063 ;; :material mat
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
064 ;; :local-translation [-3 0 0])
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
065 ;; (add-to-root cube)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
066 ;; (set-state :cube2 cube)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
067
|
067
|
||||||
|
@ -208,17 +208,17 @@
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
068 ;; We added the new cube, but it's not rotating. We need to update the simple-update fn.
|
068 ;; We added the new cube, but it's not rotating. We need to update the simple-update fn.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
069 (defn simple-update [tpf]
|
069 ;; (defn simple-update [tpf]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
070 (let [{:keys [cube cube2]} (get-state)]
|
070 ;; (let [{:keys [cube cube2]} (get-state)]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="8 out of 8 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
071 (rotate cube 0 (* 2 tpf) 0)
|
071 ;; (rotate cube 0 (* 2 tpf) 0)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="8 out of 8 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
072 (rotate cube2 0 (* 2 tpf) 0)))
|
072 ;; (rotate cube2 0 (* 2 tpf) 0)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -139,5 +139,53 @@
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
045 ;; (value-or-default nil :altitude 8)
|
045 ;; (value-or-default nil :altitude 8)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
046
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
047 (defn truthy?
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
048 "Returns `true` unless `val` is `nil`, `false` or an empty sequence.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
049 Otherwise always 'false'; never any other value."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
050 [val]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="11 out of 11 forms covered">
|
||||||
|
051 (and (or val false) true))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
052
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
053
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
054 (defn inc-or-one
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
055 "If this `val` is a number, return that number incremented by one; otherwise,
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
056 return 1. TODO: should probably be in `utils`."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
057 [val]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
058 (if
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
059 (number? val)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
060 (inc val)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
061 1))
|
||||||
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -25,6 +25,17 @@
|
||||||
<td class="with-number">100.00 %</td>
|
<td class="with-number">100.00 %</td>
|
||||||
<td class="with-number">45</td><td class="with-number">5</td><td class="with-number">3</td>
|
<td class="with-number">45</td><td class="with-number">5</td><td class="with-number">3</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="cc/journeyman/the_great_game/buildings/module.clj.html">cc.journeyman.the-great-game.buildings.module</a></td><td class="with-bar"><div class="covered"
|
||||||
|
style="width:100.0%;
|
||||||
|
float:left;"> 2 </div></td>
|
||||||
|
<td class="with-number">100.00 %</td>
|
||||||
|
<td class="with-bar"><div class="covered"
|
||||||
|
style="width:100.0%;
|
||||||
|
float:left;"> 2 </div></td>
|
||||||
|
<td class="with-number">100.00 %</td>
|
||||||
|
<td class="with-number">81</td><td class="with-number">6</td><td class="with-number">2</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="cc/journeyman/the_great_game/buildings/rectangular.clj.html">cc.journeyman.the-great-game.buildings.rectangular</a></td><td class="with-bar"><div class="covered"
|
<td><a href="cc/journeyman/the_great_game/buildings/rectangular.clj.html">cc.journeyman.the-great-game.buildings.rectangular</a></td><td class="with-bar"><div class="covered"
|
||||||
style="width:74.64788732394366%;
|
style="width:74.64788732394366%;
|
||||||
|
@ -40,7 +51,7 @@
|
||||||
style="width:19.35483870967742%;
|
style="width:19.35483870967742%;
|
||||||
float:left;"> 6 </div></td>
|
float:left;"> 6 </div></td>
|
||||||
<td class="with-number">80.65 %</td>
|
<td class="with-number">80.65 %</td>
|
||||||
<td class="with-number">180</td><td class="with-number">25</td><td class="with-number">31</td>
|
<td class="with-number">150</td><td class="with-number">25</td><td class="with-number">31</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="cc/journeyman/the_great_game/gossip/gossip.clj.html">cc.journeyman.the-great-game.gossip.gossip</a></td><td class="with-bar"><div class="covered"
|
<td><a href="cc/journeyman/the_great_game/gossip/gossip.clj.html">cc.journeyman.the-great-game.gossip.gossip</a></td><td class="with-bar"><div class="covered"
|
||||||
|
@ -59,20 +70,20 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="cc/journeyman/the_great_game/gossip/news_items.clj.html">cc.journeyman.the-great-game.gossip.news-items</a></td><td class="with-bar"><div class="covered"
|
<td><a href="cc/journeyman/the_great_game/gossip/news_items.clj.html">cc.journeyman.the-great-game.gossip.news-items</a></td><td class="with-bar"><div class="covered"
|
||||||
style="width:68.92744479495268%;
|
style="width:77.15582450832072%;
|
||||||
float:left;"> 437 </div><div class="not-covered"
|
float:left;"> 510 </div><div class="not-covered"
|
||||||
style="width:31.07255520504732%;
|
style="width:22.844175491679273%;
|
||||||
float:left;"> 197 </div></td>
|
float:left;"> 151 </div></td>
|
||||||
<td class="with-number">68.93 %</td>
|
<td class="with-number">77.16 %</td>
|
||||||
<td class="with-bar"><div class="covered"
|
<td class="with-bar"><div class="covered"
|
||||||
style="width:63.07692307692308%;
|
style="width:72.66187050359713%;
|
||||||
float:left;"> 82 </div><div class="partial"
|
float:left;"> 101 </div><div class="partial"
|
||||||
style="width:7.6923076923076925%;
|
style="width:5.755395683453237%;
|
||||||
float:left;"> 10 </div><div class="not-covered"
|
float:left;"> 8 </div><div class="not-covered"
|
||||||
style="width:29.23076923076923%;
|
style="width:21.58273381294964%;
|
||||||
float:left;"> 38 </div></td>
|
float:left;"> 30 </div></td>
|
||||||
<td class="with-number">70.77 %</td>
|
<td class="with-number">78.42 %</td>
|
||||||
<td class="with-number">313</td><td class="with-number">36</td><td class="with-number">130</td>
|
<td class="with-number">345</td><td class="with-number">41</td><td class="with-number">139</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="cc/journeyman/the_great_game/holdings/holding.clj.html">cc.journeyman.the-great-game.holdings.holding</a></td><td class="with-bar"><div class="covered"
|
<td><a href="cc/journeyman/the_great_game/holdings/holding.clj.html">cc.journeyman.the-great-game.holdings.holding</a></td><td class="with-bar"><div class="covered"
|
||||||
|
@ -102,7 +113,7 @@
|
||||||
style="width:71.42857142857143%;
|
style="width:71.42857142857143%;
|
||||||
float:left;"> 10 </div></td>
|
float:left;"> 10 </div></td>
|
||||||
<td class="with-number">28.57 %</td>
|
<td class="with-number">28.57 %</td>
|
||||||
<td class="with-number">47</td><td class="with-number">8</td><td class="with-number">14</td>
|
<td class="with-number">45</td><td class="with-number">7</td><td class="with-number">14</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="cc/journeyman/the_great_game/merchants/markets.clj.html">cc.journeyman.the-great-game.merchants.markets</a></td><td class="with-bar"><div class="covered"
|
<td><a href="cc/journeyman/the_great_game/merchants/markets.clj.html">cc.journeyman.the-great-game.merchants.markets</a></td><td class="with-bar"><div class="covered"
|
||||||
|
@ -213,20 +224,20 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="cc/journeyman/the_great_game/playroom.clj.html">cc.journeyman.the-great-game.playroom</a></td><td class="with-bar"><div class="covered"
|
<td><a href="cc/journeyman/the_great_game/playroom.clj.html">cc.journeyman.the-great-game.playroom</a></td><td class="with-bar"><div class="covered"
|
||||||
style="width:86.05947955390334%;
|
style="width:56.92307692307692%;
|
||||||
float:left;"> 463 </div><div class="not-covered"
|
float:left;"> 222 </div><div class="not-covered"
|
||||||
style="width:13.940520446096654%;
|
style="width:43.07692307692308%;
|
||||||
float:left;"> 75 </div></td>
|
float:left;"> 168 </div></td>
|
||||||
<td class="with-number">86.06 %</td>
|
<td class="with-number">56.92 %</td>
|
||||||
<td class="with-bar"><div class="covered"
|
<td class="with-bar"><div class="covered"
|
||||||
style="width:80.0%;
|
style="width:23.529411764705884%;
|
||||||
float:left;"> 28 </div><div class="partial"
|
float:left;"> 4 </div><div class="partial"
|
||||||
style="width:14.285714285714286%;
|
style="width:17.647058823529413%;
|
||||||
float:left;"> 5 </div><div class="not-covered"
|
float:left;"> 3 </div><div class="not-covered"
|
||||||
style="width:5.714285714285714%;
|
style="width:58.8235294117647%;
|
||||||
float:left;"> 2 </div></td>
|
float:left;"> 10 </div></td>
|
||||||
<td class="with-number">94.29 %</td>
|
<td class="with-number">41.18 %</td>
|
||||||
<td class="with-number">72</td><td class="with-number">12</td><td class="with-number">35</td>
|
<td class="with-number">72</td><td class="with-number">12</td><td class="with-number">17</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="cc/journeyman/the_great_game/time.clj.html">cc.journeyman.the-great-game.time</a></td><td class="with-bar"><div class="covered"
|
<td><a href="cc/journeyman/the_great_game/time.clj.html">cc.journeyman.the-great-game.time</a></td><td class="with-bar"><div class="covered"
|
||||||
|
@ -247,18 +258,18 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="cc/journeyman/the_great_game/utils.clj.html">cc.journeyman.the-great-game.utils</a></td><td class="with-bar"><div class="covered"
|
<td><a href="cc/journeyman/the_great_game/utils.clj.html">cc.journeyman.the-great-game.utils</a></td><td class="with-bar"><div class="covered"
|
||||||
style="width:84.33734939759036%;
|
style="width:85.4368932038835%;
|
||||||
float:left;"> 70 </div><div class="not-covered"
|
float:left;"> 88 </div><div class="not-covered"
|
||||||
style="width:15.662650602409638%;
|
style="width:14.563106796116505%;
|
||||||
float:left;"> 13 </div></td>
|
float:left;"> 15 </div></td>
|
||||||
<td class="with-number">84.34 %</td>
|
<td class="with-number">85.44 %</td>
|
||||||
<td class="with-bar"><div class="covered"
|
<td class="with-bar"><div class="covered"
|
||||||
style="width:95.23809523809524%;
|
style="width:92.5925925925926%;
|
||||||
float:left;"> 20 </div><div class="not-covered"
|
float:left;"> 25 </div><div class="not-covered"
|
||||||
style="width:4.761904761904762%;
|
style="width:7.407407407407407%;
|
||||||
float:left;"> 1 </div></td>
|
float:left;"> 2 </div></td>
|
||||||
<td class="with-number">95.24 %</td>
|
<td class="with-number">92.59 %</td>
|
||||||
<td class="with-number">45</td><td class="with-number">5</td><td class="with-number">21</td>
|
<td class="with-number">61</td><td class="with-number">8</td><td class="with-number">27</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="cc/journeyman/the_great_game/world/heightmap.clj.html">cc.journeyman.the-great-game.world.heightmap</a></td><td class="with-bar"><div class="covered"
|
<td><a href="cc/journeyman/the_great_game/world/heightmap.clj.html">cc.journeyman.the-great-game.world.heightmap</a></td><td class="with-bar"><div class="covered"
|
||||||
|
@ -350,9 +361,9 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr><td>Totals:</td>
|
<tr><td>Totals:</td>
|
||||||
<td class="with-bar"></td>
|
<td class="with-bar"></td>
|
||||||
<td class="with-number">61.00 %</td>
|
<td class="with-number">58.91 %</td>
|
||||||
<td class="with-bar"></td>
|
<td class="with-bar"></td>
|
||||||
<td class="with-number">61.78 %</td>
|
<td class="with-number">61.63 %</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
23
project.clj
23
project.clj
|
@ -1,11 +1,18 @@
|
||||||
(defproject journeyman-cc/the-great-game "0.1.2-SNAPSHOT"
|
(defproject journeyman-cc/the-great-game "0.1.2-SNAPSHOT"
|
||||||
:cloverage {:output "docs/cloverage"}
|
:cloverage {:output "docs/cloverage"
|
||||||
:codox {:metadata {:doc "**TODO**: write docs"
|
:codecov? true
|
||||||
|
:emma-xml? true}
|
||||||
|
:codox {:froboz.cloverage {:output "docs/cloverage"
|
||||||
|
:codecov? true
|
||||||
|
:html? true
|
||||||
|
:debug? true}
|
||||||
|
:metadata {:doc "**TODO**: write docs"
|
||||||
:doc/format :markdown}
|
:doc/format :markdown}
|
||||||
:output-path "docs/codox"
|
:output-path "docs/codox"
|
||||||
:source-uri "https://github.com/simon-brooke/the-great-game/blob/master/{filepath}#L{line}"}
|
:source-uri "https://github.com/simon-brooke/the-great-game/blob/master/{filepath}#L{line}"}
|
||||||
:cucumber-feature-paths ["test/features/"]
|
:cucumber-feature-paths ["test/features/"]
|
||||||
:dependencies [[com.taoensso/timbre "5.1.2"]
|
:dependencies [;;[codox "0.10.7-cloverage"]
|
||||||
|
[com.taoensso/timbre "5.1.2"]
|
||||||
[environ "1.2.0"]
|
[environ "1.2.0"]
|
||||||
[jme-clj "0.1.13"]
|
[jme-clj "0.1.13"]
|
||||||
;; [jme3-core "3.4.0-stable"]
|
;; [jme3-core "3.4.0-stable"]
|
||||||
|
@ -16,12 +23,13 @@
|
||||||
[org.clojure/algo.generic "0.1.3"]
|
[org.clojure/algo.generic "0.1.3"]
|
||||||
[org.clojure/clojure "1.10.3"]
|
[org.clojure/clojure "1.10.3"]
|
||||||
[org.clojure/math.numeric-tower "0.0.4"]
|
[org.clojure/math.numeric-tower "0.0.4"]
|
||||||
]
|
[org.clojure/tools.namespace "1.0.0"]
|
||||||
|
[org.clojure/tools.reader "1.3.5"]]
|
||||||
:description "Prototype code towards the great game I've been writing about for ten years, and know I will never finish."
|
:description "Prototype code towards the great game I've been writing about for ten years, and know I will never finish."
|
||||||
:license {:name "GNU General Public License,version 2.0 or (at your option) any later version"
|
:license {:name "GNU General Public License,version 2.0 or (at your option) any later version"
|
||||||
:url "https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html"}
|
:url "https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html"}
|
||||||
:plugins [[lein-cloverage "1.1.1"]
|
:plugins [[lein-cloverage "1.2.2"]
|
||||||
[lein-codox "0.10.7"]
|
[lein-codox "0.10.7-cloverage"]
|
||||||
[lein-cucumber "1.0.2"]
|
[lein-cucumber "1.0.2"]
|
||||||
[lein-gorilla "0.4.0"]]
|
[lein-gorilla "0.4.0"]]
|
||||||
|
|
||||||
|
@ -38,5 +46,4 @@
|
||||||
["change" "version" "leiningen.release/bump-version"]
|
["change" "version" "leiningen.release/bump-version"]
|
||||||
["vcs" "commit"]]
|
["vcs" "commit"]]
|
||||||
|
|
||||||
:url "https://github.com/simon-brooke/the-great-game"
|
:url "https://github.com/simon-brooke/the-great-game")
|
||||||
)
|
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
(ns cc.journeyman.the-great-game.gossip.news-items
|
(ns cc.journeyman.the-great-game.gossip.news-items
|
||||||
"Using news items (propositions) to transfer knowledge between gossip agents.
|
"Using news items (propositions) to transfer knowledge between gossip agents.
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
What is here is essentially working. It's not, however, working with the
|
||||||
|
rich data objects which will be needed, and it's not yet nearly efficient
|
||||||
|
enough, but it allows knowledge to propagate through the world procedurally,
|
||||||
|
at a rate limited by the speed of movement of the gossip agents.
|
||||||
|
|
||||||
|
## Discussion
|
||||||
|
|
||||||
The ideas here are based on the essay [The spread of knowledge in a large
|
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.;
|
game world](The-spread-of-knowledge-in-a-large-game-world.html), q.v.;
|
||||||
they've advanced a little beyond that and will doubtless
|
they've advanced a little beyond that and will doubtless
|
||||||
|
@ -8,7 +17,7 @@
|
||||||
|
|
||||||
A news item is a map with the keys:
|
A news item is a map with the keys:
|
||||||
|
|
||||||
* `date` - the date on which the reported event happened;
|
* `date` - the date on which the reported event is claimed to have happened;
|
||||||
* `nth-hand` - the number of agents the news item has passed through;
|
* `nth-hand` - the number of agents the news item has passed through;
|
||||||
* `verb` - what it is that happened (key into `news-topics`);
|
* `verb` - what it is that happened (key into `news-topics`);
|
||||||
|
|
||||||
|
@ -23,9 +32,9 @@
|
||||||
proposition is offered. This is woefully inefficient. "
|
proposition is offered. This is woefully inefficient. "
|
||||||
(:require [cc.journeyman.the-great-game.world.location :refer [distance-between]]
|
(: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]]
|
||||||
|
[cc.journeyman.the-great-game.utils :refer [inc-or-one truthy?]]
|
||||||
[taoensso.timbre :as l]))
|
[taoensso.timbre :as l]))
|
||||||
|
|
||||||
|
|
||||||
(def news-topics
|
(def news-topics
|
||||||
"Topics of interest to gossip agents. Topics are keyed in this map by
|
"Topics of interest to gossip agents. Topics are keyed in this map by
|
||||||
their `verbs`. The `keys` associated with each topic are the extra pieces
|
their `verbs`. The `keys` associated with each topic are the extra pieces
|
||||||
|
@ -40,9 +49,7 @@
|
||||||
action;
|
action;
|
||||||
* `price` is special to buy/sell, but of significant interest to merchants.
|
* `price` is special to buy/sell, but of significant interest to merchants.
|
||||||
|
|
||||||
## Notes
|
## Characters
|
||||||
|
|
||||||
### Characters
|
|
||||||
|
|
||||||
*TODO* but note that at most all the receiver can learn about a character
|
*TODO* but note that at most all the receiver can learn about a character
|
||||||
from a news item is what the giver knows about that character, degraded by
|
from a news item is what the giver knows about that character, degraded by
|
||||||
|
@ -56,7 +63,7 @@
|
||||||
as the receiver stores only that segment which the receiver finds
|
as the receiver stores only that segment which the receiver finds
|
||||||
interesting.
|
interesting.
|
||||||
|
|
||||||
### Locations
|
## Locations
|
||||||
|
|
||||||
A 'location' value is a list comprising at most the x/y coordinate location
|
A 'location' value is a list comprising at most the x/y coordinate location
|
||||||
and the ids of the settlement and region (possibly hierarchically) that contain
|
and the ids of the settlement and region (possibly hierarchically) that contain
|
||||||
|
@ -66,12 +73,11 @@
|
||||||
|
|
||||||
It is assumed that the `:home` of a character is a location in this sense.
|
It is assumed that the `:home` of a character is a location in this sense.
|
||||||
|
|
||||||
### Inferences
|
## Inferences
|
||||||
|
|
||||||
If an agent learns that Adam has married Betty, they can infer that Betty has
|
If an agent learns that Adam has married Betty, they can infer that Betty has
|
||||||
married Adam; if they learn that Charles killed Dorothy, that Dorothy has died.
|
married Adam; if they learn that Charles killed Dorothy, that Dorothy has died.
|
||||||
I'm not convinced that my representation of inferences here is ideal.
|
I'm not convinced that my representation of inferences here is ideal."
|
||||||
"
|
|
||||||
{;; A significant attack is interesting whether or not it leads to deaths
|
{;; A significant attack is interesting whether or not it leads to deaths
|
||||||
:attack {:verb :attack :keys [:actor :other :location]}
|
:attack {:verb :attack :keys [:actor :other :location]}
|
||||||
;; Deaths of characters may be interesting
|
;; Deaths of characters may be interesting
|
||||||
|
@ -95,7 +101,7 @@
|
||||||
{:verb :sex}
|
{:verb :sex}
|
||||||
{:verb :sex :actor :other :other :actor}]}
|
{:verb :sex :actor :other :other :actor}]}
|
||||||
;; Merchants, especially, are interested in prices in other markets
|
;; Merchants, especially, are interested in prices in other markets
|
||||||
:sell {:verb :sell :keys [:actor :other :object :location :price]}
|
:sell {:verb :sell :keys [:actor :other :object :location :quantity :price]}
|
||||||
;; Sex can juicy gossip, although not normally if the participants are in an
|
;; Sex can juicy gossip, although not normally if the participants are in an
|
||||||
;; established sexual relationship.
|
;; established sexual relationship.
|
||||||
:sex {:verb :sex :keys [:actor :other :location]
|
:sex {:verb :sex :keys [:actor :other :location]
|
||||||
|
@ -110,6 +116,11 @@
|
||||||
:inferences [{:verb :war :actor :other :other :actor}]}})
|
:inferences [{:verb :war :actor :other :other :actor}]}})
|
||||||
|
|
||||||
|
|
||||||
|
(def all-known-verbs
|
||||||
|
"All verbs currently known to the gossip system."
|
||||||
|
(set (keys news-topics)))
|
||||||
|
|
||||||
|
|
||||||
(defn interest-in-character
|
(defn interest-in-character
|
||||||
"Integer representation of how interesting this `character` is to this
|
"Integer representation of how interesting this `character` is to this
|
||||||
`gossip`.
|
`gossip`.
|
||||||
|
@ -118,8 +129,11 @@
|
||||||
[gossip character]
|
[gossip character]
|
||||||
(count
|
(count
|
||||||
(concat
|
(concat
|
||||||
(filter #(= (:actor % character)) (:knowledge gossip))
|
;; TODO: we ought also check the relationships of the gossip.
|
||||||
(filter #(= (:other % character)) (:knowledge gossip)))))
|
;; Are relationships just propositions in the knowledge base?
|
||||||
|
(filter #(= (:actor %) character) (:knowledge gossip))
|
||||||
|
(filter #(= (:other %) character) (:knowledge gossip)))))
|
||||||
|
|
||||||
|
|
||||||
(defn interesting-character?
|
(defn interesting-character?
|
||||||
"Boolean representation of whether this `character` is interesting to this
|
"Boolean representation of whether this `character` is interesting to this
|
||||||
|
@ -135,10 +149,13 @@
|
||||||
(and (map? location) (number? (:x location)) (number? (:y location)))
|
(and (map? location) (number? (:x location)) (number? (:y location)))
|
||||||
(if-let [home (:home gossip)]
|
(if-let [home (:home gossip)]
|
||||||
(let [d (distance-between location home)
|
(let [d (distance-between location home)
|
||||||
i (/ 10000 d) ;; 10000 at metre scale is 10km; interest should
|
i (if
|
||||||
|
(zero? d) 1
|
||||||
|
(/ 10000 d))
|
||||||
|
;; 10000 at metre scale is 10km; interest should
|
||||||
;;fall off with distance from home, but possibly on a log scale
|
;;fall off with distance from home, but possibly on a log scale
|
||||||
]
|
]
|
||||||
(if (> i 1) i 0))
|
(if (>= i 1) i 0))
|
||||||
0)
|
0)
|
||||||
(coll? location)
|
(coll? location)
|
||||||
(reduce
|
(reduce
|
||||||
|
@ -152,6 +169,7 @@
|
||||||
#(some (fn [x] (= x location)) (:location %))
|
#(some (fn [x] (= x location)) (:location %))
|
||||||
(cons {:location (:home gossip)} (:knowledge gossip))))))
|
(cons {:location (:home gossip)} (:knowledge gossip))))))
|
||||||
|
|
||||||
|
;; (distance-between {:x 25 :y 37} {:x 25 :y 37})
|
||||||
;; (interest-in-location {:home [{0, 0} :test-home] :knowledge []} [:test-home])
|
;; (interest-in-location {:home [{0, 0} :test-home] :knowledge []} [:test-home])
|
||||||
|
|
||||||
(defn interesting-location?
|
(defn interesting-location?
|
||||||
|
@ -169,6 +187,17 @@
|
||||||
;; TODO: Not yet (really) implemented
|
;; TODO: Not yet (really) implemented
|
||||||
true)
|
true)
|
||||||
|
|
||||||
|
(defn interesting-verb?
|
||||||
|
"Is this `verb` interesting to this `gossip`?"
|
||||||
|
[gossip verb]
|
||||||
|
(let [vs (:interesting-verbs gossip)]
|
||||||
|
(truthy?
|
||||||
|
(if (set? vs)
|
||||||
|
(vs verb)
|
||||||
|
false))))
|
||||||
|
|
||||||
|
;; (interesting-verb? {:interesting-verbs #{:kill :sell}} :sell)
|
||||||
|
|
||||||
(defn compatible-value?
|
(defn compatible-value?
|
||||||
"True if `known-value` is the same as `new-value`, or, for each key present
|
"True if `known-value` is the same as `new-value`, or, for each key present
|
||||||
in `new-value`, has the same value for that key.
|
in `new-value`, has the same value for that key.
|
||||||
|
@ -191,16 +220,14 @@
|
||||||
learning that 'someone killed Sweet Daisy', but there is point in learning
|
learning that 'someone killed Sweet Daisy', but there is point in learning
|
||||||
'someone killed Sweet Daisy _with poison_'."
|
'someone killed Sweet Daisy _with poison_'."
|
||||||
[new-item known-item]
|
[new-item known-item]
|
||||||
(if
|
(truthy?
|
||||||
(reduce
|
(reduce
|
||||||
#(and %1 %2)
|
#(and %1 %2)
|
||||||
(map #(if
|
(map #(if
|
||||||
(known-item %) ;; if known-item has this key
|
(known-item %) ;; if known-item has this key
|
||||||
(compatible-value? (new-item %) (known-item %))
|
(compatible-value? (new-item %) (known-item %))
|
||||||
true)
|
true)
|
||||||
(remove #{:nth-hand :confidence :learned-from} (keys new-item))))
|
(remove #{:nth-hand :confidence :learned-from} (keys new-item))))))
|
||||||
true
|
|
||||||
false))
|
|
||||||
|
|
||||||
(defn known-item?
|
(defn known-item?
|
||||||
"True if this news `item` is already known to this `gossip`.
|
"True if this news `item` is already known to this `gossip`.
|
||||||
|
@ -209,18 +236,17 @@
|
||||||
the same _or more specific_ values for all the keys of this `item` except
|
the same _or more specific_ values for all the keys of this `item` except
|
||||||
`:nth-hand`, `:confidence` and `:learned-from`."
|
`:nth-hand`, `:confidence` and `:learned-from`."
|
||||||
[gossip item]
|
[gossip item]
|
||||||
(if
|
(truthy?
|
||||||
(reduce
|
(reduce
|
||||||
#(or %1 %2)
|
#(or %1 %2)
|
||||||
false
|
false
|
||||||
(filter true? (map #(compatible-item? item %) (:knowledge gossip))))
|
(filter true? (map #(compatible-item? item %) (:knowledge gossip))))))
|
||||||
true
|
|
||||||
false))
|
|
||||||
|
|
||||||
(defn interesting-item?
|
(defn interesting-item?
|
||||||
"True if anything about this news `item` is interesting to this `gossip`."
|
"True if anything about this news `item` is interesting to this `gossip`."
|
||||||
[gossip item]
|
[gossip item]
|
||||||
(and (not (known-item? gossip item))
|
(and (not (known-item? gossip item))
|
||||||
|
(interesting-verb? gossip item) ;; news is only interesting if the topic is.
|
||||||
(or
|
(or
|
||||||
(interesting-character? gossip (:actor item))
|
(interesting-character? gossip (:actor item))
|
||||||
(interesting-character? gossip (:other item))
|
(interesting-character? gossip (:other item))
|
||||||
|
@ -228,15 +254,6 @@
|
||||||
(interesting-object? gossip (:object item))
|
(interesting-object? gossip (:object item))
|
||||||
(interesting-topic? gossip (:verb 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
|
(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]
|
[item rule]
|
||||||
|
@ -281,15 +298,9 @@
|
||||||
location))]
|
location))]
|
||||||
(when-not (empty? l) l)))
|
(when-not (empty? l) l)))
|
||||||
|
|
||||||
(defn learn-news-item
|
(defn degrade-news-item
|
||||||
"Return a gossip like this `gossip`, which has learned this news `item` if
|
[gossip item]
|
||||||
it is of interest to them."
|
(assoc
|
||||||
([gossip item]
|
|
||||||
(learn-news-item gossip item true))
|
|
||||||
([gossip item follow-inferences?]
|
|
||||||
(if
|
|
||||||
(interesting-item? gossip item)
|
|
||||||
(let [item' (assoc
|
|
||||||
item
|
item
|
||||||
:nth-hand (inc-or-one (:nth-hand item))
|
:nth-hand (inc-or-one (:nth-hand item))
|
||||||
:time-stamp (if
|
:time-stamp (if
|
||||||
|
@ -302,7 +313,20 @@
|
||||||
;; TODO: do something to degrade confidence in the item,
|
;; TODO: do something to degrade confidence in the item,
|
||||||
;; probably as a function of the provider's confidence in
|
;; probably as a function of the provider's confidence in
|
||||||
;; the item and the gossip's trust in the provider
|
;; the item and the gossip's trust in the provider
|
||||||
)
|
))
|
||||||
|
|
||||||
|
;; (degrade-news-item {:home [{:x 25 :y 37} :auchencairn :scotland]}
|
||||||
|
;; {:verb :marry :actor :adam :other :belinda :location [{:x 25 :y 37} :auchencairn :scotland]})
|
||||||
|
|
||||||
|
(defn learn-news-item
|
||||||
|
"Return a gossip like this `gossip`, which has learned this news `item` if
|
||||||
|
it is of interest to them."
|
||||||
|
([gossip item]
|
||||||
|
(learn-news-item gossip item true))
|
||||||
|
([gossip item follow-inferences?]
|
||||||
|
(if
|
||||||
|
(interesting-item? gossip item)
|
||||||
|
(let [item' (degrade-news-item gossip item)
|
||||||
g (assoc
|
g (assoc
|
||||||
gossip
|
gossip
|
||||||
:knowledge
|
:knowledge
|
||||||
|
@ -313,7 +337,7 @@
|
||||||
(assoc
|
(assoc
|
||||||
g
|
g
|
||||||
:knowledge
|
:knowledge
|
||||||
(concat (:knowledge g) (make-all-inferences item)))
|
(concat (:knowledge g) (make-all-inferences item')))
|
||||||
g)))
|
g)))
|
||||||
gossip))
|
gossip))
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
:init init
|
:init init
|
||||||
:update simple-update)
|
:update simple-update)
|
||||||
|
|
||||||
(start app)
|
;; (start app)
|
||||||
|
|
||||||
;; Reinitialises the running app
|
;; Reinitialises the running app
|
||||||
;;(run app
|
;;(run app
|
||||||
|
@ -45,28 +45,28 @@
|
||||||
|
|
||||||
;; By default, there is a Fly Camera attached to the app that you can control with W, A, S and D keys.
|
;; By default, there is a Fly Camera attached to the app that you can control with W, A, S and D keys.
|
||||||
;; Let's increase its movement speed. Now, you fly faster :)
|
;; Let's increase its movement speed. Now, you fly faster :)
|
||||||
(run app
|
;; (run app
|
||||||
(set* (fly-cam) :move-speed 15))
|
;; (set* (fly-cam) :move-speed 15))
|
||||||
|
|
||||||
|
|
||||||
;; Updates the app
|
;; Updates the app
|
||||||
(run app
|
;; (run app
|
||||||
(let [{:keys [cube]} (get-state)]
|
;; (let [{:keys [cube]} (get-state)]
|
||||||
(set* cube :local-translation (add (get* cube :local-translation) 1 1 1))))
|
;; (set* cube :local-translation (add (get* cube :local-translation) 1 1 1))))
|
||||||
|
|
||||||
;; Updates the app adding a second cube
|
;; Updates the app adding a second cube
|
||||||
(run app
|
;; (run app
|
||||||
(let [cube (geo "jMonkey cube" (box 1 1 1))
|
;; (let [cube (geo "jMonkey cube" (box 1 1 1))
|
||||||
mat (unshaded-mat)]
|
;; mat (unshaded-mat)]
|
||||||
(set* mat :texture "ColorMap" (load-texture "textures/Monkey.jpg"))
|
;; (set* mat :texture "ColorMap" (load-texture "textures/Monkey.jpg"))
|
||||||
(setc cube
|
;; (setc cube
|
||||||
:material mat
|
;; :material mat
|
||||||
:local-translation [-3 0 0])
|
;; :local-translation [-3 0 0])
|
||||||
(add-to-root cube)
|
;; (add-to-root cube)
|
||||||
(set-state :cube2 cube)))
|
;; (set-state :cube2 cube)))
|
||||||
|
|
||||||
;; We added the new cube, but it's not rotating. We need to update the simple-update fn.
|
;; We added the new cube, but it's not rotating. We need to update the simple-update fn.
|
||||||
(defn simple-update [tpf]
|
;; (defn simple-update [tpf]
|
||||||
(let [{:keys [cube cube2]} (get-state)]
|
;; (let [{:keys [cube cube2]} (get-state)]
|
||||||
(rotate cube 0 (* 2 tpf) 0)
|
;; (rotate cube 0 (* 2 tpf) 0)
|
||||||
(rotate cube2 0 (* 2 tpf) 0)))
|
;; (rotate cube2 0 (* 2 tpf) 0)))
|
||||||
|
|
|
@ -43,3 +43,19 @@
|
||||||
;; (value-or-default {:x 0 :y 0 :altitude 7} :altitude 8)
|
;; (value-or-default {:x 0 :y 0 :altitude 7} :altitude 8)
|
||||||
;; (value-or-default {:x 0 :y 0 :altitude 7} :alt 8)
|
;; (value-or-default {:x 0 :y 0 :altitude 7} :alt 8)
|
||||||
;; (value-or-default nil :altitude 8)
|
;; (value-or-default nil :altitude 8)
|
||||||
|
|
||||||
|
(defn truthy?
|
||||||
|
"Returns `true` unless `val` is `nil`, `false` or an empty sequence.
|
||||||
|
Otherwise always 'false'; never any other value."
|
||||||
|
[val]
|
||||||
|
(and (or val false) true))
|
||||||
|
|
||||||
|
|
||||||
|
(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))
|
||||||
|
|
|
@ -1,8 +1,49 @@
|
||||||
(ns cc.journeyman.the-great-game.gossip.news-items-test
|
(ns cc.journeyman.the-great-game.gossip.news-items-test
|
||||||
(:require [clojure.test :refer [deftest is testing]]
|
(:require [clojure.test :refer [deftest is testing]]
|
||||||
[cc.journeyman.the-great-game.gossip.news-items :refer
|
[cc.journeyman.the-great-game.gossip.news-items :refer
|
||||||
[compatible-item? degrade-location infer interest-in-location interesting-location?
|
[all-known-verbs compatible-item? degrade-location infer
|
||||||
learn-news-item make-all-inferences]]))
|
interest-in-character interesting-character? interest-in-location
|
||||||
|
interesting-location? learn-news-item make-all-inferences]]))
|
||||||
|
|
||||||
|
(deftest interesting-character-tests
|
||||||
|
(testing "To what degree characters are of interest to the gossip"
|
||||||
|
(let [expected 1
|
||||||
|
gossip {:home [{0, 0} :test-home]
|
||||||
|
:interesting-verbs all-known-verbs
|
||||||
|
;; already knows about adam
|
||||||
|
:knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}]}
|
||||||
|
actual (interest-in-character
|
||||||
|
gossip
|
||||||
|
:adam)]
|
||||||
|
(is (= actual expected)))
|
||||||
|
(let [expected 0
|
||||||
|
gossip {:home [{0, 0} :test-home]
|
||||||
|
:interesting-verbs all-known-verbs
|
||||||
|
;; already knows about adam
|
||||||
|
:knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}]}
|
||||||
|
actual (interest-in-character
|
||||||
|
gossip
|
||||||
|
:dorothy)]
|
||||||
|
(is (= actual expected))))
|
||||||
|
(testing "Whether characters are of interest to the gossip"
|
||||||
|
(let [expected true
|
||||||
|
gossip {:home [{0, 0} :test-home]
|
||||||
|
:interesting-verbs all-known-verbs
|
||||||
|
;; already knows about adam
|
||||||
|
:knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}]}
|
||||||
|
actual (interesting-character?
|
||||||
|
gossip
|
||||||
|
:adam)]
|
||||||
|
(is (= actual expected)))
|
||||||
|
(let [expected false
|
||||||
|
gossip {:home [{0, 0} :test-home]
|
||||||
|
:interesting-verbs all-known-verbs
|
||||||
|
;; already knows about adam
|
||||||
|
:knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}]}
|
||||||
|
actual (interesting-character?
|
||||||
|
gossip
|
||||||
|
:dorothy)]
|
||||||
|
(is (= actual expected)))))
|
||||||
|
|
||||||
(deftest compatible-item-test
|
(deftest compatible-item-test
|
||||||
(testing "Compatible item: items are identical"
|
(testing "Compatible item: items are identical"
|
||||||
|
@ -128,17 +169,17 @@
|
||||||
|
|
||||||
(deftest inference-tests
|
(deftest inference-tests
|
||||||
(testing "Ability to infer new knowledge from news items: single rule tests"
|
(testing "Ability to infer new knowledge from news items: single rule tests"
|
||||||
(let [expected {:verb :marry, :actor :belinda, :other :adam}
|
(let [expected {:verb :marry, :actor :belinda, :other :adam, :nth-hand 1}
|
||||||
item {:verb :marry :actor :adam :other :belinda}
|
item {:verb :marry :actor :adam :other :belinda}
|
||||||
rule {:verb :marry :actor :other :other :actor}
|
rule {:verb :marry :actor :other :other :actor}
|
||||||
actual (infer item rule)]
|
actual (infer item rule)]
|
||||||
(is (= actual expected)))
|
(is (= actual expected)))
|
||||||
(let [expected {:verb :attack, :actor :adam, :other :belinda}
|
(let [expected {:verb :attack, :actor :adam, :other :belinda, :nth-hand 1}
|
||||||
item {:verb :rape :actor :adam :other :belinda}
|
item {:verb :rape :actor :adam :other :belinda}
|
||||||
rule {:verb :attack}
|
rule {:verb :attack}
|
||||||
actual (infer item rule)]
|
actual (infer item rule)]
|
||||||
(is (= actual expected)))
|
(is (= actual expected)))
|
||||||
(let [expected {:verb :sex, :actor :belinda, :other :adam}
|
(let [expected {:verb :sex, :actor :belinda, :other :adam, :nth-hand 1}
|
||||||
item {:verb :rape :actor :adam :other :belinda}
|
item {:verb :rape :actor :adam :other :belinda}
|
||||||
rule {:verb :sex :actor :other :other :actor}
|
rule {:verb :sex :actor :other :other :actor}
|
||||||
actual (infer item rule)]
|
actual (infer item rule)]
|
||||||
|
@ -149,15 +190,22 @@
|
||||||
{:verb :attack, :actor :adam, :other :belinda, :location :test-home, :nth-hand 1}}
|
{:verb :attack, :actor :adam, :other :belinda, :location :test-home, :nth-hand 1}}
|
||||||
;; dates will not be and cannot be expected to be equal
|
;; dates will not be and cannot be expected to be equal
|
||||||
actual (set (make-all-inferences
|
actual (set (make-all-inferences
|
||||||
{:verb :rape :actor :adam :other :belinda :location :test-home :nth-hand 1}))]
|
{:verb :rape :actor :adam :other :belinda :location :test-home}))]
|
||||||
(is (= actual expected)))))
|
(is (= actual expected)))))
|
||||||
|
|
||||||
(deftest learn-tests
|
(deftest learn-tests
|
||||||
(testing "Learning from an interesting news item."
|
(testing "Learning from an interesting news item."
|
||||||
(let [expected {:home [{0 0} :test-home]
|
(let [expected {:home [{0 0} :test-home]
|
||||||
:knowledge [{:verb :sex, :actor :adam, :other :belinda, :location [:test-home], :nth-hand 1}
|
:interesting-verbs all-known-verbs
|
||||||
|
:knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}
|
||||||
|
{:verb :sex, :actor :adam, :other :belinda, :location [:test-home], :nth-hand 1}
|
||||||
{:verb :sex, :actor :belinda, :other :adam, :location [:test-home], :nth-hand 1}]}
|
{:verb :sex, :actor :belinda, :other :adam, :location [:test-home], :nth-hand 1}]}
|
||||||
|
gossip {:home [{0, 0} :test-home]
|
||||||
|
:interesting-verbs all-known-verbs
|
||||||
|
;; already knows about adam
|
||||||
|
:knowledge [{:verb :sell :actor :adam :other :charles :object :wheat :quantity 10 :price 5 :location [:test-home]}]}
|
||||||
actual (learn-news-item
|
actual (learn-news-item
|
||||||
{:home [{0, 0} :test-home] :knowledge []}
|
gossip
|
||||||
{:verb :sex :actor :adam :other :belinda :location [:test-home]})]
|
{:verb :sex :actor :adam :other :belinda :location [:test-home]})]
|
||||||
(is (= actual expected)))))
|
(is (= actual expected)))))
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,31 @@
|
||||||
{
|
{
|
||||||
"folders": [
|
"folders": [
|
||||||
{
|
{
|
||||||
"path": "."
|
"path": "../GreatGameTerrain"
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "../gossip"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "../walkmap"
|
"path": "../walkmap"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "../genbuildings"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "../GreatGameTerrain"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "../jme-clj"
|
"path": "../jme-clj"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "../codox"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../cloverage"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "../MicroWorld/mw-engine"
|
"path": "../MicroWorld/mw-engine"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../test-graphs"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"settings": {}
|
"settings": {
|
||||||
|
"java.configuration.updateBuildConfiguration": "automatic"
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue