drainage/flow-world-nr now works; drainage/flow-world still doesn't

This commit is contained in:
Simon Brooke 2024-04-06 09:41:52 +01:00
parent 93dab8067b
commit e19ce2e5f7
17 changed files with 1540 additions and 815 deletions

View file

@ -16,20 +16,20 @@
</tr></thead>
<tr>
<td><a href="mw_engine/core.clj.html">mw-engine.core</a></td><td class="with-bar"><div class="covered"
style="width:33.116883116883116%;
float:left;"> 51 </div><div class="not-covered"
style="width:66.88311688311688%;
float:left;"> 103 </div></td>
<td class="with-number">33.12 %</td>
style="width:37.185929648241206%;
float:left;"> 74 </div><div class="not-covered"
style="width:62.814070351758794%;
float:left;"> 125 </div></td>
<td class="with-number">37.19 %</td>
<td class="with-bar"><div class="covered"
style="width:36.36363636363637%;
float:left;"> 12 </div><div class="partial"
style="width:3.0303030303030303%;
style="width:50.0%;
float:left;"> 26 </div><div class="partial"
style="width:1.9230769230769231%;
float:left;"> 1 </div><div class="not-covered"
style="width:60.60606060606061%;
float:left;"> 20 </div></td>
<td class="with-number">39.39 %</td>
<td class="with-number">115</td><td class="with-number">15</td><td class="with-number">33</td>
style="width:48.07692307692308%;
float:left;"> 25 </div></td>
<td class="with-number">51.92 %</td>
<td class="with-number">145</td><td class="with-number">13</td><td class="with-number">52</td>
</tr>
<tr>
<td><a href="mw_engine/display.clj.html">mw-engine.display</a></td><td class="with-bar"><div class="covered"
@ -63,37 +63,37 @@
</tr>
<tr>
<td><a href="mw_engine/flow.clj.html">mw-engine.flow</a></td><td class="with-bar"><div class="covered"
style="width:86.62790697674419%;
float:left;"> 447 </div><div class="not-covered"
style="width:13.372093023255815%;
float:left;"> 69 </div></td>
<td class="with-number">86.63 %</td>
style="width:77.65957446808511%;
float:left;"> 511 </div><div class="not-covered"
style="width:22.340425531914892%;
float:left;"> 147 </div></td>
<td class="with-number">77.66 %</td>
<td class="with-bar"><div class="covered"
style="width:85.45454545454545%;
float:left;"> 47 </div><div class="partial"
style="width:7.2727272727272725%;
float:left;"> 4 </div><div class="not-covered"
style="width:7.2727272727272725%;
float:left;"> 4 </div></td>
<td class="with-number">92.73 %</td>
<td class="with-number">141</td><td class="with-number">15</td><td class="with-number">55</td>
style="width:67.5%;
float:left;"> 54 </div><div class="partial"
style="width:10.0%;
float:left;"> 8 </div><div class="not-covered"
style="width:22.5%;
float:left;"> 18 </div></td>
<td class="with-number">77.50 %</td>
<td class="with-number">179</td><td class="with-number">18</td><td class="with-number">80</td>
</tr>
<tr>
<td><a href="mw_engine/heightmap.clj.html">mw-engine.heightmap</a></td><td class="with-bar"><div class="covered"
style="width:92.51700680272108%;
float:left;"> 136 </div><div class="not-covered"
style="width:7.482993197278912%;
style="width:92.71523178807946%;
float:left;"> 140 </div><div class="not-covered"
style="width:7.28476821192053%;
float:left;"> 11 </div></td>
<td class="with-number">92.52 %</td>
<td class="with-number">92.72 %</td>
<td class="with-bar"><div class="covered"
style="width:90.9090909090909%;
float:left;"> 40 </div><div class="partial"
style="width:4.545454545454546%;
style="width:91.30434782608695%;
float:left;"> 42 </div><div class="partial"
style="width:4.3478260869565215%;
float:left;"> 2 </div><div class="not-covered"
style="width:4.545454545454546%;
style="width:4.3478260869565215%;
float:left;"> 2 </div></td>
<td class="with-number">95.45 %</td>
<td class="with-number">127</td><td class="with-number">11</td><td class="with-number">44</td>
<td class="with-number">95.65 %</td>
<td class="with-number">133</td><td class="with-number">12</td><td class="with-number">46</td>
</tr>
<tr>
<td><a href="mw_engine/natural_rules.clj.html">mw-engine.natural-rules</a></td><td class="with-bar"><div class="covered"
@ -113,44 +113,59 @@
<td class="with-number">184</td><td class="with-number">14</td><td class="with-number">106</td>
</tr>
<tr>
<td><a href="mw_engine/utils.clj.html">mw-engine.utils</a></td><td class="with-bar"><div class="covered"
style="width:69.88847583643123%;
float:left;"> 376 </div><div class="not-covered"
style="width:30.111524163568774%;
float:left;"> 162 </div></td>
<td class="with-number">69.89 %</td>
<td><a href="mw_engine/render.clj.html">mw-engine.render</a></td><td class="with-bar"><div class="covered"
style="width:6.875%;
float:left;"> 11 </div><div class="not-covered"
style="width:93.125%;
float:left;"> 149 </div></td>
<td class="with-number">6.88 %</td>
<td class="with-bar"><div class="covered"
style="width:73.21428571428571%;
float:left;"> 82 </div><div class="partial"
style="width:0.8928571428571429%;
style="width:27.77777777777778%;
float:left;"> 10 </div><div class="not-covered"
style="width:72.22222222222223%;
float:left;"> 26 </div></td>
<td class="with-number">27.78 %</td>
<td class="with-number">98</td><td class="with-number">11</td><td class="with-number">36</td>
</tr>
<tr>
<td><a href="mw_engine/utils.clj.html">mw-engine.utils</a></td><td class="with-bar"><div class="covered"
style="width:65.87395957193817%;
float:left;"> 554 </div><div class="not-covered"
style="width:34.126040428061835%;
float:left;"> 287 </div></td>
<td class="with-number">65.87 %</td>
<td class="with-bar"><div class="covered"
style="width:64.93506493506493%;
float:left;"> 100 </div><div class="partial"
style="width:0.6493506493506493%;
float:left;"> 1 </div><div class="not-covered"
style="width:25.892857142857142%;
float:left;"> 29 </div></td>
<td class="with-number">74.11 %</td>
<td class="with-number">301</td><td class="with-number">35</td><td class="with-number">112</td>
style="width:34.41558441558441%;
float:left;"> 53 </div></td>
<td class="with-number">65.58 %</td>
<td class="with-number">379</td><td class="with-number">41</td><td class="with-number">154</td>
</tr>
<tr>
<td><a href="mw_engine/world.clj.html">mw-engine.world</a></td><td class="with-bar"><div class="covered"
style="width:54.310344827586206%;
float:left;"> 63 </div><div class="not-covered"
style="width:45.689655172413794%;
float:left;"> 53 </div></td>
<td class="with-number">54.31 %</td>
style="width:34.57446808510638%;
float:left;"> 65 </div><div class="not-covered"
style="width:65.42553191489361%;
float:left;"> 123 </div></td>
<td class="with-number">34.57 %</td>
<td class="with-bar"><div class="covered"
style="width:42.30769230769231%;
float:left;"> 11 </div><div class="partial"
style="width:3.8461538461538463%;
style="width:33.333333333333336%;
float:left;"> 13 </div><div class="partial"
style="width:2.5641025641025643%;
float:left;"> 1 </div><div class="not-covered"
style="width:53.84615384615385%;
float:left;"> 14 </div></td>
<td class="with-number">46.15 %</td>
<td class="with-number">89</td><td class="with-number">12</td><td class="with-number">26</td>
style="width:64.1025641025641%;
float:left;"> 25 </div></td>
<td class="with-number">35.90 %</td>
<td class="with-number">111</td><td class="with-number">14</td><td class="with-number">39</td>
</tr>
<tr><td>Totals:</td>
<td class="with-bar"></td>
<td class="with-number">46.89 %</td>
<td class="with-number">45.14 %</td>
<td class="with-bar"></td>
<td class="with-number">57.73 %</td>
<td class="with-number">54.18 %</td>
</tr>
</table>
</body>

View file

@ -77,277 +77,367 @@
024&nbsp;&nbsp;&nbsp;mw-engine.core
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[mw-engine.utils&nbsp;:refer&nbsp;[get-int-or-zero&nbsp;map-world]]
025&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[mw-engine.flow&nbsp;:refer&nbsp;[flow-world]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[taoensso.timbre&nbsp;:as&nbsp;l]))
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[mw-engine.utils&nbsp;:refer&nbsp;[add-history-event&nbsp;get-int-or-zero&nbsp;map-world&nbsp;rule-type]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[taoensso.timbre&nbsp;:as&nbsp;l]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
027&nbsp;&nbsp;
028&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
029&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;;;;;
030&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;;;;;&nbsp;mw-engine:&nbsp;the&nbsp;state&#x2F;transition&nbsp;engine&nbsp;of&nbsp;MicroWorld.
031&nbsp;&nbsp;;;;;&nbsp;mw-engine:&nbsp;the&nbsp;state&#x2F;transition&nbsp;engine&nbsp;of&nbsp;MicroWorld.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;;;;;
032&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
033&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
034&nbsp;&nbsp;;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
035&nbsp;&nbsp;;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
036&nbsp;&nbsp;;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;;;;;
037&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
038&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
039&nbsp;&nbsp;;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
040&nbsp;&nbsp;;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
041&nbsp;&nbsp;;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;;;;;
042&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
043&nbsp;&nbsp;;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
044&nbsp;&nbsp;;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,
045&nbsp;&nbsp;;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;;;;;&nbsp;USA.
046&nbsp;&nbsp;;;;;&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;;;;;
047&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2014&nbsp;Simon&nbsp;Brooke
048&nbsp;&nbsp;;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2014&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;;;;;
049&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
050&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
050&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
051&nbsp;&nbsp;(defn&nbsp;apply-rule
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&quot;Apply&nbsp;a&nbsp;single&nbsp;`rule`&nbsp;to&nbsp;a&nbsp;`cell`.&nbsp;What&nbsp;this&nbsp;is&nbsp;about&nbsp;is&nbsp;that&nbsp;I&nbsp;want&nbsp;to&nbsp;be&nbsp;able,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;debugging&nbsp;purposes,&nbsp;to&nbsp;tag&nbsp;a&nbsp;cell&nbsp;with&nbsp;the&nbsp;rule&nbsp;text&nbsp;of&nbsp;the&nbsp;rule&nbsp;which
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fired&nbsp;(and&nbsp;especially&nbsp;so&nbsp;when&nbsp;an&nbsp;exception&nbsp;is&nbsp;thrown.&nbsp;So&nbsp;a&nbsp;rule&nbsp;may&nbsp;be&nbsp;either
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;an&nbsp;ifn,&nbsp;or&nbsp;a&nbsp;list&nbsp;(ifn&nbsp;source-text).&nbsp;This&nbsp;function&nbsp;deals&nbsp;with&nbsp;despatching
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;on&nbsp;those&nbsp;two&nbsp;possibilities.&nbsp;`world`&nbsp;is&nbsp;also&nbsp;passed&nbsp;in&nbsp;in&nbsp;order&nbsp;to&nbsp;be&nbsp;able
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;access&nbsp;neighbours.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;cell&nbsp;rule]
</span><br/>
<span class="partial" title="2 out of 3 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ifn?&nbsp;rule)&nbsp;(apply-rule&nbsp;world&nbsp;cell&nbsp;rule&nbsp;nil)
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;rule)&nbsp;(let&nbsp;[[afn&nbsp;src]&nbsp;rule]&nbsp;(apply-rule&nbsp;world&nbsp;cell&nbsp;afn&nbsp;src))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;cell&nbsp;rule&nbsp;source]
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[result&nbsp;(apply&nbsp;rule&nbsp;(list&nbsp;cell&nbsp;world))]
051&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
052&nbsp;&nbsp;(def&nbsp;^:dynamic&nbsp;*with-history*
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;result&nbsp;source)&nbsp;(merge&nbsp;result&nbsp;{:rule&nbsp;source})
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&quot;I&nbsp;suspect&nbsp;that&nbsp;caching&nbsp;history&nbsp;on&nbsp;the&nbsp;cells&nbsp;is&nbsp;greatly&nbsp;worsening&nbsp;the
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;result))))
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memory&nbsp;problems.&nbsp;Make&nbsp;it&nbsp;optional,&nbsp;but&nbsp;by&nbsp;default&nbsp;false.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;false)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
067&nbsp;&nbsp;
056&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
068&nbsp;&nbsp;(defn-&nbsp;apply-rules
057&nbsp;&nbsp;(defn&nbsp;apply-rule
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&quot;Derive&nbsp;a&nbsp;cell&nbsp;from&nbsp;this&nbsp;`cell`&nbsp;of&nbsp;this&nbsp;`world`&nbsp;by&nbsp;applying&nbsp;these&nbsp;`rules`.&quot;
058&nbsp;&nbsp;&nbsp;&nbsp;&quot;Apply&nbsp;a&nbsp;single&nbsp;`rule`&nbsp;to&nbsp;a&nbsp;`cell`.&nbsp;What&nbsp;this&nbsp;is&nbsp;about&nbsp;is&nbsp;that&nbsp;I&nbsp;want&nbsp;to&nbsp;be&nbsp;able,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;cell&nbsp;rules]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(empty?&nbsp;rules)&nbsp;cell
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(let&nbsp;[result&nbsp;(apply-rule&nbsp;world&nbsp;cell&nbsp;(first&nbsp;rules))]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;result&nbsp;result
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(apply-rules&nbsp;world&nbsp;cell&nbsp;(rest&nbsp;rules))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
075&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
076&nbsp;&nbsp;(defn-&nbsp;transform-cell
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;debugging&nbsp;purposes,&nbsp;to&nbsp;tag&nbsp;a&nbsp;cell&nbsp;with&nbsp;the&nbsp;rule&nbsp;text&nbsp;of&nbsp;the&nbsp;rule&nbsp;which
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&quot;Derive&nbsp;a&nbsp;cell&nbsp;from&nbsp;this&nbsp;`cell`&nbsp;of&nbsp;this&nbsp;`world`&nbsp;by&nbsp;applying&nbsp;these&nbsp;`rules`.&nbsp;If&nbsp;an
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fired&nbsp;(and&nbsp;especially&nbsp;so&nbsp;when&nbsp;an&nbsp;exception&nbsp;is&nbsp;thrown).&nbsp;&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exception&nbsp;is&nbsp;thrown,&nbsp;cache&nbsp;its&nbsp;message&nbsp;on&nbsp;the&nbsp;cell&nbsp;and&nbsp;set&nbsp;it&#x27;s&nbsp;state&nbsp;to&nbsp;error&quot;
061&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;as&nbsp;of&nbsp;version&nbsp;0-3-0,&nbsp;metadata&nbsp;for&nbsp;rules&nbsp;is&nbsp;now&nbsp;passed&nbsp;around&nbsp;on&nbsp;the&nbsp;metadata
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;cell&nbsp;rules]
062&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;of&nbsp;the&nbsp;rule&nbsp;function&nbsp;itself.&nbsp;Yes,&nbsp;I&nbsp;know,&nbsp;this&nbsp;is&nbsp;obvious;&nbsp;but&nbsp;I&#x27;ll&nbsp;confess
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;I&nbsp;didn&#x27;t&nbsp;think&nbsp;of&nbsp;it&nbsp;before.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;cell&nbsp;rule]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[result&nbsp;(try
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;rule&nbsp;(list&nbsp;cell&nbsp;world))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
</span><br/>
<span class="not-covered" title="0 out of 16 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(l&#x2F;warn&nbsp;e
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(format
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;Error&nbsp;in&nbsp;`apply-rule`:&nbsp;`%s`&nbsp;(%s)&nbsp;while&nbsp;executing&nbsp;rule&nbsp;`%s`&nbsp;on&nbsp;cell&nbsp;`%s`&quot;
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;(try
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.getMessage&nbsp;e)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(-&gt;&nbsp;rule&nbsp;meta&nbsp;:lisp)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cell))))]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;*with-history*
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(add-history-event&nbsp;result&nbsp;rule)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
078&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
079&nbsp;&nbsp;(defn-&nbsp;apply-rules
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&quot;Derive&nbsp;a&nbsp;cell&nbsp;from&nbsp;this&nbsp;`cell`&nbsp;of&nbsp;this&nbsp;`world`&nbsp;by&nbsp;applying&nbsp;these&nbsp;`rules`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;cell&nbsp;rules]
</span><br/>
<span class="partial" title="4 out of 5 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;(or
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(first
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(remove
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nil?
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;#(apply-rule&nbsp;world&nbsp;cell&nbsp;%)&nbsp;rules)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
</span><br/>
<span class="not-covered" title="0 out of 16 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(l&#x2F;warn&nbsp;e
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(format
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;Error&nbsp;in&nbsp;`apply-rules`:&nbsp;`%s`&nbsp;(%s)&nbsp;while&nbsp;executing&nbsp;rules&nbsp;on&nbsp;cell&nbsp;`%s`&quot;
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply-rules&nbsp;world&nbsp;cell&nbsp;rules)
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:generation&nbsp;(+&nbsp;(get-int-or-zero&nbsp;cell&nbsp;:generation)&nbsp;1)})
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:error
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(format&nbsp;&quot;%s&nbsp;at&nbsp;generation&nbsp;%d&nbsp;when&nbsp;in&nbsp;state&nbsp;%s&quot;
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(-&gt;&nbsp;e&nbsp;.getClass&nbsp;.getName)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.getMessage&nbsp;e)
093&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.getMessage&nbsp;e)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:generation&nbsp;cell)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:state&nbsp;cell))
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:stacktrace&nbsp;(map&nbsp;#(.toString&nbsp;%)&nbsp;(.getStackTrace&nbsp;e))
<span class="not-covered" title="0 out of 1 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cell))))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:state&nbsp;:error}))))
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cell))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
092&nbsp;&nbsp;
096&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
093&nbsp;&nbsp;(defn&nbsp;transform-world
097&nbsp;&nbsp;(defn-&nbsp;transform-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;world&nbsp;derived&nbsp;from&nbsp;this&nbsp;`world`&nbsp;by&nbsp;applying&nbsp;these&nbsp;`rules`&nbsp;to&nbsp;each&nbsp;cell.&quot;
098&nbsp;&nbsp;&nbsp;&nbsp;&quot;Derive&nbsp;a&nbsp;cell&nbsp;from&nbsp;this&nbsp;`cell`&nbsp;of&nbsp;this&nbsp;`world`&nbsp;by&nbsp;applying&nbsp;these&nbsp;`rules`.&nbsp;If&nbsp;an
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;rules]
099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exception&nbsp;is&nbsp;thrown,&nbsp;cache&nbsp;its&nbsp;message&nbsp;on&nbsp;the&nbsp;cell&nbsp;and&nbsp;set&nbsp;it&#x27;s&nbsp;state&nbsp;to&nbsp;error&quot;
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;transform-cell&nbsp;(list&nbsp;rules))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
097&nbsp;&nbsp;
<span class="not-tracked" title="0 out of 0 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;cell&nbsp;rules]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
098&nbsp;&nbsp;(defn&nbsp;run-world
101&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply-rules&nbsp;world&nbsp;cell&nbsp;rules)
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:generation&nbsp;(+&nbsp;(get-int-or-zero&nbsp;cell&nbsp;:generation)&nbsp;1)})
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;&quot;Run&nbsp;this&nbsp;world&nbsp;with&nbsp;these&nbsp;rules&nbsp;for&nbsp;this&nbsp;number&nbsp;of&nbsp;generations.
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
100&nbsp;&nbsp;
<span class="not-covered" title="0 out of 4 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[narrative&nbsp;(format&nbsp;&quot;Error&nbsp;in&nbsp;`transform-cell`:&nbsp;`%s`&nbsp;(%s)&nbsp;at&nbsp;generation&nbsp;%d&nbsp;when&nbsp;in&nbsp;state&nbsp;%s;&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world&nbsp;as&nbsp;discussed&nbsp;above;
<span class="not-covered" title="0 out of 2 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(-&gt;&nbsp;e&nbsp;.getClass&nbsp;.getName)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`init-rules`&nbsp;a&nbsp;sequence&nbsp;of&nbsp;rules&nbsp;as&nbsp;defined&nbsp;above,&nbsp;to&nbsp;be&nbsp;run&nbsp;once&nbsp;to&nbsp;initialise&nbsp;the&nbsp;world;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`rules`&nbsp;a&nbsp;sequence&nbsp;of&nbsp;rules&nbsp;as&nbsp;defined&nbsp;above,&nbsp;to&nbsp;be&nbsp;run&nbsp;iteratively&nbsp;for&nbsp;each&nbsp;generation;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`generations`&nbsp;an&nbsp;(integer)&nbsp;number&nbsp;of&nbsp;generations.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
105&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;Return&nbsp;the&nbsp;final&nbsp;generation&nbsp;of&nbsp;the&nbsp;world.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;init-rules&nbsp;rules&nbsp;generations]
<span class="not-covered" title="0 out of 1 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.getMessage&nbsp;e)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;(reduce&nbsp;(fn&nbsp;[world&nbsp;iteration]
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:generation&nbsp;cell)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:state&nbsp;cell))]
</span><br/>
<span class="not-covered" title="0 out of 17 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(l&#x2F;info&nbsp;&quot;Running&nbsp;iteration&nbsp;&quot;&nbsp;iteration)
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(l&#x2F;warn&nbsp;e&nbsp;narrative)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(transform-world&nbsp;world&nbsp;rules))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(transform-world&nbsp;world&nbsp;init-rules)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(range&nbsp;generations)))
<span class="not-covered" title="0 out of 1 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cell))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
113&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
114&nbsp;&nbsp;
<span class="covered" title="1 out of 1 forms covered">
114&nbsp;&nbsp;(defn&nbsp;transform-world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
115&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;world&nbsp;derived&nbsp;from&nbsp;this&nbsp;`world`&nbsp;by&nbsp;applying&nbsp;the&nbsp;production&nbsp;rules&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;found&nbsp;among&nbsp;these&nbsp;`rules`&nbsp;to&nbsp;each&nbsp;cell.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;rules]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;transform-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;Yes,&nbsp;that&nbsp;`list`&nbsp;is&nbsp;there&nbsp;for&nbsp;a&nbsp;reason!&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(filter
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
122&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(=&nbsp;:production&nbsp;(rule-type&nbsp;%))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
123&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rules))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
115&nbsp;&nbsp;
124&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
125&nbsp;&nbsp;(defn&nbsp;run-world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
126&nbsp;&nbsp;&nbsp;&nbsp;&quot;Run&nbsp;this&nbsp;world&nbsp;with&nbsp;these&nbsp;rules&nbsp;for&nbsp;this&nbsp;number&nbsp;of&nbsp;generations.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
127&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
128&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world&nbsp;as&nbsp;discussed&nbsp;above;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
129&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`init-rules`&nbsp;a&nbsp;sequence&nbsp;of&nbsp;rules&nbsp;as&nbsp;defined&nbsp;above,&nbsp;to&nbsp;be&nbsp;run&nbsp;once&nbsp;to&nbsp;initialise&nbsp;the&nbsp;world;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
130&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`rules`&nbsp;a&nbsp;sequence&nbsp;of&nbsp;rules&nbsp;as&nbsp;defined&nbsp;above,&nbsp;to&nbsp;be&nbsp;run&nbsp;iteratively&nbsp;for&nbsp;each&nbsp;generation;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
131&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`generations`&nbsp;an&nbsp;(integer)&nbsp;number&nbsp;of&nbsp;generations.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
132&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
133&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;**NOTE&nbsp;THAT**&nbsp;all&nbsp;rules&nbsp;**must**&nbsp;be&nbsp;tagged&nbsp;with&nbsp;`rule-type`&nbsp;metadata,&nbsp;or&nbsp;thet&nbsp;**will&nbsp;not**
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
134&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;executed.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
135&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
136&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return&nbsp;the&nbsp;final&nbsp;generation&nbsp;of&nbsp;the&nbsp;world.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
137&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;rules&nbsp;generations]
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
138&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(run-world&nbsp;world&nbsp;rules&nbsp;rules&nbsp;(dec&nbsp;generations)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
139&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;init-rules&nbsp;rules&nbsp;generations]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
140&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(reduce&nbsp;(fn&nbsp;[world&nbsp;iteration]
</span><br/>
<span class="not-covered" title="0 out of 17 forms covered">
141&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(l&#x2F;info&nbsp;&quot;Running&nbsp;iteration&nbsp;&quot;&nbsp;iteration)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
142&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[w&#x27;&nbsp;(transform-world&nbsp;world&nbsp;rules)]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
143&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(flow-world&nbsp;w&#x27;&nbsp;rules)))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
144&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(transform-world&nbsp;world&nbsp;init-rules)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
145&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(range&nbsp;generations))))
</span><br/>
</body>
</html>

View file

@ -77,355 +77,469 @@
024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;executed.&nbsp;This&nbsp;namespace&nbsp;deals&nbsp;with&nbsp;mainly&nbsp;with&nbsp;execution.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[mw-engine.utils&nbsp;:refer&nbsp;[get-cell&nbsp;get-num&nbsp;in-bounds?&nbsp;merge-cell]]
025&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[mw-engine.utils&nbsp;:refer&nbsp;[add-history-event&nbsp;get-cell&nbsp;get-num
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[taoensso.timbre&nbsp;:refer&nbsp;[info&nbsp;warn]]))
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in-bounds?&nbsp;map-world&nbsp;merge-cell&nbsp;rule-type]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[taoensso.timbre&nbsp;:refer&nbsp;[info&nbsp;warn]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
027&nbsp;&nbsp;
028&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
029&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;;;;;
030&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;;;;;&nbsp;mw-engine:&nbsp;the&nbsp;state&#x2F;transition&nbsp;engine&nbsp;of&nbsp;MicroWorld.
031&nbsp;&nbsp;;;;;&nbsp;mw-engine:&nbsp;the&nbsp;state&#x2F;transition&nbsp;engine&nbsp;of&nbsp;MicroWorld.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;;;;;
032&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
033&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
034&nbsp;&nbsp;;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
035&nbsp;&nbsp;;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
036&nbsp;&nbsp;;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;;;;;
037&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
038&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
039&nbsp;&nbsp;;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
040&nbsp;&nbsp;;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
041&nbsp;&nbsp;;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;;;;;
042&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
043&nbsp;&nbsp;;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
044&nbsp;&nbsp;;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,
045&nbsp;&nbsp;;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;;;;;&nbsp;USA.
046&nbsp;&nbsp;;;;;&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;;;;;
047&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2014&nbsp;Simon&nbsp;Brooke
048&nbsp;&nbsp;;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2014&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;;;;;
049&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
050&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
050&nbsp;&nbsp;
051&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
051&nbsp;&nbsp;(defn&nbsp;coordinate?
052&nbsp;&nbsp;(defn&nbsp;coordinate?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;`true`&nbsp;if&nbsp;this&nbsp;object&nbsp;`o`&nbsp;is&nbsp;a&nbsp;valid&nbsp;coordinate&nbsp;with&nbsp;respect&nbsp;to
053&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;`true`&nbsp;if&nbsp;this&nbsp;object&nbsp;`o`&nbsp;is&nbsp;a&nbsp;valid&nbsp;coordinate&nbsp;with&nbsp;respect&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;`world`,&nbsp;else&nbsp;`false`.&nbsp;Assumes&nbsp;square&nbsp;worlds.&quot;
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;`world`,&nbsp;else&nbsp;`false`.&nbsp;Assumes&nbsp;square&nbsp;worlds.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;[o&nbsp;world]
055&nbsp;&nbsp;&nbsp;&nbsp;[o&nbsp;world]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;(try
056&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="covered" title="14 out of 14 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(or&nbsp;(zero?&nbsp;o)&nbsp;(pos-int?&nbsp;o))
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(or&nbsp;(zero?&nbsp;o)&nbsp;(pos-int?&nbsp;o))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;&nbsp;o&nbsp;(count&nbsp;world)))
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;&nbsp;o&nbsp;(count&nbsp;world)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
</span><br/>
<span class="covered" title="20 out of 20 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Not&nbsp;a&nbsp;valid&nbsp;coordinate:&nbsp;%s;&nbsp;%s&quot;&nbsp;o&nbsp;(.getMessage&nbsp;e)))
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Not&nbsp;a&nbsp;valid&nbsp;coordinate:&nbsp;%s;&nbsp;%s&quot;&nbsp;o&nbsp;(.getMessage&nbsp;e)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false)))
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
061&nbsp;&nbsp;
062&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
062&nbsp;&nbsp;(defn&nbsp;location?
063&nbsp;&nbsp;(defn&nbsp;location?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;`true`&nbsp;if&nbsp;this&nbsp;object&nbsp;`o`&nbsp;is&nbsp;a&nbsp;location&nbsp;as&nbsp;defined&nbsp;above&nbsp;with&nbsp;respect&nbsp;to
064&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;`true`&nbsp;if&nbsp;this&nbsp;object&nbsp;`o`&nbsp;is&nbsp;a&nbsp;location&nbsp;as&nbsp;defined&nbsp;above&nbsp;with&nbsp;respect&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;`world`,&nbsp;else&nbsp;`false`.&quot;
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;`world`,&nbsp;else&nbsp;`false`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;[o&nbsp;world]
066&nbsp;&nbsp;&nbsp;&nbsp;[o&nbsp;world]
</span><br/>
<span class="partial" title="1 out of 2 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;(try
067&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="partial" title="14 out of 16 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(map?&nbsp;o)
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(map?&nbsp;o)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(integer?&nbsp;(:x&nbsp;o))
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(integer?&nbsp;(:x&nbsp;o))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(integer?&nbsp;(:y&nbsp;o))
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(integer?&nbsp;(:y&nbsp;o))
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(in-bounds?&nbsp;world&nbsp;(:x&nbsp;o)&nbsp;(:y&nbsp;o)))
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(in-bounds?&nbsp;world&nbsp;(:x&nbsp;o)&nbsp;(:y&nbsp;o)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
</span><br/>
<span class="not-covered" title="0 out of 20 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Not&nbsp;a&nbsp;valid&nbsp;location:&nbsp;%s;&nbsp;%s&quot;&nbsp;o&nbsp;(.getMessage&nbsp;e)))
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Not&nbsp;a&nbsp;valid&nbsp;location:&nbsp;%s;&nbsp;%s&quot;&nbsp;o&nbsp;(.getMessage&nbsp;e)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false)))
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
074&nbsp;&nbsp;
075&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
075&nbsp;&nbsp;(defn&nbsp;flow?
076&nbsp;&nbsp;(defn&nbsp;flow?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;`true`&nbsp;if&nbsp;this&nbsp;object&nbsp;`o`&nbsp;is&nbsp;a&nbsp;flow&nbsp;as&nbsp;defined&nbsp;above&nbsp;with&nbsp;respect&nbsp;to
077&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;`true`&nbsp;if&nbsp;this&nbsp;object&nbsp;`o`&nbsp;is&nbsp;a&nbsp;flow&nbsp;as&nbsp;defined&nbsp;above&nbsp;with&nbsp;respect&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;`world`,&nbsp;else&nbsp;`false`.&nbsp;Assumes&nbsp;square&nbsp;worlds.&quot;
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;`world`,&nbsp;else&nbsp;`false`.&nbsp;Assumes&nbsp;square&nbsp;worlds.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;[o&nbsp;world]
079&nbsp;&nbsp;&nbsp;&nbsp;[o&nbsp;world]
</span><br/>
<span class="partial" title="1 out of 2 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;(try
080&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="partial" title="16 out of 20 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(map?&nbsp;o)
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(map?&nbsp;o)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(location?&nbsp;(:source&nbsp;o)&nbsp;world)
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(location?&nbsp;(:source&nbsp;o)&nbsp;world)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(location?&nbsp;(:destination&nbsp;o)&nbsp;world)
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(location?&nbsp;(:destination&nbsp;o)&nbsp;world)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(keyword?&nbsp;(:property&nbsp;o))
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(keyword?&nbsp;(:property&nbsp;o))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pos?&nbsp;(:quantity&nbsp;o)))
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pos?&nbsp;(:quantity&nbsp;o)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
</span><br/>
<span class="not-covered" title="0 out of 20 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Not&nbsp;a&nbsp;valid&nbsp;flow:&nbsp;%s;&nbsp;%s&quot;&nbsp;o&nbsp;(.getMessage&nbsp;e)))
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Not&nbsp;a&nbsp;valid&nbsp;flow:&nbsp;%s;&nbsp;%s&quot;&nbsp;o&nbsp;(.getMessage&nbsp;e)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false)))
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
088&nbsp;&nbsp;
089&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
089&nbsp;&nbsp;(defn&nbsp;execute
090&nbsp;&nbsp;(defn&nbsp;execute
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;world&nbsp;like&nbsp;this&nbsp;`world`,&nbsp;except&nbsp;with&nbsp;the&nbsp;quantity&nbsp;of&nbsp;the&nbsp;property
091&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;world&nbsp;like&nbsp;this&nbsp;`world`,&nbsp;except&nbsp;with&nbsp;the&nbsp;quantity&nbsp;of&nbsp;the&nbsp;property
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;described&nbsp;in&nbsp;this&nbsp;`flow`&nbsp;object&nbsp;transferred&nbsp;from&nbsp;the&nbsp;source&nbsp;of&nbsp;that&nbsp;flow
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;described&nbsp;in&nbsp;this&nbsp;`flow`&nbsp;object&nbsp;transferred&nbsp;from&nbsp;the&nbsp;source&nbsp;of&nbsp;that&nbsp;flow
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;its&nbsp;destination.&quot;
093&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;its&nbsp;destination.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;flow]
094&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;flow]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;(try
095&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[sx&nbsp;(-&gt;&nbsp;flow&nbsp;:source&nbsp;:x)
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[sx&nbsp;(-&gt;&nbsp;flow&nbsp;:source&nbsp;:x)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sy&nbsp;(-&gt;&nbsp;flow&nbsp;:source&nbsp;:y)
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sy&nbsp;(-&gt;&nbsp;flow&nbsp;:source&nbsp;:y)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;source&nbsp;(get-cell&nbsp;world&nbsp;sx&nbsp;sy)
098&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;source&nbsp;(get-cell&nbsp;world&nbsp;sx&nbsp;sy)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dx&nbsp;(-&gt;&nbsp;flow&nbsp;:destination&nbsp;:x)
099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dx&nbsp;(-&gt;&nbsp;flow&nbsp;:destination&nbsp;:x)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dy&nbsp;(-&gt;&nbsp;flow&nbsp;:destination&nbsp;:y)
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dy&nbsp;(-&gt;&nbsp;flow&nbsp;:destination&nbsp;:y)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dest&nbsp;(get-cell&nbsp;world&nbsp;dx&nbsp;dy)
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dest&nbsp;(get-cell&nbsp;world&nbsp;dx&nbsp;dy)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;(:property&nbsp;flow)
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;(:property&nbsp;flow)
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q&nbsp;(min&nbsp;(:quantity&nbsp;flow)&nbsp;(get-num&nbsp;source&nbsp;p))
<span class="partial" title="16 out of 22 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q&nbsp;(min&nbsp;(:quantity&nbsp;flow)&nbsp;(get-num&nbsp;source&nbsp;p))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s&#x27;&nbsp;(add-history-event&nbsp;
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s&#x27;&nbsp;(assoc&nbsp;source&nbsp;p&nbsp;(-&nbsp;(source&nbsp;p)&nbsp;q))
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;source&nbsp;p&nbsp;(-&nbsp;(source&nbsp;p)&nbsp;q))&nbsp;
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d&#x27;&nbsp;(assoc&nbsp;dest&nbsp;p&nbsp;(+&nbsp;(get-num&nbsp;dest&nbsp;p)&nbsp;q))]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(=&nbsp;q&nbsp;(:quantity&nbsp;flow))
</span><br/>
<span class="covered" title="18 out of 18 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(info&nbsp;(format&nbsp;&quot;Moving&nbsp;%f&nbsp;units&nbsp;of&nbsp;%s&nbsp;from&nbsp;%d,%d&nbsp;to&nbsp;%d,%d&quot;
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(float&nbsp;q)&nbsp;(name&nbsp;p)&nbsp;sx&nbsp;sy&nbsp;dx&nbsp;dy))
</span><br/>
<span class="covered" title="18 out of 18 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Moving&nbsp;%s&nbsp;from&nbsp;%d,%d&nbsp;to&nbsp;%d,%d;&nbsp;%f&nbsp;units&nbsp;ordered&nbsp;but&nbsp;only&nbsp;%f&nbsp;available&quot;
<span class="covered" title="3 out of 3 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:rule&nbsp;flow)&nbsp;
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(name&nbsp;p)&nbsp;sx&nbsp;sy&nbsp;dx&nbsp;dy&nbsp;(float&nbsp;(:quantity&nbsp;flow))&nbsp;(float&nbsp;q))))
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:direction&nbsp;:sent&nbsp;:other&nbsp;{:x&nbsp;dx&nbsp;:y&nbsp;dy}&nbsp;:property&nbsp;p&nbsp;:quantity&nbsp;q})
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d&#x27;&nbsp;(add-history-event
</span><br/>
<span class="partial" title="20 out of 24 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;dest&nbsp;p&nbsp;(+&nbsp;(get-num&nbsp;dest&nbsp;p)&nbsp;q))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:rule&nbsp;flow)
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:direction&nbsp;:received&nbsp;:other&nbsp;{:x&nbsp;sx&nbsp;:y&nbsp;sy}&nbsp;:property&nbsp;p&nbsp;:quantity&nbsp;q})]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(=&nbsp;q&nbsp;(:quantity&nbsp;flow))
</span><br/>
<span class="covered" title="18 out of 18 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(info&nbsp;(format&nbsp;&quot;Moving&nbsp;%f&nbsp;units&nbsp;of&nbsp;%s&nbsp;from&nbsp;%d,%d&nbsp;to&nbsp;%d,%d&quot;
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(float&nbsp;q)&nbsp;(name&nbsp;p)&nbsp;sx&nbsp;sy&nbsp;dx&nbsp;dy))
</span><br/>
<span class="covered" title="18 out of 18 forms covered">
115&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Moving&nbsp;%s&nbsp;from&nbsp;%d,%d&nbsp;to&nbsp;%d,%d;&nbsp;%f&nbsp;units&nbsp;ordered&nbsp;but&nbsp;only&nbsp;%f&nbsp;available&quot;
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(name&nbsp;p)&nbsp;sx&nbsp;sy&nbsp;dx&nbsp;dy&nbsp;(float&nbsp;(:quantity&nbsp;flow))&nbsp;(float&nbsp;q))))
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge-cell&nbsp;(merge-cell&nbsp;world&nbsp;s&#x27;)&nbsp;d&#x27;))
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge-cell&nbsp;(merge-cell&nbsp;world&nbsp;s&#x27;)&nbsp;d&#x27;))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
118&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
</span><br/>
<span class="not-covered" title="0 out of 20 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Failed&nbsp;to&nbsp;execute&nbsp;flow&nbsp;%s:&nbsp;%s&quot;&nbsp;flow&nbsp;(.getMessage&nbsp;e)))
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Failed&nbsp;to&nbsp;execute&nbsp;flow&nbsp;%s:&nbsp;%s&quot;&nbsp;flow&nbsp;(.getMessage&nbsp;e)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;return&nbsp;the&nbsp;world&nbsp;unmodified.
120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;return&nbsp;the&nbsp;world&nbsp;unmodified.
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
115&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
116&nbsp;&nbsp;(defn&nbsp;execute-flows
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;world&nbsp;like&nbsp;this&nbsp;`world`,&nbsp;but&nbsp;with&nbsp;each&nbsp;of&nbsp;these&nbsp;flows&nbsp;executed.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;flows]
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;(reduce&nbsp;execute&nbsp;world&nbsp;(filter&nbsp;#(flow?&nbsp;%&nbsp;world)&nbsp;flows)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
120&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
121&nbsp;&nbsp;;;&nbsp;building&nbsp;blocks&nbsp;for&nbsp;compiled&nbsp;flow&nbsp;rules
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
122&nbsp;&nbsp;
</span><br/>
<span class="covered" title="32 out of 32 forms covered">
123&nbsp;&nbsp;(defmacro&nbsp;create-location
<span class="covered" title="1 out of 1 forms covered">
123&nbsp;&nbsp;(defn&nbsp;execute-flows
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;[cell]
124&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;world&nbsp;like&nbsp;this&nbsp;`world`,&nbsp;but&nbsp;with&nbsp;each&nbsp;of&nbsp;these&nbsp;flows&nbsp;executed.&quot;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;`(select-keys&nbsp;~cell&nbsp;[:x&nbsp;:y]))
<span class="not-tracked" title="0 out of 0 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;flows]
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
126&nbsp;&nbsp;&nbsp;&nbsp;(reduce&nbsp;execute&nbsp;world&nbsp;(filter&nbsp;#(flow?&nbsp;%&nbsp;world)&nbsp;flows)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
126&nbsp;&nbsp;
127&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
128&nbsp;&nbsp;(defn-&nbsp;plan-cell-flows&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
129&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;cell&nbsp;rules]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
130&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;;;&nbsp;across&nbsp;all&nbsp;the&nbsp;rules
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
131&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[rule]&nbsp;(let&nbsp;[r&nbsp;(try&nbsp;
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
132&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;rule&nbsp;(list&nbsp;cell&nbsp;world))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
133&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;any
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
134&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(ex-info&nbsp;&quot;Planning&nbsp;of&nbsp;flows&nbsp;failed&quot;
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
135&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;(meta&nbsp;rule)&nbsp;{:cell&nbsp;cell})
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
136&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;any))))]&nbsp;
</span><br/>
<span class="not-covered" title="0 out of 12 forms covered">
137&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when&nbsp;r&nbsp;(map&nbsp;#(assoc&nbsp;%&nbsp;:rule&nbsp;rule)&nbsp;r))))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
138&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rules))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
139&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
140&nbsp;&nbsp;(defn&nbsp;plan-flows
</span><br/>
<span class="partial" title="3 out of 4 forms covered">
141&nbsp;&nbsp;&nbsp;&nbsp;&quot;Plan,&nbsp;but&nbsp;do&nbsp;not&nbsp;execute,&nbsp;all&nbsp;the&nbsp;flows&nbsp;in&nbsp;this&nbsp;`world`&nbsp;implied&nbsp;by&nbsp;those&nbsp;of&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
142&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;these&nbsp;`rules`&nbsp;(which&nbsp;are&nbsp;expected&nbsp;to&nbsp;be&nbsp;pre-compiled)&nbsp;which&nbsp;are
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
143&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flow&nbsp;rules.&nbsp;Return&nbsp;the&nbsp;list&nbsp;of&nbsp;plans,&nbsp;as&nbsp;flow&nbsp;objects.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
144&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;rules]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
145&nbsp;&nbsp;&nbsp;&nbsp;(remove&nbsp;nil?
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
146&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(flatten
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
147&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
149&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;plan-cell-flows
</span><br/>
<span class="partial" title="4 out of 17 forms covered">
150&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;(filter&nbsp;#(=&nbsp;:flow&nbsp;(rule-type&nbsp;%))&nbsp;rules))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
151&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
152&nbsp;&nbsp;(defn&nbsp;flow-world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
153&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;world&nbsp;derived&nbsp;from&nbsp;this&nbsp;`world`&nbsp;by&nbsp;applying&nbsp;the&nbsp;flow&nbsp;rules&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
154&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;found&nbsp;among&nbsp;these&nbsp;`rules`&nbsp;to&nbsp;each&nbsp;cell,&nbsp;and&nbsp;executing&nbsp;all&nbsp;the&nbsp;flows
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;planned.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
156&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;rules]
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
157&nbsp;&nbsp;&nbsp;&nbsp;(execute-flows&nbsp;world&nbsp;(plan-flows&nbsp;world&nbsp;rules)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
158&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
159&nbsp;&nbsp;;;&nbsp;building&nbsp;blocks&nbsp;for&nbsp;compiled&nbsp;flow&nbsp;rules
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
160&nbsp;&nbsp;
</span><br/>
<span class="covered" title="32 out of 32 forms covered">
161&nbsp;&nbsp;(defmacro&nbsp;create-location
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
162&nbsp;&nbsp;&nbsp;&nbsp;[cell]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
163&nbsp;&nbsp;&nbsp;&nbsp;`(select-keys&nbsp;~cell&nbsp;[:x&nbsp;:y]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
164&nbsp;&nbsp;
</span><br/>
<span class="covered" title="56 out of 56 forms covered">
127&nbsp;&nbsp;(defmacro&nbsp;create-flow-quantity
165&nbsp;&nbsp;(defmacro&nbsp;create-flow-quantity
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
128&nbsp;&nbsp;&nbsp;&nbsp;[source&nbsp;dest&nbsp;prop&nbsp;quantity]
166&nbsp;&nbsp;&nbsp;&nbsp;[source&nbsp;dest&nbsp;prop&nbsp;quantity]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
129&nbsp;&nbsp;&nbsp;&nbsp;`{:source&nbsp;(create-location&nbsp;~source)
167&nbsp;&nbsp;&nbsp;&nbsp;`{:source&nbsp;(create-location&nbsp;~source)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
130&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:destination&nbsp;(create-location&nbsp;~dest)
168&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:destination&nbsp;(create-location&nbsp;~dest)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
131&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:prop&nbsp;~prop
169&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:prop&nbsp;~prop
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
132&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:quantity&nbsp;~quantity})
170&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:quantity&nbsp;~quantity})
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
133&nbsp;&nbsp;
171&nbsp;&nbsp;
</span><br/>
<span class="covered" title="48 out of 48 forms covered">
134&nbsp;&nbsp;(defmacro&nbsp;create-flow-fraction
172&nbsp;&nbsp;(defmacro&nbsp;create-flow-fraction
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
135&nbsp;&nbsp;&nbsp;&nbsp;[source&nbsp;dest&nbsp;prop&nbsp;fraction]
173&nbsp;&nbsp;&nbsp;&nbsp;[source&nbsp;dest&nbsp;prop&nbsp;fraction]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
136&nbsp;&nbsp;&nbsp;&nbsp;`(create-flow-quantity&nbsp;~source&nbsp;~dest&nbsp;~prop
174&nbsp;&nbsp;&nbsp;&nbsp;`(create-flow-quantity&nbsp;~source&nbsp;~dest&nbsp;~prop
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
137&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*&nbsp;~fraction&nbsp;(get-num&nbsp;~source&nbsp;~prop))))
175&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*&nbsp;~fraction&nbsp;(get-num&nbsp;~source&nbsp;~prop))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
138&nbsp;&nbsp;
176&nbsp;&nbsp;
</span><br/>
<span class="covered" title="36 out of 36 forms covered">
139&nbsp;&nbsp;(defmacro&nbsp;create-flow-percent
177&nbsp;&nbsp;(defmacro&nbsp;create-flow-percent
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
140&nbsp;&nbsp;&nbsp;&nbsp;[source&nbsp;dest&nbsp;prop&nbsp;percent]
178&nbsp;&nbsp;&nbsp;&nbsp;[source&nbsp;dest&nbsp;prop&nbsp;percent]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
141&nbsp;&nbsp;&nbsp;&nbsp;`(create-flow-fraction&nbsp;~source&nbsp;~dest&nbsp;~prop&nbsp;(&#x2F;&nbsp;~percent&nbsp;100)))
179&nbsp;&nbsp;&nbsp;&nbsp;`(create-flow-fraction&nbsp;~source&nbsp;~dest&nbsp;~prop&nbsp;(&#x2F;&nbsp;~percent&nbsp;100)))
</span><br/>
</body>
</html>

View file

@ -107,283 +107,301 @@
034&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
035&nbsp;&nbsp;(defn&nbsp;tag-property
035&nbsp;&nbsp;(defn&nbsp;abs&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&quot;Set&nbsp;the&nbsp;value&nbsp;of&nbsp;this&nbsp;`property`&nbsp;of&nbsp;this&nbsp;cell&nbsp;from&nbsp;the&nbsp;corresponding&nbsp;pixel&nbsp;of&nbsp;this&nbsp;`heightmap`.
036&nbsp;&nbsp;&nbsp;&nbsp;&quot;Prior&nbsp;to&nbsp;Clojure&nbsp;1.11,&nbsp;there&nbsp;is&nbsp;no&nbsp;native&nbsp;`abs`&nbsp;function.&nbsp;Afterwards,&nbsp;there
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;the&nbsp;heightmap&nbsp;you&nbsp;supply&nbsp;is&nbsp;smaller&nbsp;than&nbsp;the&nbsp;world,&nbsp;this&nbsp;will&nbsp;break.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
038&nbsp;&nbsp;
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;is.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;not&nbsp;actually&nbsp;used,&nbsp;but&nbsp;present&nbsp;to&nbsp;enable&nbsp;this&nbsp;function&nbsp;to&nbsp;be
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;passed&nbsp;as&nbsp;an&nbsp;argument&nbsp;to&nbsp;`mw-engine.utils&#x2F;map-world`,&nbsp;q.v.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`cell`&nbsp;a&nbsp;cell,&nbsp;as&nbsp;discussed&nbsp;in&nbsp;world.clj,&nbsp;q.v.&nbsp;Alternatively,&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`property`&nbsp;the&nbsp;property&nbsp;(normally&nbsp;a&nbsp;keyword)&nbsp;whose&nbsp;value&nbsp;will&nbsp;be&nbsp;set&nbsp;on&nbsp;the&nbsp;cell.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`heightmap`&nbsp;an&nbsp;(ideally)&nbsp;greyscale&nbsp;image,&nbsp;whose&nbsp;x&nbsp;and&nbsp;y&nbsp;dimensions&nbsp;should
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exceed&nbsp;those&nbsp;of&nbsp;the&nbsp;world&nbsp;of&nbsp;which&nbsp;the&nbsp;`cell`&nbsp;forms&nbsp;part.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;([_&nbsp;cell&nbsp;property&nbsp;heightmap]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(tag-property&nbsp;cell&nbsp;property&nbsp;heightmap))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;([cell&nbsp;property&nbsp;heightmap]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell
038&nbsp;&nbsp;&nbsp;&nbsp;[n]&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{property
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(+&nbsp;(get-int&nbsp;cell&nbsp;property)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(-&nbsp;256
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(abs
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(mod
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.getRGB&nbsp;heightmap
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-int&nbsp;cell&nbsp;:x)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-int&nbsp;cell&nbsp;:y))&nbsp;256))))})))
039&nbsp;&nbsp;&nbsp;&nbsp;(Math&#x2F;abs&nbsp;n))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
057&nbsp;&nbsp;
040&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
058&nbsp;&nbsp;(defn&nbsp;tag-gradient
041&nbsp;&nbsp;(defn&nbsp;tag-property
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&quot;Set&nbsp;the&nbsp;`gradient`&nbsp;property&nbsp;of&nbsp;this&nbsp;`cell`&nbsp;of&nbsp;this&nbsp;`world`&nbsp;to&nbsp;the&nbsp;difference&nbsp;in
042&nbsp;&nbsp;&nbsp;&nbsp;&quot;Set&nbsp;the&nbsp;value&nbsp;of&nbsp;this&nbsp;`property`&nbsp;of&nbsp;this&nbsp;cell&nbsp;from&nbsp;the&nbsp;corresponding&nbsp;pixel&nbsp;of&nbsp;this&nbsp;`heightmap`.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;altitude&nbsp;between&nbsp;its&nbsp;highest&nbsp;and&nbsp;lowest&nbsp;neghbours.&quot;
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;the&nbsp;heightmap&nbsp;you&nbsp;supply&nbsp;is&nbsp;smaller&nbsp;than&nbsp;the&nbsp;world,&nbsp;this&nbsp;will&nbsp;break.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
044&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;cell]
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;not&nbsp;actually&nbsp;used,&nbsp;but&nbsp;present&nbsp;to&nbsp;enable&nbsp;this&nbsp;function&nbsp;to&nbsp;be
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;passed&nbsp;as&nbsp;an&nbsp;argument&nbsp;to&nbsp;`mw-engine.utils&#x2F;map-world`,&nbsp;q.v.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`cell`&nbsp;a&nbsp;cell,&nbsp;as&nbsp;discussed&nbsp;in&nbsp;world.clj,&nbsp;q.v.&nbsp;Alternatively,&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`property`&nbsp;the&nbsp;property&nbsp;(normally&nbsp;a&nbsp;keyword)&nbsp;whose&nbsp;value&nbsp;will&nbsp;be&nbsp;set&nbsp;on&nbsp;the&nbsp;cell.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`heightmap`&nbsp;an&nbsp;(ideally)&nbsp;greyscale&nbsp;image,&nbsp;whose&nbsp;x&nbsp;and&nbsp;y&nbsp;dimensions&nbsp;should
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exceed&nbsp;those&nbsp;of&nbsp;the&nbsp;world&nbsp;of&nbsp;which&nbsp;the&nbsp;`cell`&nbsp;forms&nbsp;part.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;([_&nbsp;cell&nbsp;property&nbsp;heightmap]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(tag-property&nbsp;cell&nbsp;property&nbsp;heightmap))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;([cell&nbsp;property&nbsp;heightmap]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{property
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(+&nbsp;(get-int&nbsp;cell&nbsp;property)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(-&nbsp;256
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(abs
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(mod
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.getRGB&nbsp;heightmap
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-int&nbsp;cell&nbsp;:x)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-int&nbsp;cell&nbsp;:y))&nbsp;256))))})))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
063&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
064&nbsp;&nbsp;(defn&nbsp;tag-gradient
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&quot;Set&nbsp;the&nbsp;`gradient`&nbsp;property&nbsp;of&nbsp;this&nbsp;`cell`&nbsp;of&nbsp;this&nbsp;`world`&nbsp;to&nbsp;the&nbsp;difference&nbsp;in
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;altitude&nbsp;between&nbsp;its&nbsp;highest&nbsp;and&nbsp;lowest&nbsp;neghbours.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;cell]
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[heights&nbsp;(remove&nbsp;nil?&nbsp;(map&nbsp;:altitude&nbsp;(get-neighbours&nbsp;world&nbsp;cell)))
068&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[heights&nbsp;(remove&nbsp;nil?&nbsp;(map&nbsp;:altitude&nbsp;(get-neighbours&nbsp;world&nbsp;cell)))
</span><br/>
<span class="partial" title="5 out of 6 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;highest&nbsp;(cond&nbsp;(empty?&nbsp;heights)&nbsp;0&nbsp;;;&nbsp;shouldn&#x27;t&nbsp;happen
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;highest&nbsp;(cond&nbsp;(empty?&nbsp;heights)&nbsp;0&nbsp;;;&nbsp;shouldn&#x27;t&nbsp;happen
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(apply&nbsp;max&nbsp;heights))
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(apply&nbsp;max&nbsp;heights))
</span><br/>
<span class="partial" title="5 out of 6 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lowest&nbsp;(cond&nbsp;(empty?&nbsp;heights)&nbsp;0&nbsp;;;&nbsp;shouldn&#x27;t
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lowest&nbsp;(cond&nbsp;(empty?&nbsp;heights)&nbsp;0&nbsp;;;&nbsp;shouldn&#x27;t
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(apply&nbsp;min&nbsp;heights))
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(apply&nbsp;min&nbsp;heights))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gradient&nbsp;(-&nbsp;highest&nbsp;lowest)]
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gradient&nbsp;(-&nbsp;highest&nbsp;lowest)]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:gradient&nbsp;gradient})))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
069&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
070&nbsp;&nbsp;(defn&nbsp;tag-gradients
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&quot;Set&nbsp;the&nbsp;`gradient`&nbsp;property&nbsp;of&nbsp;each&nbsp;cell&nbsp;in&nbsp;this&nbsp;`world`&nbsp;to&nbsp;the&nbsp;difference&nbsp;in
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;altitude&nbsp;between&nbsp;its&nbsp;highest&nbsp;and&nbsp;lowest&nbsp;neghbours.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;[world]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;tag-gradient))
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:gradient&nbsp;gradient})))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
075&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
076&nbsp;&nbsp;(defn&nbsp;tag-altitude
076&nbsp;&nbsp;(defn&nbsp;tag-gradients
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&quot;Set&nbsp;the&nbsp;altitude&nbsp;of&nbsp;this&nbsp;cell&nbsp;from&nbsp;the&nbsp;corresponding&nbsp;pixel&nbsp;of&nbsp;this&nbsp;heightmap.
077&nbsp;&nbsp;&nbsp;&nbsp;&quot;Set&nbsp;the&nbsp;`gradient`&nbsp;property&nbsp;of&nbsp;each&nbsp;cell&nbsp;in&nbsp;this&nbsp;`world`&nbsp;to&nbsp;the&nbsp;difference&nbsp;in
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;the&nbsp;heightmap&nbsp;you&nbsp;supply&nbsp;is&nbsp;smaller&nbsp;than&nbsp;the&nbsp;world,&nbsp;this&nbsp;will&nbsp;break.
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;altitude&nbsp;between&nbsp;its&nbsp;highest&nbsp;and&nbsp;lowest&nbsp;neghbours.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;[world]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;tag-gradient))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
079&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;not&nbsp;actually&nbsp;used,&nbsp;but&nbsp;present&nbsp;to&nbsp;enable&nbsp;this&nbsp;function&nbsp;to&nbsp;be
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;passed&nbsp;as&nbsp;an&nbsp;argument&nbsp;to&nbsp;`mw-engine.utils&#x2F;map-world`,&nbsp;q.v.;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`cell`&nbsp;a&nbsp;cell,&nbsp;as&nbsp;discussed&nbsp;in&nbsp;world.clj,&nbsp;q.v.&nbsp;Alternatively,&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`heightmap`&nbsp;an&nbsp;(ideally)&nbsp;greyscale&nbsp;image,&nbsp;whose&nbsp;x&nbsp;and&nbsp;y&nbsp;dimensions&nbsp;should
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exceed&nbsp;those&nbsp;of&nbsp;the&nbsp;world&nbsp;of&nbsp;which&nbsp;the&nbsp;`cell`&nbsp;forms&nbsp;part.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;([_&nbsp;cell&nbsp;heightmap]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(tag-property&nbsp;cell&nbsp;:altitude&nbsp;heightmap))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;([cell&nbsp;heightmap]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(tag-property&nbsp;cell&nbsp;:altitude&nbsp;heightmap)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
089&nbsp;&nbsp;
081&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
090&nbsp;&nbsp;(defn&nbsp;apply-heightmap
082&nbsp;&nbsp;(defn&nbsp;tag-altitude
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&quot;Apply&nbsp;the&nbsp;image&nbsp;file&nbsp;loaded&nbsp;from&nbsp;this&nbsp;path&nbsp;to&nbsp;this&nbsp;world,&nbsp;and&nbsp;return&nbsp;a&nbsp;world&nbsp;whose
083&nbsp;&nbsp;&nbsp;&nbsp;&quot;Set&nbsp;the&nbsp;altitude&nbsp;of&nbsp;this&nbsp;cell&nbsp;from&nbsp;the&nbsp;corresponding&nbsp;pixel&nbsp;of&nbsp;this&nbsp;heightmap.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;altitudes&nbsp;are&nbsp;modified&nbsp;(added&nbsp;to)&nbsp;by&nbsp;the&nbsp;altitudes&nbsp;in&nbsp;the&nbsp;heightmap.&nbsp;It&nbsp;is&nbsp;assumed&nbsp;that
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;the&nbsp;heightmap&nbsp;you&nbsp;supply&nbsp;is&nbsp;smaller&nbsp;than&nbsp;the&nbsp;world,&nbsp;this&nbsp;will&nbsp;break.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
085&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;heightmap&nbsp;is&nbsp;at&nbsp;least&nbsp;as&nbsp;large&nbsp;in&nbsp;x&nbsp;and&nbsp;y&nbsp;dimensions&nbsp;as&nbsp;the&nbsp;world.&nbsp;Note&nbsp;that,&nbsp;in
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;not&nbsp;actually&nbsp;used,&nbsp;but&nbsp;present&nbsp;to&nbsp;enable&nbsp;this&nbsp;function&nbsp;to&nbsp;be
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;addition&nbsp;to&nbsp;setting&nbsp;the&nbsp;`:altitude`&nbsp;of&nbsp;each&nbsp;cell,&nbsp;this&nbsp;function&nbsp;also&nbsp;sets&nbsp;the&nbsp;`:gradient`.
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;passed&nbsp;as&nbsp;an&nbsp;argument&nbsp;to&nbsp;`mw-engine.utils&#x2F;map-world`,&nbsp;q.v.;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`cell`&nbsp;a&nbsp;cell,&nbsp;as&nbsp;discussed&nbsp;in&nbsp;world.clj,&nbsp;q.v.&nbsp;Alternatively,&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`heightmap`&nbsp;an&nbsp;(ideally)&nbsp;greyscale&nbsp;image,&nbsp;whose&nbsp;x&nbsp;and&nbsp;y&nbsp;dimensions&nbsp;should
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exceed&nbsp;those&nbsp;of&nbsp;the&nbsp;world&nbsp;of&nbsp;which&nbsp;the&nbsp;`cell`&nbsp;forms&nbsp;part.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;([_&nbsp;cell&nbsp;heightmap]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(tag-property&nbsp;cell&nbsp;:altitude&nbsp;heightmap))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;([cell&nbsp;heightmap]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(tag-property&nbsp;cell&nbsp;:altitude&nbsp;heightmap)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
095&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world,&nbsp;as&nbsp;defined&nbsp;in&nbsp;`world.clj`,&nbsp;q.v.;&nbsp;if&nbsp;world&nbsp;is&nbsp;not&nbsp;supplied,
<span class="covered" title="1 out of 1 forms covered">
096&nbsp;&nbsp;(defn&nbsp;apply-heightmap
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;world&nbsp;the&nbsp;size&nbsp;of&nbsp;the&nbsp;heightmap&nbsp;will&nbsp;be&nbsp;created;
097&nbsp;&nbsp;&nbsp;&nbsp;&quot;Apply&nbsp;the&nbsp;image&nbsp;file&nbsp;loaded&nbsp;from&nbsp;this&nbsp;path&nbsp;to&nbsp;this&nbsp;world,&nbsp;and&nbsp;return&nbsp;a&nbsp;world&nbsp;whose
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`imagepath`&nbsp;a&nbsp;file&nbsp;path&nbsp;or&nbsp;URL&nbsp;which&nbsp;indicates&nbsp;an&nbsp;(ideally&nbsp;greyscale)&nbsp;image&nbsp;file.&quot;
098&nbsp;&nbsp;&nbsp;&nbsp;altitudes&nbsp;are&nbsp;modified&nbsp;(added&nbsp;to)&nbsp;by&nbsp;the&nbsp;altitudes&nbsp;in&nbsp;the&nbsp;heightmap.&nbsp;It&nbsp;is&nbsp;assumed&nbsp;that
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;imagepath]
099&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;heightmap&nbsp;is&nbsp;at&nbsp;least&nbsp;as&nbsp;large&nbsp;in&nbsp;x&nbsp;and&nbsp;y&nbsp;dimensions&nbsp;as&nbsp;the&nbsp;world.&nbsp;Note&nbsp;that,&nbsp;in
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;addition&nbsp;to&nbsp;setting&nbsp;the&nbsp;`:altitude`&nbsp;of&nbsp;each&nbsp;cell,&nbsp;this&nbsp;function&nbsp;also&nbsp;sets&nbsp;the&nbsp;`:gradient`.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
101&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world,&nbsp;as&nbsp;defined&nbsp;in&nbsp;`world.clj`,&nbsp;q.v.;&nbsp;if&nbsp;world&nbsp;is&nbsp;not&nbsp;supplied,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;world&nbsp;the&nbsp;size&nbsp;of&nbsp;the&nbsp;heightmap&nbsp;will&nbsp;be&nbsp;created;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`imagepath`&nbsp;a&nbsp;file&nbsp;path&nbsp;or&nbsp;URL&nbsp;which&nbsp;indicates&nbsp;an&nbsp;(ideally&nbsp;greyscale)&nbsp;image&nbsp;file.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;imagepath]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[heightmap&nbsp;(filter-image
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[heightmap&nbsp;(filter-image
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(load-image&nbsp;imagepath)
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(load-image&nbsp;imagepath)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(filters&#x2F;grayscale))]
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(filters&#x2F;grayscale))]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;tag-altitude&nbsp;(list&nbsp;heightmap))
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;tag-altitude&nbsp;(list&nbsp;heightmap))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tag-gradient)))
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tag-gradient)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;([imagepath]
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;([imagepath]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[heightmap&nbsp;(filter-image
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[heightmap&nbsp;(filter-image
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(load-image&nbsp;imagepath)
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(load-image&nbsp;imagepath)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(filters&#x2F;grayscale))
115&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(filters&#x2F;grayscale))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world&nbsp;(make-world&nbsp;(.getWidth&nbsp;heightmap)&nbsp;(.getHeight&nbsp;heightmap))]
116&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world&nbsp;(make-world&nbsp;(.getWidth&nbsp;heightmap)&nbsp;(.getHeight&nbsp;heightmap))]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;tag-altitude&nbsp;(list&nbsp;heightmap))
118&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;tag-altitude&nbsp;(list&nbsp;heightmap))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tag-gradient))))
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tag-gradient))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
114&nbsp;&nbsp;
120&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
115&nbsp;&nbsp;(defn&nbsp;apply-valuemap
121&nbsp;&nbsp;(defn&nbsp;apply-valuemap
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&quot;Generalised&nbsp;from&nbsp;apply-heightmap,&nbsp;set&nbsp;an&nbsp;arbitrary&nbsp;property&nbsp;on&nbsp;each&nbsp;cell
122&nbsp;&nbsp;&nbsp;&nbsp;&quot;Generalised&nbsp;from&nbsp;apply-heightmap,&nbsp;set&nbsp;an&nbsp;arbitrary&nbsp;property&nbsp;on&nbsp;each&nbsp;cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;of&nbsp;this&nbsp;`world`&nbsp;from&nbsp;the&nbsp;values&nbsp;in&nbsp;this&nbsp;(ideally&nbsp;greyscale)&nbsp;heightmap.
123&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;of&nbsp;this&nbsp;`world`&nbsp;from&nbsp;the&nbsp;values&nbsp;in&nbsp;this&nbsp;(ideally&nbsp;greyscale)&nbsp;heightmap.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
118&nbsp;&nbsp;
124&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world,&nbsp;as&nbsp;defined&nbsp;in&nbsp;`world.clj`,&nbsp;q.v.;
125&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world,&nbsp;as&nbsp;defined&nbsp;in&nbsp;`world.clj`,&nbsp;q.v.;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`imagepath`&nbsp;a&nbsp;file&nbsp;path&nbsp;or&nbsp;URL&nbsp;which&nbsp;indicates&nbsp;an&nbsp;(ideally&nbsp;greyscale)&nbsp;image&nbsp;file;
126&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`imagepath`&nbsp;a&nbsp;file&nbsp;path&nbsp;or&nbsp;URL&nbsp;which&nbsp;indicates&nbsp;an&nbsp;(ideally&nbsp;greyscale)&nbsp;image&nbsp;file;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`property`&nbsp;the&nbsp;property&nbsp;of&nbsp;each&nbsp;cell&nbsp;whose&nbsp;value&nbsp;should&nbsp;be&nbsp;added&nbsp;to&nbsp;from&nbsp;the
127&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`property`&nbsp;the&nbsp;property&nbsp;of&nbsp;each&nbsp;cell&nbsp;whose&nbsp;value&nbsp;should&nbsp;be&nbsp;added&nbsp;to&nbsp;from&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
122&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intensity&nbsp;of&nbsp;the&nbsp;corresponding&nbsp;cell&nbsp;of&nbsp;the&nbsp;image.&quot;
128&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intensity&nbsp;of&nbsp;the&nbsp;corresponding&nbsp;cell&nbsp;of&nbsp;the&nbsp;image.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
123&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;imagepath&nbsp;property]
129&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;imagepath&nbsp;property]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[heightmap&nbsp;(filter-image
130&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[heightmap&nbsp;(filter-image
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(load-image&nbsp;imagepath)
131&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(load-image&nbsp;imagepath)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
126&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(filters&#x2F;grayscale))]
132&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(filters&#x2F;grayscale))]
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
127&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;tag-property&nbsp;(list&nbsp;property&nbsp;heightmap))))
133&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;tag-property&nbsp;(list&nbsp;property&nbsp;heightmap))))
</span><br/>
</body>
</html>

View file

@ -0,0 +1,302 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> mw_engine/render.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;mw-engine.render
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Render&nbsp;a&nbsp;world&nbsp;as&nbsp;HTML.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Adapted&nbsp;(simplified)&nbsp;from&nbsp;mw-ui.render-world;&nbsp;this&nbsp;is&nbsp;for&nbsp;visualisation,&nbsp;not
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interaction.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;TODO:&nbsp;but&nbsp;possibly&nbsp;it&nbsp;would&nbsp;be&nbsp;better&nbsp;if&nbsp;there&nbsp;is&nbsp;to&nbsp;be&nbsp;a&nbsp;newer&nbsp;version&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;mw-ui,&nbsp;to&nbsp;base&nbsp;it&nbsp;on&nbsp;this.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[hiccup2.core&nbsp;:refer&nbsp;[html]])
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
010&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;;;;;&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2024&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
031&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
032&nbsp;&nbsp;(def&nbsp;^:dynamic&nbsp;*state-images-relative-path*&nbsp;&quot;img&#x2F;tiles&#x2F;&quot;)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
033&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
034&nbsp;&nbsp;(defn&nbsp;format-css-class
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;&quot;Format&nbsp;this&nbsp;statekey,&nbsp;assumed&nbsp;to&nbsp;be&nbsp;a&nbsp;keyword&nbsp;indicating&nbsp;a&nbsp;state&nbsp;in&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world,&nbsp;into&nbsp;a&nbsp;CSS&nbsp;class&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;[statekey]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;(name&nbsp;statekey))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
039&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
040&nbsp;&nbsp;(defn&nbsp;format-image-path
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&quot;Render&nbsp;this&nbsp;statekey,&nbsp;assumed&nbsp;to&nbsp;be&nbsp;a&nbsp;keyword&nbsp;indicating&nbsp;a&nbsp;state&nbsp;in&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world,&nbsp;into&nbsp;a&nbsp;path&nbsp;which&nbsp;should&nbsp;recover&nbsp;the&nbsp;corresponding&nbsp;image&nbsp;file.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;[statekey]
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;(format&nbsp;&quot;%s%s.png&quot;&nbsp;*state-images-relative-path*&nbsp;(format-css-class&nbsp;statekey)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
045&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
046&nbsp;&nbsp;(defn&nbsp;format-mouseover&nbsp;[cell]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;cell))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
048&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
049&nbsp;&nbsp;(defn&nbsp;render-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&quot;Render&nbsp;this&nbsp;world&nbsp;cell&nbsp;as&nbsp;a&nbsp;Hiccup&nbsp;table&nbsp;cell.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;[cell]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[state&nbsp;(:state&nbsp;cell)]
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:td&nbsp;{:class&nbsp;(format-css-class&nbsp;state)&nbsp;:title&nbsp;(format-mouseover&nbsp;cell)}
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:img&nbsp;{:alt&nbsp;(:state&nbsp;cell)&nbsp;:src&nbsp;(format-image-path&nbsp;state)}]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
056&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
057&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
058&nbsp;&nbsp;(defn&nbsp;render-world-row
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&quot;Render&nbsp;this&nbsp;world&nbsp;row&nbsp;as&nbsp;a&nbsp;Hiccup&nbsp;table&nbsp;row.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;[row]
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;vector&nbsp;(cons&nbsp;:tr&nbsp;(map&nbsp;render-cell&nbsp;row))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
062&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
063&nbsp;&nbsp;(defn&nbsp;render-world-table
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&quot;Render&nbsp;this&nbsp;`world`&nbsp;as&nbsp;a&nbsp;complete&nbsp;HTML&nbsp;table&nbsp;in&nbsp;a&nbsp;DIV.&nbsp;If&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`state-images-relative-path`&nbsp;is&nbsp;passed,&nbsp;use&nbsp;that&nbsp;to&nbsp;override&nbsp;the&nbsp;default&nbsp;path.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;([world]&nbsp;
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:div&nbsp;{:class&nbsp;&quot;world&quot;}
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;vector
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;:table
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;render-world-row&nbsp;world)))
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:p
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;&quot;Generation&nbsp;&quot;&nbsp;(:generation&nbsp;(first&nbsp;(flatten&nbsp;world))))]])
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;state-images-relative-path]
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(binding&nbsp;[*state-images-relative-path*&nbsp;state-images-relative-path]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(render-world-table&nbsp;world))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
076&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
077&nbsp;&nbsp;(defn&nbsp;render-world-page
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;([world]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:html
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:head
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:title&nbsp;&quot;Rendered&nbsp;world&quot;]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:style&nbsp;&quot;div.world&nbsp;table,&nbsp;div.world&nbsp;table&nbsp;tr&nbsp;td&nbsp;{
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
083&nbsp;&nbsp; padding:&nbsp;0;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
084&nbsp;&nbsp; margin:&nbsp;0;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
085&nbsp;&nbsp; border-collapse:&nbsp;collapse;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
086&nbsp;&nbsp; border:&nbsp;none;}&quot;]]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:body
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(render-world-table&nbsp;world)]])
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;state-images-relative-path]
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(binding&nbsp;[*state-images-relative-path*&nbsp;state-images-relative-path]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(render-world-page&nbsp;world))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
092&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
093&nbsp;&nbsp;(defn&nbsp;world-&gt;html-file
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;output-path]
</span><br/>
<span class="not-covered" title="0 out of 18 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;(spit&nbsp;output-path&nbsp;(str&nbsp;(html&nbsp;(render-world-page&nbsp;world)))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;output-path&nbsp;state-images-relative-path]
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(binding&nbsp;[*state-images-relative-path*&nbsp;state-images-relative-path]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(world-&gt;html-file&nbsp;world&nbsp;output-path))))
</span><br/>
</body>
</html>

View file

@ -17,10 +17,10 @@
004&nbsp;&nbsp;&nbsp;mw-engine.utils
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;(:require
005&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[clojure.math.combinatorics&nbsp;:as&nbsp;combo]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.math.combinatorics&nbsp;:as&nbsp;combo]))
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.string&nbsp;:refer&nbsp;[join]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
007&nbsp;&nbsp;
@ -101,7 +101,7 @@
032&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;&#x27;true&#x27;&nbsp;if&nbsp;elt&nbsp;is&nbsp;a&nbsp;member&nbsp;of&nbsp;col,&nbsp;else&nbsp;&#x27;false&#x27;.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;[elt&nbsp;col]&nbsp;
033&nbsp;&nbsp;&nbsp;&nbsp;[elt&nbsp;col]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;(contains?&nbsp;(set&nbsp;col)&nbsp;elt))
@ -124,7 +124,7 @@
<span class="covered" title="4 out of 4 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[value&nbsp;(map&nbsp;property)]
</span><br/>
<span class="partial" title="5 out of 6 forms covered">
<span class="covered" title="6 out of 6 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(integer?&nbsp;value)&nbsp;value&nbsp;0)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
@ -424,8 +424,8 @@
<span class="blank" title="0 out of 0 forms covered">
140&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
141&nbsp;&nbsp;(defn&nbsp;get-num
<span class="covered" title="136 out of 136 forms covered">
141&nbsp;&nbsp;(defmacro&nbsp;get-num
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
142&nbsp;&nbsp;&nbsp;&nbsp;&quot;Get&nbsp;the&nbsp;value&nbsp;of&nbsp;a&nbsp;property&nbsp;expected&nbsp;to&nbsp;be&nbsp;a&nbsp;number&nbsp;from&nbsp;a&nbsp;map;&nbsp;if&nbsp;not
@ -445,20 +445,20 @@
<span class="not-tracked" title="0 out of 0 forms covered">
147&nbsp;&nbsp;&nbsp;&nbsp;[map&nbsp;key]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
148&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(map?&nbsp;map)
<span class="covered" title="1 out of 1 forms covered">
148&nbsp;&nbsp;&nbsp;&nbsp;`(if&nbsp;(map?&nbsp;~map)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
149&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[v&nbsp;(map&nbsp;key)]
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
150&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(and&nbsp;v&nbsp;(number?&nbsp;v))&nbsp;v
<span class="covered" title="2 out of 2 forms covered">
149&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[~&#x27;v&nbsp;(~map&nbsp;~key)]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
151&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;0))
150&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(and&nbsp;~&#x27;v&nbsp;(number?&nbsp;~&#x27;v))&nbsp;~&#x27;v
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
152&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(Exception.&nbsp;&quot;No&nbsp;map&nbsp;passed?&quot;))))
<span class="not-tracked" title="0 out of 0 forms covered">
151&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;0))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
152&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(Exception.&nbsp;&quot;No&nbsp;map&nbsp;passed?&quot;))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
153&nbsp;&nbsp;
@ -907,5 +907,239 @@
<span class="covered" title="1 out of 1 forms covered">
301&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
302&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
303&nbsp;&nbsp;(defn&nbsp;rule-type
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
304&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;the&nbsp;rule-type&nbsp;of&nbsp;this&nbsp;compiled&nbsp;`rule`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
305&nbsp;&nbsp;&nbsp;&nbsp;[rule]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
306&nbsp;&nbsp;&nbsp;&nbsp;(:rule-type&nbsp;(meta&nbsp;rule)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
307&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
308&nbsp;&nbsp;(defn&nbsp;add-history-event
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
309&nbsp;&nbsp;&nbsp;&nbsp;&quot;If&nbsp;`cell`&nbsp;is&nbsp;non-nil,&nbsp;expect&nbsp;it&nbsp;to&nbsp;be&nbsp;a&nbsp;map&nbsp;representing&nbsp;a&nbsp;cell;&nbsp;add
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
310&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;its&nbsp;history&nbsp;an&nbsp;an&nbsp;event&nbsp;recording&nbsp;the&nbsp;firing&nbsp;of&nbsp;this&nbsp;rule.&nbsp;If
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
311&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`detail`&nbsp;is&nbsp;passed,&nbsp;treat&nbsp;it&nbsp;as&nbsp;a&nbsp;map&nbsp;of&nbsp;additional&nbsp;data&nbsp;to&nbsp;be
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
312&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;added&nbsp;to&nbsp;the&nbsp;event.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
313&nbsp;&nbsp;&nbsp;&nbsp;([cell&nbsp;rule]
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
314&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when&nbsp;cell&nbsp;(add-history-event&nbsp;cell&nbsp;rule&nbsp;{})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
315&nbsp;&nbsp;&nbsp;&nbsp;([result&nbsp;rule&nbsp;detail]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
316&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when&nbsp;result
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
317&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[rule-meta&nbsp;(meta&nbsp;rule)
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
318&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event&nbsp;{:rule&nbsp;(:source&nbsp;rule-meta)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
319&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:rule-type&nbsp;(:rule-type&nbsp;rule-meta)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
320&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:generation&nbsp;(get-int-or-zero
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
321&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
322&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:generation)}
</span><br/>
<span class="partial" title="6 out of 7 forms covered">
323&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event&#x27;&nbsp;(if&nbsp;detail&nbsp;(merge&nbsp;event&nbsp;detail)&nbsp;event)]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
324&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;result
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
325&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:history&nbsp;(concat
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
326&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:history&nbsp;result)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
327&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;event&#x27;))})))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
328&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
329&nbsp;&nbsp;(defn-&nbsp;event-narrative&nbsp;[event]
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
330&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(:rule-type&nbsp;event)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
331&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:production&nbsp;(:rule&nbsp;event)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
332&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:flow&nbsp;(format&nbsp;&quot;%s&nbsp;%f&nbsp;units&nbsp;of&nbsp;%s&nbsp;%s&nbsp;%d,%d:\n&nbsp;&nbsp;&nbsp;&nbsp;%s&quot;
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
333&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(name&nbsp;(:direction&nbsp;event))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
334&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:quantity&nbsp;event)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
335&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:property&nbsp;event)
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
336&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(=&nbsp;:sent&nbsp;(:direction&nbsp;event))&nbsp;&quot;to&quot;&nbsp;&quot;from&quot;)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
337&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:x&nbsp;(:other&nbsp;event))
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
338&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:y&nbsp;(:other&nbsp;event))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
339&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:rule&nbsp;event))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
340&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
341&nbsp;&nbsp;(defn&nbsp;history-string
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
342&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;the&nbsp;history&nbsp;of&nbsp;this&nbsp;`cell`&nbsp;as&nbsp;a&nbsp;string&nbsp;for&nbsp;presentation&nbsp;to&nbsp;the&nbsp;user.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
343&nbsp;&nbsp;&nbsp;&nbsp;[cell]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
344&nbsp;&nbsp;&nbsp;&nbsp;(join&nbsp;&quot;\n&quot;
</span><br/>
<span class="not-covered" title="0 out of 12 forms covered">
345&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;#(format&nbsp;&quot;%6d:&nbsp;%s&quot;&nbsp;(:generation&nbsp;%)&nbsp;(event-narrative&nbsp;%))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
346&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:history&nbsp;cell))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
347&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
348&nbsp;&nbsp;(defn-&nbsp;extend-summary&nbsp;[summary&nbsp;rs&nbsp;rl&nbsp;event]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
349&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;summary
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
350&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;rs&nbsp;(format&nbsp;&quot;%d-%d&nbsp;(%d&nbsp;occurances):&nbsp;%s\n&quot;&nbsp;rs
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
351&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:generation&nbsp;event)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
352&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rl
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
353&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(event-narrative&nbsp;event))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
354&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(format&nbsp;&quot;%d:&nbsp;%s\n&quot;&nbsp;(:generation&nbsp;event)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
355&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(event-narrative&nbsp;event)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
356&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
357&nbsp;&nbsp;(defn&nbsp;summarise-history
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
358&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return,&nbsp;as&nbsp;a&nbsp;string,&nbsp;a&nbsp;shorter&nbsp;summary&nbsp;of&nbsp;the&nbsp;history&nbsp;of&nbsp;this&nbsp;cell&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
359&nbsp;&nbsp;&nbsp;&nbsp;[cell]
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
360&nbsp;&nbsp;&nbsp;&nbsp;(loop&nbsp;[history&nbsp;(rest&nbsp;(:history&nbsp;cell))
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
361&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event&nbsp;(first&nbsp;(:history&nbsp;cell))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
362&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev&nbsp;nil
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
363&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rs&nbsp;nil
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
364&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rl&nbsp;0
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
365&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;summary&nbsp;&quot;&quot;]
</span><br/>
<span class="not-covered" title="0 out of 12 forms covered">
366&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(nil?&nbsp;event)&nbsp;(extend-summary&nbsp;summary&nbsp;rs&nbsp;rl&nbsp;prev)
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
367&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(:rule&nbsp;event)&nbsp;(:rule&nbsp;prev))&nbsp;(recur
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
368&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rest&nbsp;history)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
369&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(first&nbsp;history)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
370&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
371&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;rs&nbsp;(:generation&nbsp;event))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
372&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(inc&nbsp;rl)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
373&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;summary)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
374&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(recur&nbsp;(rest&nbsp;history)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
375&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(first&nbsp;history)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
376&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
377&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nil
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
378&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
379&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(extend-summary&nbsp;summary&nbsp;rs&nbsp;(inc&nbsp;rl)&nbsp;event)))))
</span><br/>
</body>
</html>

View file

@ -115,161 +115,227 @@
<span class="blank" title="0 out of 0 forms covered">
037&nbsp;&nbsp;
</span><br/>
<span class="covered" title="30 out of 30 forms covered">
038&nbsp;&nbsp;(defmacro&nbsp;make-cell
<span class="covered" title="1 out of 1 forms covered">
038&nbsp;&nbsp;(defn&nbsp;cell?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&quot;Create&nbsp;a&nbsp;minimal&nbsp;default&nbsp;cell&nbsp;at&nbsp;x,&nbsp;y
039&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;`true`&nbsp;if&nbsp;`obj`&nbsp;is&nbsp;a&nbsp;cell,&nbsp;as&nbsp;understood&nbsp;by&nbsp;MicroWorld,&nbsp;else&nbsp;`false`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;[obj]
</span><br/>
<span class="not-covered" title="0 out of 16 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(map?&nbsp;obj)&nbsp;;;&nbsp;it&#x27;s&nbsp;a&nbsp;map...
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;TODO:&nbsp;it&#x27;s&nbsp;worth&nbsp;checking&nbsp;(and&nbsp;this&nbsp;does&nbsp;not)&nbsp;that&nbsp;cells&nbsp;have&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;right&nbsp;co-ordinates!
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pos-int?&nbsp;(:x&nbsp;obj))&nbsp;;;&nbsp;with&nbsp;an&nbsp;x&nbsp;co-ordinate...
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pos-int?&nbsp;(:y&nbsp;obj))&nbsp;;;&nbsp;and&nbsp;a&nbsp;y&nbsp;co-ordinate...
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(keyword?&nbsp;(:state&nbsp;obj))))&nbsp;;;&nbsp;and&nbsp;a&nbsp;state&nbsp;which&nbsp;is&nbsp;a&nbsp;keyword.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
040&nbsp;&nbsp;
047&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
048&nbsp;&nbsp;(defn&nbsp;world?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`x`&nbsp;the&nbsp;x&nbsp;coordinate&nbsp;at&nbsp;which&nbsp;this&nbsp;cell&nbsp;is&nbsp;created;
049&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;`true`&nbsp;if&nbsp;`obj`&nbsp;is&nbsp;a&nbsp;world,&nbsp;as&nbsp;understood&nbsp;by&nbsp;MicroWorld,&nbsp;else&nbsp;`false`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`y`&nbsp;the&nbsp;y&nbsp;coordinate&nbsp;at&nbsp;which&nbsp;this&nbsp;cell&nbsp;is&nbsp;created.&quot;
050&nbsp;&nbsp;&nbsp;&nbsp;[obj]
</span><br/>
<span class="not-covered" title="0 out of 16 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(coll?&nbsp;obj)&nbsp;;;&nbsp;it&#x27;s&nbsp;a&nbsp;collection...
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;coll?&nbsp;obj)&nbsp;;;&nbsp;of&nbsp;collections...
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;1&nbsp;(count&nbsp;(set&nbsp;(map&nbsp;count&nbsp;obj))))&nbsp;;;&nbsp;all&nbsp;of&nbsp;which&nbsp;are&nbsp;the&nbsp;same&nbsp;length...
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(every?&nbsp;cell?&nbsp;(flatten&nbsp;obj))))&nbsp;;;&nbsp;and&nbsp;every&nbsp;element&nbsp;of&nbsp;each&nbsp;of&nbsp;those&nbsp;is&nbsp;a&nbsp;cell.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
055&nbsp;&nbsp;
</span><br/>
<span class="covered" title="30 out of 30 forms covered">
056&nbsp;&nbsp;(defmacro&nbsp;make-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;[x&nbsp;y]
057&nbsp;&nbsp;&nbsp;&nbsp;&quot;Create&nbsp;a&nbsp;minimal&nbsp;default&nbsp;cell&nbsp;at&nbsp;x,&nbsp;y
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
058&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`x`&nbsp;the&nbsp;x&nbsp;coordinate&nbsp;at&nbsp;which&nbsp;this&nbsp;cell&nbsp;is&nbsp;created;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`y`&nbsp;the&nbsp;y&nbsp;coordinate&nbsp;at&nbsp;which&nbsp;this&nbsp;cell&nbsp;is&nbsp;created.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;[x&nbsp;y]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;`{:x&nbsp;~x&nbsp;:y&nbsp;~y&nbsp;:state&nbsp;:new})
062&nbsp;&nbsp;&nbsp;&nbsp;`{:x&nbsp;~x&nbsp;:y&nbsp;~y&nbsp;:state&nbsp;:new})
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
045&nbsp;&nbsp;
063&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
046&nbsp;&nbsp;(defn&nbsp;make-world
064&nbsp;&nbsp;(defn&nbsp;make-world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&quot;Make&nbsp;a&nbsp;world&nbsp;width&nbsp;cells&nbsp;from&nbsp;east&nbsp;to&nbsp;west,&nbsp;and&nbsp;height&nbsp;cells&nbsp;from&nbsp;north&nbsp;to
065&nbsp;&nbsp;&nbsp;&nbsp;&quot;Make&nbsp;a&nbsp;world&nbsp;width&nbsp;cells&nbsp;from&nbsp;east&nbsp;to&nbsp;west,&nbsp;and&nbsp;height&nbsp;cells&nbsp;from&nbsp;north&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;south.
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;south.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
049&nbsp;&nbsp;
067&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`width`&nbsp;a&nbsp;natural&nbsp;number&nbsp;representing&nbsp;the&nbsp;width&nbsp;of&nbsp;the&nbsp;matrix&nbsp;to&nbsp;be&nbsp;created;
068&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`width`&nbsp;a&nbsp;natural&nbsp;number&nbsp;representing&nbsp;the&nbsp;width&nbsp;of&nbsp;the&nbsp;matrix&nbsp;to&nbsp;be&nbsp;created;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`height`&nbsp;a&nbsp;natural&nbsp;number&nbsp;representing&nbsp;the&nbsp;height&nbsp;of&nbsp;the&nbsp;matrix&nbsp;to&nbsp;be&nbsp;created.&quot;
069&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`height`&nbsp;a&nbsp;natural&nbsp;number&nbsp;representing&nbsp;the&nbsp;height&nbsp;of&nbsp;the&nbsp;matrix&nbsp;to&nbsp;be&nbsp;created.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;[width&nbsp;height]
070&nbsp;&nbsp;&nbsp;&nbsp;[width&nbsp;height]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;vector
071&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;vector
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;(fn&nbsp;[h]
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;(fn&nbsp;[h]
</span><br/>
<span class="covered" title="16 out of 16 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;vector&nbsp;(map&nbsp;#(make-cell&nbsp;%&nbsp;h)&nbsp;(range&nbsp;width))))
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;vector&nbsp;(map&nbsp;#(make-cell&nbsp;%&nbsp;h)&nbsp;(range&nbsp;width))))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(range&nbsp;height))))
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(range&nbsp;height))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
057&nbsp;&nbsp;
075&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
058&nbsp;&nbsp;(defn&nbsp;truncate-state
076&nbsp;&nbsp;(defn&nbsp;truncate-state
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&quot;Truncate&nbsp;the&nbsp;print&nbsp;name&nbsp;of&nbsp;the&nbsp;state&nbsp;of&nbsp;this&nbsp;cell&nbsp;to&nbsp;at&nbsp;most&nbsp;limit&nbsp;characters.&quot;
077&nbsp;&nbsp;&nbsp;&nbsp;&quot;Truncate&nbsp;the&nbsp;print&nbsp;name&nbsp;of&nbsp;the&nbsp;state&nbsp;of&nbsp;this&nbsp;cell&nbsp;to&nbsp;at&nbsp;most&nbsp;limit&nbsp;characters.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;[cell&nbsp;limit]
078&nbsp;&nbsp;&nbsp;&nbsp;[cell&nbsp;limit]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[s&nbsp;(:state&nbsp;cell)]
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(&gt;&nbsp;(count&nbsp;(str&nbsp;s))&nbsp;limit)&nbsp;(subs&nbsp;s&nbsp;0&nbsp;limit)
079&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[s&nbsp;(:state&nbsp;cell)]
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;s)))
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="not-covered" title="0 out of 15 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(&gt;&nbsp;(count&nbsp;(str&nbsp;s))&nbsp;limit)&nbsp;(subs&nbsp;(name&nbsp;s)&nbsp;0&nbsp;limit)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;s)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;any&nbsp;
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(ex-info&nbsp;(.getMessage&nbsp;any)&nbsp;
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:cell&nbsp;cell
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:limit&nbsp;limit
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:exception-class&nbsp;(.getClass&nbsp;any)}))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
064&nbsp;&nbsp;
088&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
065&nbsp;&nbsp;(defn&nbsp;format-cell
089&nbsp;&nbsp;(defn&nbsp;format-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;formatted&nbsp;string&nbsp;summarising&nbsp;the&nbsp;current&nbsp;state&nbsp;of&nbsp;this&nbsp;cell.&quot;
090&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;formatted&nbsp;string&nbsp;summarising&nbsp;the&nbsp;current&nbsp;state&nbsp;of&nbsp;this&nbsp;cell.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;[cell]
091&nbsp;&nbsp;&nbsp;&nbsp;[cell]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;(format&nbsp;&quot;%10s(%2d&#x2F;%2d)&quot;
092&nbsp;&nbsp;&nbsp;&nbsp;(format&nbsp;&quot;%10s&quot;
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(truncate-state&nbsp;cell&nbsp;10)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(population&nbsp;cell&nbsp;:deer)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(population&nbsp;cell&nbsp;:wolves)))
093&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(truncate-state&nbsp;cell&nbsp;10)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
072&nbsp;&nbsp;
094&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
073&nbsp;&nbsp;(defn-&nbsp;format-world-row
095&nbsp;&nbsp;(defn-&nbsp;format-world-row
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&quot;Format&nbsp;one&nbsp;row&nbsp;in&nbsp;the&nbsp;state&nbsp;of&nbsp;a&nbsp;world&nbsp;for&nbsp;printing.&quot;
096&nbsp;&nbsp;&nbsp;&nbsp;&quot;Format&nbsp;one&nbsp;row&nbsp;in&nbsp;the&nbsp;state&nbsp;of&nbsp;a&nbsp;world&nbsp;for&nbsp;printing.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;[row]
097&nbsp;&nbsp;&nbsp;&nbsp;[row]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;(string&#x2F;join&nbsp;(map&nbsp;format-cell&nbsp;row)))
098&nbsp;&nbsp;&nbsp;&nbsp;(string&#x2F;join&nbsp;(map&nbsp;format-cell&nbsp;row)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
077&nbsp;&nbsp;
099&nbsp;&nbsp;
</span><br/>
<span class="partial" title="1 out of 2 forms covered">
078&nbsp;&nbsp;(defn&nbsp;print-world
100&nbsp;&nbsp;(defn&nbsp;print-world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&quot;Print&nbsp;the&nbsp;current&nbsp;state&nbsp;of&nbsp;this&nbsp;world,&nbsp;and&nbsp;return&nbsp;nil.
101&nbsp;&nbsp;&nbsp;&nbsp;&quot;Print&nbsp;the&nbsp;current&nbsp;state&nbsp;of&nbsp;this&nbsp;world,&nbsp;and&nbsp;return&nbsp;nil.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
080&nbsp;&nbsp;
102&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world&nbsp;as&nbsp;defined&nbsp;above.&quot;
103&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world&nbsp;as&nbsp;defined&nbsp;above.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;[world]
104&nbsp;&nbsp;&nbsp;&nbsp;[world]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;(println)
105&nbsp;&nbsp;&nbsp;&nbsp;(println)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;(dorun
106&nbsp;&nbsp;&nbsp;&nbsp;(dorun
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(println
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(println
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(format-world-row&nbsp;%))
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(format-world-row&nbsp;%))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world))
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;nil)
111&nbsp;&nbsp;&nbsp;&nbsp;nil)
</span><br/>
</body>
</html>

View file

@ -4,7 +4,9 @@
:doc/format :markdown}
:output-path "docs/codox"
:source-uri "https://github.com/simon-brooke/mw-engine/blob/master/{filepath}#L{line}"}
:dependencies [[org.clojure/clojure "1.11.1"]
:dependencies [[com.github.pmonks/embroidery "0.1.20"] ;; better pmap?
[distributions "0.1.2"] ;; mainly for investigating drainage
[org.clojure/clojure "1.11.1"]
[org.clojure/clojurescript "1.11.60" :scope "provided"]
[org.clojure/math.combinatorics "0.2.0"]
[org.clojure/tools.trace "0.7.11"]

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

1
resources/test.edn Normal file
View file

@ -0,0 +1 @@
{:hello "goodbye"}

View file

@ -22,7 +22,8 @@
further rules can be applied to that cell."
:author "Simon Brooke"}
mw-engine.core
(:require [mw-engine.flow :refer [flow-world]]
(:require [clojure.set :refer [difference]]
[mw-engine.flow :refer [flow-world]]
[mw-engine.utils :refer [add-history-event get-int-or-zero map-world rule-type]]
[taoensso.timbre :as l]))
@ -54,6 +55,10 @@
memory problems. Make it optional, but by default false."
false)
(def known-rule-types
"Types of rules we know about."
#{:ad-hoc :flow :production})
(defn apply-rule
"Apply a single `rule` to a `cell`. What this is about is that I want to be able,
for debugging purposes, to tag a cell with the rule text of the rule which
@ -119,27 +124,37 @@
;; Yes, that `list` is there for a reason!
(list
(filter
#(= :production (rule-type %))
#(#{:ad-hoc :production} (rule-type %))
rules))))
(defn run-world
"Run this world with these rules for this number of generations.
"Run this `world` with these `rules` for this number of `generations`.
* `world` a world as discussed above;
* `init-rules` a sequence of rules as defined above, to be run once to initialise the world;
* `rules` a sequence of rules as defined above, to be run iteratively for each generation;
* `generations` an (integer) number of generations.
**NOTE THAT** all rules **must** be tagged with `rule-type` metadata, or thet **will not**
**NOTE THAT** all rules **must** be tagged with `rule-type` metadata, or they **will not**
be executed.
Return the final generation of the world."
([world rules generations]
(run-world world rules rules (dec generations)))
([world init-rules rules generations]
(reduce (fn [world iteration]
(l/info "Running iteration " iteration)
(let [w' (transform-world world rules)]
(flow-world w' rules)))
(transform-world world init-rules)
(range generations))))
(let [found-types (map rule-type (concat init-rules rules))]
(if (every? known-rule-types found-types)
(reduce (fn [world iteration]
(l/info "Running iteration " iteration)
(let [w' (transform-world world rules)]
(flow-world w' rules)))
(transform-world world init-rules)
(range generations))
(let [unexpected (difference (set found-types) known-rule-types)]
(throw
(ex-info (format
"Unexpected rule type(s) %s found. Expected types are %s"
unexpected
known-rule-types)
{:types unexpected})))))))

View file

@ -2,12 +2,13 @@
compute drainage on a world, assumed to have altitudes already set
from a heightmap."
:author "Simon Brooke"}
mw-engine.drainage
mw-engine.drainage
(:require [mw-engine.core :refer [run-world]]
[mw-engine.heightmap :as heightmap]
[mw-engine.heightmap :refer [apply-heightmap]]
[mw-engine.utils :refer [get-int-or-zero get-least-cell get-neighbours
get-neighbours-with-property-value
map-world]]))
map-world]]
[taoensso.timbre :refer [info]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
@ -42,17 +43,17 @@
"Compute rainfall for a cell with this `gradient` west-east, given
`remaining` drops to distribute, and this overall map width."
[gradient remaining map-width]
(cond
(cond
;; if there's no rain left in the cloud, it can't fall;
(zero? remaining)
0
(pos? gradient)
(zero? remaining)
0
(pos? gradient)
;; rain, on prevailing westerly wind, falls preferentially on rising ground;
(int (rand gradient))
(int (rand gradient))
;; rain falls randomly across the width of the map...
(zero? (int (rand map-width))) 1
:else
0))
(zero? (int (rand map-width))) 1
:else
0))
(defn rain-row
"Return a row like this `row`, across which rainfall has been distributed;
@ -71,12 +72,12 @@
rising (- alt previous-altitude)
fall (rainfall rising drops-in-cloud map-width)]
(cons
(assoc cell :rainfall fall)
(rain-row (rest row) map-width alt (- drops-in-cloud fall))))
(assoc cell :rainfall fall)
(rain-row (rest row) map-width alt (- drops-in-cloud fall))))
:else
(map
#(assoc % :rainfall 0)
row))))
#(assoc % :rainfall 0)
row))))
(defn rain-world
@ -84,8 +85,8 @@
rain more on west-facing slopes, and less to the east of high ground"
[world]
(map
rain-row
world))
rain-row
world))
(defn flow-contributors
@ -95,14 +96,14 @@
[cell world]
(filter #(map? %)
(map
(fn [n]
(cond
(= cell (get-least-cell (get-neighbours world n) :altitude)) n
(and (= (:altitude cell) (:altitude n))
(> (or (:flow n) 0) (or (:flow cell) 0))) n))
(get-neighbours-with-property-value
world (:x cell) (:y cell) 1 :altitude
(or (:altitude cell) 0) >=))))
(fn [n]
(cond
(= cell (get-least-cell (get-neighbours world n) :altitude)) n
(and (= (:altitude cell) (:altitude n))
(> (or (:flow n) 0) (or (:flow cell) 0))) n))
(get-neighbours-with-property-value
world (:x cell) (:y cell) 1 :altitude
(or (:altitude cell) 0) >=))))
(defn is-hollow
@ -116,17 +117,17 @@
altitude (get-int-or-zero cell :altitude)]
(= (count neighbours)
(count (get-neighbours-with-property-value
world (:x cell) (:y cell) 1 :altitude altitude >)))))
world (:x cell) (:y cell) 1 :altitude altitude >)))))
(defn flood-hollow
"Raise the altitude of a copy of this `cell` of this `world` to the altitude
of the lowest of its `neighbours`."
([_world cell neighbours]
(let [lowest (get-least-cell neighbours :altitude)]
(merge cell {:state :water :altitude (:altitude lowest)})))
(let [lowest (get-least-cell neighbours :altitude)]
(merge cell {:state :water :altitude (:altitude lowest)})))
([world cell]
(flood-hollow world cell (get-neighbours world cell))))
(flood-hollow world cell (get-neighbours world cell))))
(defn flood-hollows
@ -146,14 +147,21 @@
`flow-world-nr`."
[cell world]
(when (= (- max-altitude (get-int-or-zero cell :generation))
(get-int-or-zero cell :altitude))
(merge cell
{:flow (reduce +
(map
#(+ (get-int-or-zero % :rainfall)
(get-int-or-zero % :flow))
(flow-contributors cell world)))})))
(get-int-or-zero cell :altitude))
(let [contributors (flow-contributors cell world)]
(when contributors
(merge cell
{:flow (reduce +
(map
#(+ (get-int-or-zero % :rainfall)
(get-int-or-zero % :flow))
contributors))})))))
(defn flow-nr-wrapper
[cell world]
(do
(info (format "Flowing cell at %d, %d" (:x cell) (:y cell)))
(flow-nr cell world)))
(def flow
"Compute the total flow upstream of this `cell` in this `world`, and return a cell identical
@ -165,20 +173,19 @@
(memoize
(fn [cell world]
(cond
(not (nil? (:flow cell))) cell
(<= (or (:altitude cell) 0) *sealevel*) cell
:else
(merge cell
{:flow (+ (:rainfall cell)
(apply +
(map (fn [neighbour] (:flow (flow neighbour world)))
(flow-contributors cell world))))})))))
(not (nil? (:flow cell))) cell
(<= (or (:altitude cell) 0) *sealevel*) cell
:else
(merge cell
{:flow (+ (:rainfall cell)
(apply +
(map (fn [neighbour] (:flow (flow neighbour world)))
(flow-contributors cell world))))})))))
(defn flow-world-nr
"Experimental non-recursive flow-world algorithm"
[world]
(run-world world nil (list flow-nr) max-altitude))
(run-world world (list (vary-meta flow-nr assoc :rule-type :ad-hoc)) max-altitude))
(defn flow-world
"Return a world like this `world`, but with cells tagged with the amount of
@ -189,8 +196,7 @@
(defn explore-lake
"Return a sequence of cells starting with this `cell` in this `world` which
form a contiguous lake"
[_world _cell]
)
[_world _cell])
(defn is-lake?
"If this `cell` in this `world` is not part of a lake, return nil. If it is,
@ -198,20 +204,21 @@
[world cell]
(if
;; if it's already tagged as a lake, it's a lake
(:lake cell) cell
(let
[outflow (apply min (map :altitude (get-neighbours world cell)))]
(when-not
(> (:altitude cell) outflow)
(assoc cell :lake true)))))
(:lake cell) cell
(let
[outflow (apply min (map :altitude (get-neighbours world cell)))]
(when-not
(> (:altitude cell) outflow)
(assoc cell :lake true :state :lake)))))
(defn find-lakes
[_world]
)
[_world])
(defn run-drainage
"Create a world from the heightmap `hmap`, rain on it, and then compute river
flows."
[hmap]
(flow-world (rain-world (flood-hollows (heightmap/apply-heightmap hmap)))))
(flow-world (rain-world (flood-hollows (apply-heightmap hmap)))))
;; (run-drainage "resources/heightmaps/20x20/crucible.png")

View file

@ -32,12 +32,6 @@
;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn abs
"Prior to Clojure 1.11, there is no native `abs` function. Afterwards, there
is."
[n]
(Math/abs n))
(defn tag-property
"Set the value of this `property` of this cell from the corresponding pixel of this `heightmap`.
If the heightmap you supply is smaller than the world, this will break.

View file

@ -35,7 +35,7 @@
"Format this statekey, assumed to be a keyword indicating a state in the
world, into a CSS class"
[statekey]
(name statekey))
(when statekey (name statekey)))
(defn format-image-path
"Render this statekey, assumed to be a keyword indicating a state in the

View file

@ -3,7 +3,8 @@
:author "Simon Brooke"}
mw-engine.utils
(:require [clojure.math.combinatorics :as combo]
[clojure.string :refer [join]]))
[clojure.string :refer [join]]
[embroidery.api :refer [pmap*]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
@ -108,7 +109,7 @@
(map-world world function nil))
([world function additional-args]
(into []
(pmap (fn [row]
(pmap* (fn [row]
(into [] (map
#(apply function
(cons world (cons % additional-args)))

View file

@ -1,134 +0,0 @@
(ns ^{:doc "Functions to transform a world and run rules."
:author "Simon Brooke"}
mw-engine.core
(:require [clojure.core.reducers :as r]
[clojure.string :refer [join]]
[mw-engine.world :as world]
[mw-engine.utils :refer [get-int-or-zero map-world]]
[taoensso.timbre :as l]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
;;;; mw-engine: the state/transition engine of MicroWorld.
;;;;
;;;; This program is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU General Public License
;;;; as published by the Free Software Foundation; either version 2
;;;; of the License, or (at your option) any later version.
;;;;
;;;; This program is distributed in the hope that it will be useful,
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;;; GNU General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU General Public License
;;;; along with this program; if not, write to the Free Software
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
;;;; USA.
;;;;
;;;; Copyright (C) 2014 Simon Brooke
;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
;;;; Every rule is a function of two arguments, a cell and a world. If the rule
;;;; fires, it returns a new cell, which should have the same values for :x and
;;;; :y as the old cell. Anything else can be modified.
;;;;
;;;; While any function of two arguments can be used as a rule, a special high
;;;; level rule language is provided by the `mw-parser` package, which compiles
;;;; rules expressed in a subset of English rules into suitable functions.
;;;;
;;;; A cell is a map containing at least values for the keys :x, :y, and :state;
;;;; a transformation should not alter the values of :x or :y, and should not
;;;; return a cell without a keyword as the value of :state. Anything else is
;;;; legal.
;;;;
;;;; A world is a two dimensional matrix (sequence of sequences) of cells, such
;;;; that every cell's :x and :y properties reflect its place in the matrix.
;;;; See `world.clj`.
;;;;
;;;; Each time the world is transformed (see `transform-world`, for each cell,
;;;; rules are applied in turn until one matches. Once one rule has matched no
;;;; further rules can be applied.
;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn apply-rule
"Apply a single `rule` to a `cell`. What this is about is that I want to be able,
for debugging purposes, to tag a cell with the rule text of the rule which
fired (and especially so when an exception is thrown. So a rule may be either
an ifn, or a list (ifn source-text). This function deals with despatching
on those two possibilities. `world` is also passed in in order to be able
to access neighbours."
([world cell rule]
(cond
(ifn? rule) (apply-rule world cell rule nil)
(seq? rule) (let [[afn src] rule] (apply-rule world cell afn src))))
([world cell rule source]
(let [result (apply rule (list cell world))]
(cond
(and result source) (merge result {:rule source})
true result))))
(defn- apply-rules
"Derive a cell from this `cell` of this `world` by applying these `rules`."
[world cell rules]
(cond (empty? rules) cell
true (let [result (apply-rule world cell (first rules))]
(cond result result
true (apply-rules world cell (rest rules))))))
(defn- transform-cell
"Derive a cell from this `cell` of this `world` by applying these `rules`. If an
exception is thrown, cache its message on the cell and set it's state to error"
[world cell rules]
(try
(merge
(apply-rules world cell rules)
{:generation (+ (get-int-or-zero cell :generation) 1)})
(catch Exception e
(merge cell {:error
(format "%s at generation %d when in state %s"
(.getMessage e)
(:generation cell)
(:state cell))
:stacktrace (map #(.toString %) (.getStackTrace e))
:state :error}))))
(defn transform-world
"Return a world derived from this `world` by applying these `rules` to each cell."
[world rules]
(map-world world transform-cell (list rules)))
(defn- transform-world-state
"Consider this single argument as a map of `:world` and `:rules`; apply the rules
to transform the world, and return a map of the new, transformed `:world` and
these `:rules`. As a side effect, print the world."
[state]
(let [world (transform-world (:world state) (:rules state))]
;;(world/print-world world)
{:world world :rules (:rules state)}))
(defn run-world
"Run this world with these rules for this number of generations.
* `world` a world as discussed above;
* `init-rules` a sequence of rules as defined above, to be run once to initialise the world;
* `rules` a sequence of rules as defined above, to be run iteratively for each generation;
* `generations` an (integer) number of generations.
Return the final generation of the world."
[world init-rules rules generations]
(reduce (fn [world iteration]
(l/info "Running iteration " iteration)
(transform-world world rules))
(transform-world world init-rules)
(range generations)))