drainage/flow-world-nr now works; drainage/flow-world still doesn't
This commit is contained in:
parent
93dab8067b
commit
e19ce2e5f7
|
@ -16,20 +16,20 @@
|
||||||
</tr></thead>
|
</tr></thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="mw_engine/core.clj.html">mw-engine.core</a></td><td class="with-bar"><div class="covered"
|
<td><a href="mw_engine/core.clj.html">mw-engine.core</a></td><td class="with-bar"><div class="covered"
|
||||||
style="width:33.116883116883116%;
|
style="width:37.185929648241206%;
|
||||||
float:left;"> 51 </div><div class="not-covered"
|
float:left;"> 74 </div><div class="not-covered"
|
||||||
style="width:66.88311688311688%;
|
style="width:62.814070351758794%;
|
||||||
float:left;"> 103 </div></td>
|
float:left;"> 125 </div></td>
|
||||||
<td class="with-number">33.12 %</td>
|
<td class="with-number">37.19 %</td>
|
||||||
<td class="with-bar"><div class="covered"
|
<td class="with-bar"><div class="covered"
|
||||||
style="width:36.36363636363637%;
|
style="width:50.0%;
|
||||||
float:left;"> 12 </div><div class="partial"
|
float:left;"> 26 </div><div class="partial"
|
||||||
style="width:3.0303030303030303%;
|
style="width:1.9230769230769231%;
|
||||||
float:left;"> 1 </div><div class="not-covered"
|
float:left;"> 1 </div><div class="not-covered"
|
||||||
style="width:60.60606060606061%;
|
style="width:48.07692307692308%;
|
||||||
float:left;"> 20 </div></td>
|
float:left;"> 25 </div></td>
|
||||||
<td class="with-number">39.39 %</td>
|
<td class="with-number">51.92 %</td>
|
||||||
<td class="with-number">115</td><td class="with-number">15</td><td class="with-number">33</td>
|
<td class="with-number">145</td><td class="with-number">13</td><td class="with-number">52</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="mw_engine/display.clj.html">mw-engine.display</a></td><td class="with-bar"><div class="covered"
|
<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>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="mw_engine/flow.clj.html">mw-engine.flow</a></td><td class="with-bar"><div class="covered"
|
<td><a href="mw_engine/flow.clj.html">mw-engine.flow</a></td><td class="with-bar"><div class="covered"
|
||||||
style="width:86.62790697674419%;
|
style="width:77.65957446808511%;
|
||||||
float:left;"> 447 </div><div class="not-covered"
|
float:left;"> 511 </div><div class="not-covered"
|
||||||
style="width:13.372093023255815%;
|
style="width:22.340425531914892%;
|
||||||
float:left;"> 69 </div></td>
|
float:left;"> 147 </div></td>
|
||||||
<td class="with-number">86.63 %</td>
|
<td class="with-number">77.66 %</td>
|
||||||
<td class="with-bar"><div class="covered"
|
<td class="with-bar"><div class="covered"
|
||||||
style="width:85.45454545454545%;
|
style="width:67.5%;
|
||||||
float:left;"> 47 </div><div class="partial"
|
float:left;"> 54 </div><div class="partial"
|
||||||
style="width:7.2727272727272725%;
|
style="width:10.0%;
|
||||||
float:left;"> 4 </div><div class="not-covered"
|
float:left;"> 8 </div><div class="not-covered"
|
||||||
style="width:7.2727272727272725%;
|
style="width:22.5%;
|
||||||
float:left;"> 4 </div></td>
|
float:left;"> 18 </div></td>
|
||||||
<td class="with-number">92.73 %</td>
|
<td class="with-number">77.50 %</td>
|
||||||
<td class="with-number">141</td><td class="with-number">15</td><td class="with-number">55</td>
|
<td class="with-number">179</td><td class="with-number">18</td><td class="with-number">80</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="mw_engine/heightmap.clj.html">mw-engine.heightmap</a></td><td class="with-bar"><div class="covered"
|
<td><a href="mw_engine/heightmap.clj.html">mw-engine.heightmap</a></td><td class="with-bar"><div class="covered"
|
||||||
style="width:92.51700680272108%;
|
style="width:92.71523178807946%;
|
||||||
float:left;"> 136 </div><div class="not-covered"
|
float:left;"> 140 </div><div class="not-covered"
|
||||||
style="width:7.482993197278912%;
|
style="width:7.28476821192053%;
|
||||||
float:left;"> 11 </div></td>
|
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"
|
<td class="with-bar"><div class="covered"
|
||||||
style="width:90.9090909090909%;
|
style="width:91.30434782608695%;
|
||||||
float:left;"> 40 </div><div class="partial"
|
float:left;"> 42 </div><div class="partial"
|
||||||
style="width:4.545454545454546%;
|
style="width:4.3478260869565215%;
|
||||||
float:left;"> 2 </div><div class="not-covered"
|
float:left;"> 2 </div><div class="not-covered"
|
||||||
style="width:4.545454545454546%;
|
style="width:4.3478260869565215%;
|
||||||
float:left;"> 2 </div></td>
|
float:left;"> 2 </div></td>
|
||||||
<td class="with-number">95.45 %</td>
|
<td class="with-number">95.65 %</td>
|
||||||
<td class="with-number">127</td><td class="with-number">11</td><td class="with-number">44</td>
|
<td class="with-number">133</td><td class="with-number">12</td><td class="with-number">46</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="mw_engine/natural_rules.clj.html">mw-engine.natural-rules</a></td><td class="with-bar"><div class="covered"
|
<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>
|
<td class="with-number">184</td><td class="with-number">14</td><td class="with-number">106</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="mw_engine/utils.clj.html">mw-engine.utils</a></td><td class="with-bar"><div class="covered"
|
<td><a href="mw_engine/render.clj.html">mw-engine.render</a></td><td class="with-bar"><div class="covered"
|
||||||
style="width:69.88847583643123%;
|
style="width:6.875%;
|
||||||
float:left;"> 376 </div><div class="not-covered"
|
float:left;"> 11 </div><div class="not-covered"
|
||||||
style="width:30.111524163568774%;
|
style="width:93.125%;
|
||||||
float:left;"> 162 </div></td>
|
float:left;"> 149 </div></td>
|
||||||
<td class="with-number">69.89 %</td>
|
<td class="with-number">6.88 %</td>
|
||||||
<td class="with-bar"><div class="covered"
|
<td class="with-bar"><div class="covered"
|
||||||
style="width:73.21428571428571%;
|
style="width:27.77777777777778%;
|
||||||
float:left;"> 82 </div><div class="partial"
|
float:left;"> 10 </div><div class="not-covered"
|
||||||
style="width:0.8928571428571429%;
|
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"
|
float:left;"> 1 </div><div class="not-covered"
|
||||||
style="width:25.892857142857142%;
|
style="width:34.41558441558441%;
|
||||||
float:left;"> 29 </div></td>
|
float:left;"> 53 </div></td>
|
||||||
<td class="with-number">74.11 %</td>
|
<td class="with-number">65.58 %</td>
|
||||||
<td class="with-number">301</td><td class="with-number">35</td><td class="with-number">112</td>
|
<td class="with-number">379</td><td class="with-number">41</td><td class="with-number">154</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="mw_engine/world.clj.html">mw-engine.world</a></td><td class="with-bar"><div class="covered"
|
<td><a href="mw_engine/world.clj.html">mw-engine.world</a></td><td class="with-bar"><div class="covered"
|
||||||
style="width:54.310344827586206%;
|
style="width:34.57446808510638%;
|
||||||
float:left;"> 63 </div><div class="not-covered"
|
float:left;"> 65 </div><div class="not-covered"
|
||||||
style="width:45.689655172413794%;
|
style="width:65.42553191489361%;
|
||||||
float:left;"> 53 </div></td>
|
float:left;"> 123 </div></td>
|
||||||
<td class="with-number">54.31 %</td>
|
<td class="with-number">34.57 %</td>
|
||||||
<td class="with-bar"><div class="covered"
|
<td class="with-bar"><div class="covered"
|
||||||
style="width:42.30769230769231%;
|
style="width:33.333333333333336%;
|
||||||
float:left;"> 11 </div><div class="partial"
|
float:left;"> 13 </div><div class="partial"
|
||||||
style="width:3.8461538461538463%;
|
style="width:2.5641025641025643%;
|
||||||
float:left;"> 1 </div><div class="not-covered"
|
float:left;"> 1 </div><div class="not-covered"
|
||||||
style="width:53.84615384615385%;
|
style="width:64.1025641025641%;
|
||||||
float:left;"> 14 </div></td>
|
float:left;"> 25 </div></td>
|
||||||
<td class="with-number">46.15 %</td>
|
<td class="with-number">35.90 %</td>
|
||||||
<td class="with-number">89</td><td class="with-number">12</td><td class="with-number">26</td>
|
<td class="with-number">111</td><td class="with-number">14</td><td class="with-number">39</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><td>Totals:</td>
|
<tr><td>Totals:</td>
|
||||||
<td class="with-bar"></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-bar"></td>
|
||||||
<td class="with-number">57.73 %</td>
|
<td class="with-number">54.18 %</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -77,277 +77,367 @@
|
||||||
024 mw-engine.core
|
024 mw-engine.core
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
025 (:require [mw-engine.utils :refer [get-int-or-zero map-world]]
|
025 (:require [mw-engine.flow :refer [flow-world]]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
026 [taoensso.timbre :as l]))
|
026 [mw-engine.utils :refer [add-history-event get-int-or-zero map-world rule-type]]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
027 [taoensso.timbre :as l]))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
027
|
028
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
028 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
029 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
029 ;;;;
|
030 ;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
030 ;;;; mw-engine: the state/transition engine of MicroWorld.
|
031 ;;;; mw-engine: the state/transition engine of MicroWorld.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
031 ;;;;
|
032 ;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
032 ;;;; This program is free software; you can redistribute it and/or
|
033 ;;;; This program is free software; you can redistribute it and/or
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
033 ;;;; modify it under the terms of the GNU General Public License
|
034 ;;;; modify it under the terms of the GNU General Public License
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
034 ;;;; as published by the Free Software Foundation; either version 2
|
035 ;;;; as published by the Free Software Foundation; either version 2
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
035 ;;;; of the License, or (at your option) any later version.
|
036 ;;;; of the License, or (at your option) any later version.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
036 ;;;;
|
037 ;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
037 ;;;; This program is distributed in the hope that it will be useful,
|
038 ;;;; This program is distributed in the hope that it will be useful,
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
038 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
039 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
039 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
040 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
040 ;;;; GNU General Public License for more details.
|
041 ;;;; GNU General Public License for more details.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
041 ;;;;
|
042 ;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
042 ;;;; You should have received a copy of the GNU General Public License
|
043 ;;;; You should have received a copy of the GNU General Public License
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
043 ;;;; along with this program; if not, write to the Free Software
|
044 ;;;; along with this program; if not, write to the Free Software
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
044 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
045 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
045 ;;;; USA.
|
046 ;;;; USA.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
046 ;;;;
|
047 ;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
047 ;;;; Copyright (C) 2014 Simon Brooke
|
048 ;;;; Copyright (C) 2014 Simon Brooke
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
048 ;;;;
|
049 ;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
049 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
050 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
050
|
051
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
|
||||||
051 (defn apply-rule
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
052 "Apply a single `rule` to a `cell`. What this is about is that I want to be able,
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
053 for debugging purposes, to tag a cell with the rule text of the rule which
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
054 fired (and especially so when an exception is thrown. So a rule may be either
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
055 an ifn, or a list (ifn source-text). This function deals with despatching
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
056 on those two possibilities. `world` is also passed in in order to be able
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
057 to access neighbours."
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
058 ([world cell rule]
|
|
||||||
</span><br/>
|
|
||||||
<span class="partial" title="2 out of 3 forms covered">
|
|
||||||
059 (cond
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="9 out of 9 forms covered">
|
|
||||||
060 (ifn? rule) (apply-rule world cell rule nil)
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="11 out of 11 forms covered">
|
|
||||||
061 (seq? rule) (let [[afn src] rule] (apply-rule world cell afn src))))
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
062 ([world cell rule source]
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="8 out of 8 forms covered">
|
|
||||||
063 (let [result (apply rule (list cell world))]
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
064 (cond
|
052 (def ^:dynamic *with-history*
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="12 out of 12 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
065 (and result source) (merge result {:rule source})
|
053 "I suspect that caching history on the cells is greatly worsening the
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
066 :else result))))
|
054 memory problems. Make it optional, but by default false."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
055 false)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
067
|
056
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
068 (defn- apply-rules
|
057 (defn apply-rule
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
069 "Derive a cell from this `cell` of this `world` by applying these `rules`."
|
058 "Apply a single `rule` to a `cell`. What this is about is that I want to be able,
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
070 [world cell rules]
|
059 for debugging purposes, to tag a cell with the rule text of the rule which
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 6 forms covered">
|
|
||||||
071 (cond (empty? rules) cell
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 8 forms covered">
|
|
||||||
072 :else (let [result (apply-rule world cell (first rules))]
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
|
||||||
073 (cond result result
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 7 forms covered">
|
|
||||||
074 :else (apply-rules world cell (rest rules))))))
|
|
||||||
</span><br/>
|
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
075
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
|
||||||
076 (defn- transform-cell
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
077 "Derive a cell from this `cell` of this `world` by applying these `rules`. If an
|
060 fired (and especially so when an exception is thrown). "
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
078 exception is thrown, cache its message on the cell and set it's state to error"
|
061 ;; as of version 0-3-0, metadata for rules is now passed around on the metadata
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
079 [world cell rules]
|
062 ;; of the rule function itself. Yes, I know, this is obvious; but I'll confess
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
063 ;; I didn't think of it before.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
064 [world cell rule]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
065 (let [result (try
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="7 out of 7 forms covered">
|
||||||
|
066 (apply rule (list cell world))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
067 (catch Exception e
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 16 forms covered">
|
||||||
|
068 (l/warn e
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
069 (format
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
070 "Error in `apply-rule`: `%s` (%s) while executing rule `%s` on cell `%s`"
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
080 (try
|
071 e
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
072 (.getMessage e)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
073 (-> rule meta :lisp)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
074 cell))))]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
075 (if *with-history*
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
|
076 (add-history-event result rule)
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
077 result)))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
078
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
079 (defn- apply-rules
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
080 "Derive a cell from this `cell` of this `world` by applying these `rules`."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
081 [world cell rules]
|
||||||
|
</span><br/>
|
||||||
|
<span class="partial" title="4 out of 5 forms covered">
|
||||||
|
082 (or
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
083 (first
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
084 (remove
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
085 nil?
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
086 (try
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="9 out of 9 forms covered">
|
||||||
|
087 (map #(apply-rule world cell %) rules)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
088 (catch Exception e
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 16 forms covered">
|
||||||
|
089 (l/warn e
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
090 (format
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
091 "Error in `apply-rules`: `%s` (%s) while executing rules on cell `%s`"
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
081 (merge
|
092 (-> e .getClass .getName)
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 5 forms covered">
|
|
||||||
082 (apply-rules world cell rules)
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 8 forms covered">
|
|
||||||
083 {:generation (+ (get-int-or-zero cell :generation) 1)})
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
084 (catch Exception e
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 8 forms covered">
|
|
||||||
085 (merge cell {:error
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
|
||||||
086 (format "%s at generation %d when in state %s"
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
087 (.getMessage e)
|
093 (.getMessage e)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
088 (:generation cell)
|
094 cell))))))
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
|
||||||
089 (:state cell))
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 5 forms covered">
|
|
||||||
090 :stacktrace (map #(.toString %) (.getStackTrace e))
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
091 :state :error}))))
|
095 cell))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
092
|
096
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
093 (defn transform-world
|
097 (defn- transform-cell
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
094 "Return a world derived from this `world` by applying these `rules` to each cell."
|
098 "Derive a cell from this `cell` of this `world` by applying these `rules`. If an
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
095 ([world rules]
|
099 exception is thrown, cache its message on the cell and set it's state to error"
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 7 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
096 (map-world world transform-cell (list rules))))
|
100 [world cell rules]
|
||||||
</span><br/>
|
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
097
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
098 (defn run-world
|
101 (try
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
102 (merge
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
|
103 (apply-rules world cell rules)
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="8 out of 8 forms covered">
|
||||||
|
104 {:generation (+ (get-int-or-zero cell :generation) 1)})
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
099 "Run this world with these rules for this number of generations.
|
105 (catch Exception e
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
100
|
106 (let [narrative (format "Error in `transform-cell`: `%s` (%s) at generation %d when in state %s;"
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
101 * `world` a world as discussed above;
|
107 (-> e .getClass .getName)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
102 * `init-rules` a sequence of rules as defined above, to be run once to initialise the world;
|
108 (.getMessage e)
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
103 * `rules` a sequence of rules as defined above, to be run iteratively for each generation;
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
104 * `generations` an (integer) number of generations.
|
|
||||||
</span><br/>
|
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
105
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
106 Return the final generation of the world."
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
107 [world init-rules rules generations]
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
108 (reduce (fn [world iteration]
|
109 (:generation cell)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
110 (:state cell))]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 17 forms covered">
|
<span class="not-covered" title="0 out of 17 forms covered">
|
||||||
109 (l/info "Running iteration " iteration)
|
111 (l/warn e narrative)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
110 (transform-world world rules))
|
112 cell))))
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
|
||||||
111 (transform-world world init-rules)
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
|
||||||
112 (range generations)))
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
113
|
113
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
114
|
114 (defn transform-world
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
115 "Return a world derived from this `world` by applying the production rules
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
116 found among these `rules` to each cell."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
117 [world rules]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
|
118 (map-world world transform-cell
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
119 ;; Yes, that `list` is there for a reason!
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
120 (list
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
121 (filter
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
|
122 #(= :production (rule-type %))
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
123 rules))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
115
|
124
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
125 (defn run-world
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
126 "Run this world with these rules for this number of generations.
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
127
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
128 * `world` a world as discussed above;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
129 * `init-rules` a sequence of rules as defined above, to be run once to initialise the world;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
130 * `rules` a sequence of rules as defined above, to be run iteratively for each generation;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
131 * `generations` an (integer) number of generations.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
132
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
133 **NOTE THAT** all rules **must** be tagged with `rule-type` metadata, or thet **will not**
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
134 be executed.
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
135
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
136 Return the final generation of the world."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
137 ([world rules generations]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 7 forms covered">
|
||||||
|
138 (run-world world rules rules (dec generations)))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
139 ([world init-rules rules generations]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
140 (reduce (fn [world iteration]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 17 forms covered">
|
||||||
|
141 (l/info "Running iteration " iteration)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
142 (let [w' (transform-world world rules)]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
|
143 (flow-world w' rules)))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
|
144 (transform-world world init-rules)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
145 (range generations))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -77,355 +77,469 @@
|
||||||
024 executed. This namespace deals with mainly with execution."
|
024 executed. This namespace deals with mainly with execution."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
025 (:require [mw-engine.utils :refer [get-cell get-num in-bounds? merge-cell]]
|
025 (:require [mw-engine.utils :refer [add-history-event get-cell get-num
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
026 [taoensso.timbre :refer [info warn]]))
|
026 in-bounds? map-world merge-cell rule-type]]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
027 [taoensso.timbre :refer [info warn]]))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
027
|
028
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
028 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
029 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
029 ;;;;
|
030 ;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
030 ;;;; mw-engine: the state/transition engine of MicroWorld.
|
031 ;;;; mw-engine: the state/transition engine of MicroWorld.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
031 ;;;;
|
032 ;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
032 ;;;; This program is free software; you can redistribute it and/or
|
033 ;;;; This program is free software; you can redistribute it and/or
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
033 ;;;; modify it under the terms of the GNU General Public License
|
034 ;;;; modify it under the terms of the GNU General Public License
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
034 ;;;; as published by the Free Software Foundation; either version 2
|
035 ;;;; as published by the Free Software Foundation; either version 2
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
035 ;;;; of the License, or (at your option) any later version.
|
036 ;;;; of the License, or (at your option) any later version.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
036 ;;;;
|
037 ;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
037 ;;;; This program is distributed in the hope that it will be useful,
|
038 ;;;; This program is distributed in the hope that it will be useful,
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
038 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
039 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
039 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
040 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
040 ;;;; GNU General Public License for more details.
|
041 ;;;; GNU General Public License for more details.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
041 ;;;;
|
042 ;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
042 ;;;; You should have received a copy of the GNU General Public License
|
043 ;;;; You should have received a copy of the GNU General Public License
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
043 ;;;; along with this program; if not, write to the Free Software
|
044 ;;;; along with this program; if not, write to the Free Software
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
044 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
045 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
045 ;;;; USA.
|
046 ;;;; USA.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
046 ;;;;
|
047 ;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
047 ;;;; Copyright (C) 2014 Simon Brooke
|
048 ;;;; Copyright (C) 2014 Simon Brooke
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
048 ;;;;
|
049 ;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
049 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
050 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
050
|
051
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
051 (defn coordinate?
|
052 (defn coordinate?
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
052 "Return `true` if this object `o` is a valid coordinate with respect to
|
053 "Return `true` if this object `o` is a valid coordinate with respect to
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
053 this `world`, else `false`. Assumes square worlds."
|
054 this `world`, else `false`. Assumes square worlds."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
054 [o world]
|
055 [o world]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
055 (try
|
056 (try
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="14 out of 14 forms covered">
|
<span class="covered" title="14 out of 14 forms covered">
|
||||||
056 (and (or (zero? o) (pos-int? o))
|
057 (and (or (zero? o) (pos-int? o))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
057 (< o (count world)))
|
058 (< o (count world)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
058 (catch Exception e
|
059 (catch Exception e
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="20 out of 20 forms covered">
|
<span class="covered" title="20 out of 20 forms covered">
|
||||||
059 (warn (format "Not a valid coordinate: %s; %s" o (.getMessage e)))
|
060 (warn (format "Not a valid coordinate: %s; %s" o (.getMessage e)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
060 false)))
|
061 false)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
061
|
062
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
062 (defn location?
|
063 (defn location?
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
063 "Return `true` if this object `o` is a location as defined above with respect to
|
064 "Return `true` if this object `o` is a location as defined above with respect to
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
064 this `world`, else `false`."
|
065 this `world`, else `false`."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
065 [o world]
|
066 [o world]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="1 out of 2 forms covered">
|
<span class="partial" title="1 out of 2 forms covered">
|
||||||
066 (try
|
067 (try
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="14 out of 16 forms covered">
|
<span class="partial" title="14 out of 16 forms covered">
|
||||||
067 (and (map? o)
|
068 (and (map? o)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
068 (integer? (:x o))
|
069 (integer? (:x o))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
069 (integer? (:y o))
|
070 (integer? (:y o))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="8 out of 8 forms covered">
|
<span class="covered" title="8 out of 8 forms covered">
|
||||||
070 (in-bounds? world (:x o) (:y o)))
|
071 (in-bounds? world (:x o) (:y o)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
071 (catch Exception e
|
072 (catch Exception e
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 20 forms covered">
|
<span class="not-covered" title="0 out of 20 forms covered">
|
||||||
072 (warn (format "Not a valid location: %s; %s" o (.getMessage e)))
|
073 (warn (format "Not a valid location: %s; %s" o (.getMessage e)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
073 false)))
|
074 false)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
074
|
075
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
075 (defn flow?
|
076 (defn flow?
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
076 "Return `true` if this object `o` is a flow as defined above with respect to
|
077 "Return `true` if this object `o` is a flow as defined above with respect to
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
077 this `world`, else `false`. Assumes square worlds."
|
078 this `world`, else `false`. Assumes square worlds."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
078 [o world]
|
079 [o world]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="1 out of 2 forms covered">
|
<span class="partial" title="1 out of 2 forms covered">
|
||||||
079 (try
|
080 (try
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="16 out of 20 forms covered">
|
<span class="partial" title="16 out of 20 forms covered">
|
||||||
080 (and (map? o)
|
081 (and (map? o)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="6 out of 6 forms covered">
|
<span class="covered" title="6 out of 6 forms covered">
|
||||||
081 (location? (:source o) world)
|
082 (location? (:source o) world)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="6 out of 6 forms covered">
|
<span class="covered" title="6 out of 6 forms covered">
|
||||||
082 (location? (:destination o) world)
|
083 (location? (:destination o) world)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
083 (keyword? (:property o))
|
084 (keyword? (:property o))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
084 (pos? (:quantity o)))
|
085 (pos? (:quantity o)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
085 (catch Exception e
|
086 (catch Exception e
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 20 forms covered">
|
<span class="not-covered" title="0 out of 20 forms covered">
|
||||||
086 (warn (format "Not a valid flow: %s; %s" o (.getMessage e)))
|
087 (warn (format "Not a valid flow: %s; %s" o (.getMessage e)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
087 false)))
|
088 false)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
088
|
089
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
089 (defn execute
|
090 (defn execute
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
090 "Return a world like this `world`, except with the quantity of the property
|
091 "Return a world like this `world`, except with the quantity of the property
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
091 described in this `flow` object transferred from the source of that flow
|
092 described in this `flow` object transferred from the source of that flow
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
092 to its destination."
|
093 to its destination."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
093 [world flow]
|
094 [world flow]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
094 (try
|
095 (try
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="6 out of 6 forms covered">
|
<span class="covered" title="6 out of 6 forms covered">
|
||||||
095 (let [sx (-> flow :source :x)
|
096 (let [sx (-> flow :source :x)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
096 sy (-> flow :source :y)
|
097 sy (-> flow :source :y)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
097 source (get-cell world sx sy)
|
098 source (get-cell world sx sy)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
098 dx (-> flow :destination :x)
|
099 dx (-> flow :destination :x)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
099 dy (-> flow :destination :y)
|
100 dy (-> flow :destination :y)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
100 dest (get-cell world dx dy)
|
101 dest (get-cell world dx dy)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
101 p (:property flow)
|
102 p (:property flow)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="8 out of 8 forms covered">
|
<span class="partial" title="16 out of 22 forms covered">
|
||||||
102 q (min (:quantity flow) (get-num source p))
|
103 q (min (:quantity flow) (get-num source p))
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
104 s' (add-history-event
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="9 out of 9 forms covered">
|
<span class="covered" title="9 out of 9 forms covered">
|
||||||
103 s' (assoc source p (- (source p) q))
|
105 (assoc source p (- (source p) q))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="10 out of 10 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
104 d' (assoc dest p (+ (get-num dest p) q))]
|
106 (:rule flow)
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="6 out of 6 forms covered">
|
|
||||||
105 (if (= q (:quantity flow))
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="18 out of 18 forms covered">
|
|
||||||
106 (info (format "Moving %f units of %s from %d,%d to %d,%d"
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="9 out of 9 forms covered">
|
|
||||||
107 (float q) (name p) sx sy dx dy))
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="18 out of 18 forms covered">
|
|
||||||
108 (warn (format "Moving %s from %d,%d to %d,%d; %f units ordered but only %f available"
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="13 out of 13 forms covered">
|
<span class="covered" title="13 out of 13 forms covered">
|
||||||
109 (name p) sx sy dx dy (float (:quantity flow)) (float q))))
|
107 {:direction :sent :other {:x dx :y dy} :property p :quantity q})
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
108 d' (add-history-event
|
||||||
|
</span><br/>
|
||||||
|
<span class="partial" title="20 out of 24 forms covered">
|
||||||
|
109 (assoc dest p (+ (get-num dest p) q))
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
110 (:rule flow)
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="13 out of 13 forms covered">
|
||||||
|
111 {:direction :received :other {:x sx :y sy} :property p :quantity q})]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="6 out of 6 forms covered">
|
||||||
|
112 (if (= q (:quantity flow))
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="18 out of 18 forms covered">
|
||||||
|
113 (info (format "Moving %f units of %s from %d,%d to %d,%d"
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="9 out of 9 forms covered">
|
||||||
|
114 (float q) (name p) sx sy dx dy))
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="18 out of 18 forms covered">
|
||||||
|
115 (warn (format "Moving %s from %d,%d to %d,%d; %f units ordered but only %f available"
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="13 out of 13 forms covered">
|
||||||
|
116 (name p) sx sy dx dy (float (:quantity flow)) (float q))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="7 out of 7 forms covered">
|
<span class="covered" title="7 out of 7 forms covered">
|
||||||
110 (merge-cell (merge-cell world s') d'))
|
117 (merge-cell (merge-cell world s') d'))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
111 (catch Exception e
|
118 (catch Exception e
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 20 forms covered">
|
<span class="not-covered" title="0 out of 20 forms covered">
|
||||||
112 (warn (format "Failed to execute flow %s: %s" flow (.getMessage e)))
|
119 (warn (format "Failed to execute flow %s: %s" flow (.getMessage e)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
113 ;; return the world unmodified.
|
120 ;; return the world unmodified.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
114 world)))
|
121 world)))
|
||||||
</span><br/>
|
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
115
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
|
||||||
116 (defn execute-flows
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
117 "Return a world like this `world`, but with each of these flows executed."
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
118 [world flows]
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="12 out of 12 forms covered">
|
|
||||||
119 (reduce execute world (filter #(flow? % world) flows)))
|
|
||||||
</span><br/>
|
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
120
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
121 ;; building blocks for compiled flow rules
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
122
|
122
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="32 out of 32 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
123 (defmacro create-location
|
123 (defn execute-flows
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
124 [cell]
|
124 "Return a world like this `world`, but with each of these flows executed."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
125 `(select-keys ~cell [:x :y]))
|
125 [world flows]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="12 out of 12 forms covered">
|
||||||
|
126 (reduce execute world (filter #(flow? % world) flows)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
126
|
127
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
128 (defn- plan-cell-flows
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
129 [world cell rules]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
130 (map ;; across all the rules
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
131 (fn [rule] (let [r (try
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 7 forms covered">
|
||||||
|
132 (apply rule (list cell world))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
133 (catch Exception any
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
|
134 (throw (ex-info "Planning of flows failed"
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 8 forms covered">
|
||||||
|
135 (merge (meta rule) {:cell cell})
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
136 any))))]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 12 forms covered">
|
||||||
|
137 (when r (map #(assoc % :rule rule) r))))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
138 rules))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
139
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
140 (defn plan-flows
|
||||||
|
</span><br/>
|
||||||
|
<span class="partial" title="3 out of 4 forms covered">
|
||||||
|
141 "Plan, but do not execute, all the flows in this `world` implied by those of
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
142 these `rules` (which are expected to be pre-compiled) which are
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
143 flow rules. Return the list of plans, as flow objects."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
144 [world rules]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
145 (remove nil?
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
146 (flatten
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
147 (map-world
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
148 world
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
149 plan-cell-flows
|
||||||
|
</span><br/>
|
||||||
|
<span class="partial" title="4 out of 17 forms covered">
|
||||||
|
150 (list (filter #(= :flow (rule-type %)) rules))))))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
151
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
152 (defn flow-world
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
153 "Return a world derived from this `world` by applying the flow rules
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
154 found among these `rules` to each cell, and executing all the flows
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
155 planned."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
156 [world rules]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 7 forms covered">
|
||||||
|
157 (execute-flows world (plan-flows world rules)))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
158
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
159 ;; building blocks for compiled flow rules
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
160
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="32 out of 32 forms covered">
|
||||||
|
161 (defmacro create-location
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
162 [cell]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
163 `(select-keys ~cell [:x :y]))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
164
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="56 out of 56 forms covered">
|
<span class="covered" title="56 out of 56 forms covered">
|
||||||
127 (defmacro create-flow-quantity
|
165 (defmacro create-flow-quantity
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
128 [source dest prop quantity]
|
166 [source dest prop quantity]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
129 `{:source (create-location ~source)
|
167 `{:source (create-location ~source)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
130 :destination (create-location ~dest)
|
168 :destination (create-location ~dest)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
131 :prop ~prop
|
169 :prop ~prop
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
132 :quantity ~quantity})
|
170 :quantity ~quantity})
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
133
|
171
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="48 out of 48 forms covered">
|
<span class="covered" title="48 out of 48 forms covered">
|
||||||
134 (defmacro create-flow-fraction
|
172 (defmacro create-flow-fraction
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
135 [source dest prop fraction]
|
173 [source dest prop fraction]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
136 `(create-flow-quantity ~source ~dest ~prop
|
174 `(create-flow-quantity ~source ~dest ~prop
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
137 (* ~fraction (get-num ~source ~prop))))
|
175 (* ~fraction (get-num ~source ~prop))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
138
|
176
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="36 out of 36 forms covered">
|
<span class="covered" title="36 out of 36 forms covered">
|
||||||
139 (defmacro create-flow-percent
|
177 (defmacro create-flow-percent
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
140 [source dest prop percent]
|
178 [source dest prop percent]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
141 `(create-flow-fraction ~source ~dest ~prop (/ ~percent 100)))
|
179 `(create-flow-fraction ~source ~dest ~prop (/ ~percent 100)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -107,283 +107,301 @@
|
||||||
034
|
034
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
035 (defn tag-property
|
035 (defn abs
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
036 "Set the value of this `property` of this cell from the corresponding pixel of this `heightmap`.
|
036 "Prior to Clojure 1.11, there is no native `abs` function. Afterwards, there
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
037 If the heightmap you supply is smaller than the world, this will break.
|
037 is."
|
||||||
</span><br/>
|
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
038
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
039 * `world` not actually used, but present to enable this function to be
|
038 [n]
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
040 passed as an argument to `mw-engine.utils/map-world`, q.v.
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
041 * `cell` a cell, as discussed in world.clj, q.v. Alternatively, a map;
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
042 * `property` the property (normally a keyword) whose value will be set on the cell.
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
043 * `heightmap` an (ideally) greyscale image, whose x and y dimensions should
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
044 exceed those of the world of which the `cell` forms part."
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
045 ([_ cell property heightmap]
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
|
||||||
046 (tag-property cell property heightmap))
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
047 ([cell property heightmap]
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
|
||||||
048 (merge cell
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
049 {property
|
039 (Math/abs n))
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
|
||||||
050 (+ (get-int cell property)
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
|
||||||
051 (- 256
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
|
||||||
052 (abs
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
|
||||||
053 (mod
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
|
||||||
054 (.getRGB heightmap
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
|
||||||
055 (get-int cell :x)
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
|
||||||
056 (get-int cell :y)) 256))))})))
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
057
|
040
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
058 (defn tag-gradient
|
041 (defn tag-property
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
059 "Set the `gradient` property of this `cell` of this `world` to the difference in
|
042 "Set the value of this `property` of this cell from the corresponding pixel of this `heightmap`.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
060 altitude between its highest and lowest neghbours."
|
043 If the heightmap you supply is smaller than the world, this will break.
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
044
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
061 [world cell]
|
045 * `world` not actually used, but present to enable this function to be
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
046 passed as an argument to `mw-engine.utils/map-world`, q.v.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
047 * `cell` a cell, as discussed in world.clj, q.v. Alternatively, a map;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
048 * `property` the property (normally a keyword) whose value will be set on the cell.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
049 * `heightmap` an (ideally) greyscale image, whose x and y dimensions should
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
050 exceed those of the world of which the `cell` forms part."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
051 ([_ cell property heightmap]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
|
052 (tag-property cell property heightmap))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
053 ([cell property heightmap]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
054 (merge cell
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
055 {property
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
|
056 (+ (get-int cell property)
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
057 (- 256
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
058 (abs
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
059 (mod
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
060 (.getRGB heightmap
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
|
061 (get-int cell :x)
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
|
062 (get-int cell :y)) 256))))})))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
063
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
064 (defn tag-gradient
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
065 "Set the `gradient` property of this `cell` of this `world` to the difference in
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
066 altitude between its highest and lowest neghbours."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
067 [world cell]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="11 out of 11 forms covered">
|
<span class="covered" title="11 out of 11 forms covered">
|
||||||
062 (let [heights (remove nil? (map :altitude (get-neighbours world cell)))
|
068 (let [heights (remove nil? (map :altitude (get-neighbours world cell)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="5 out of 6 forms covered">
|
<span class="partial" title="5 out of 6 forms covered">
|
||||||
063 highest (cond (empty? heights) 0 ;; shouldn't happen
|
069 highest (cond (empty? heights) 0 ;; shouldn't happen
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
064 :else (apply max heights))
|
070 :else (apply max heights))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="5 out of 6 forms covered">
|
<span class="partial" title="5 out of 6 forms covered">
|
||||||
065 lowest (cond (empty? heights) 0 ;; shouldn't
|
071 lowest (cond (empty? heights) 0 ;; shouldn't
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
066 :else (apply min heights))
|
072 :else (apply min heights))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
067 gradient (- highest lowest)]
|
073 gradient (- highest lowest)]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="6 out of 6 forms covered">
|
<span class="covered" title="6 out of 6 forms covered">
|
||||||
068 (merge cell {:gradient gradient})))
|
074 (merge cell {:gradient gradient})))
|
||||||
</span><br/>
|
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
069
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
|
||||||
070 (defn tag-gradients
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
071 "Set the `gradient` property of each cell in this `world` to the difference in
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
072 altitude between its highest and lowest neghbours."
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
073 [world]
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
|
||||||
074 (map-world world tag-gradient))
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
075
|
075
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
076 (defn tag-altitude
|
076 (defn tag-gradients
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
077 "Set the altitude of this cell from the corresponding pixel of this heightmap.
|
077 "Set the `gradient` property of each cell in this `world` to the difference in
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
078 If the heightmap you supply is smaller than the world, this will break.
|
078 altitude between its highest and lowest neghbours."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
079 [world]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
|
080 (map-world world tag-gradient))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
079
|
081
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
080 * `world` not actually used, but present to enable this function to be
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
081 passed as an argument to `mw-engine.utils/map-world`, q.v.;
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
082 * `cell` a cell, as discussed in world.clj, q.v. Alternatively, a map;
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
083 * `heightmap` an (ideally) greyscale image, whose x and y dimensions should
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
084 exceed those of the world of which the `cell` forms part."
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
085 ([_ cell heightmap]
|
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="5 out of 5 forms covered">
|
|
||||||
086 (tag-property cell :altitude heightmap))
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
|
||||||
087 ([cell heightmap]
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 5 forms covered">
|
|
||||||
088 (tag-property cell :altitude heightmap)))
|
|
||||||
</span><br/>
|
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
|
||||||
089
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
090 (defn apply-heightmap
|
082 (defn tag-altitude
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
091 "Apply the image file loaded from this path to this world, and return a world whose
|
083 "Set the altitude of this cell from the corresponding pixel of this heightmap.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
092 altitudes are modified (added to) by the altitudes in the heightmap. It is assumed that
|
084 If the heightmap you supply is smaller than the world, this will break.
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
085
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
093 the heightmap is at least as large in x and y dimensions as the world. Note that, in
|
086 * `world` not actually used, but present to enable this function to be
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
094 addition to setting the `:altitude` of each cell, this function also sets the `:gradient`.
|
087 passed as an argument to `mw-engine.utils/map-world`, q.v.;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
088 * `cell` a cell, as discussed in world.clj, q.v. Alternatively, a map;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
089 * `heightmap` an (ideally) greyscale image, whose x and y dimensions should
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
090 exceed those of the world of which the `cell` forms part."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
091 ([_ cell heightmap]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
|
092 (tag-property cell :altitude heightmap))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
093 ([cell heightmap]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
094 (tag-property cell :altitude heightmap)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
095
|
095
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
096 * `world` a world, as defined in `world.clj`, q.v.; if world is not supplied,
|
096 (defn apply-heightmap
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
097 a world the size of the heightmap will be created;
|
097 "Apply the image file loaded from this path to this world, and return a world whose
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
098 * `imagepath` a file path or URL which indicates an (ideally greyscale) image file."
|
098 altitudes are modified (added to) by the altitudes in the heightmap. It is assumed that
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
099 ([world imagepath]
|
099 the heightmap is at least as large in x and y dimensions as the world. Note that, in
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
100 addition to setting the `:altitude` of each cell, this function also sets the `:gradient`.
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
101
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
102 * `world` a world, as defined in `world.clj`, q.v.; if world is not supplied,
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
103 a world the size of the heightmap will be created;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
104 * `imagepath` a file path or URL which indicates an (ideally greyscale) image file."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
105 ([world imagepath]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
100 (let [heightmap (filter-image
|
106 (let [heightmap (filter-image
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
101 (load-image imagepath)
|
107 (load-image imagepath)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
102 (filters/grayscale))]
|
108 (filters/grayscale))]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
103 (map-world
|
109 (map-world
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="7 out of 7 forms covered">
|
<span class="covered" title="7 out of 7 forms covered">
|
||||||
104 (map-world world tag-altitude (list heightmap))
|
110 (map-world world tag-altitude (list heightmap))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
105 tag-gradient)))
|
111 tag-gradient)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
106 ([imagepath]
|
112 ([imagepath]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
107 (let [heightmap (filter-image
|
113 (let [heightmap (filter-image
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
108 (load-image imagepath)
|
114 (load-image imagepath)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
109 (filters/grayscale))
|
115 (filters/grayscale))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
110 world (make-world (.getWidth heightmap) (.getHeight heightmap))]
|
116 world (make-world (.getWidth heightmap) (.getHeight heightmap))]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
111 (map-world
|
117 (map-world
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="7 out of 7 forms covered">
|
<span class="covered" title="7 out of 7 forms covered">
|
||||||
112 (map-world world tag-altitude (list heightmap))
|
118 (map-world world tag-altitude (list heightmap))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
113 tag-gradient))))
|
119 tag-gradient))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
114
|
120
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
115 (defn apply-valuemap
|
121 (defn apply-valuemap
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
116 "Generalised from apply-heightmap, set an arbitrary property on each cell
|
122 "Generalised from apply-heightmap, set an arbitrary property on each cell
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
117 of this `world` from the values in this (ideally greyscale) heightmap.
|
123 of this `world` from the values in this (ideally greyscale) heightmap.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
118
|
124
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
119 * `world` a world, as defined in `world.clj`, q.v.;
|
125 * `world` a world, as defined in `world.clj`, q.v.;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
120 * `imagepath` a file path or URL which indicates an (ideally greyscale) image file;
|
126 * `imagepath` a file path or URL which indicates an (ideally greyscale) image file;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
121 * `property` the property of each cell whose value should be added to from the
|
127 * `property` the property of each cell whose value should be added to from the
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
122 intensity of the corresponding cell of the image."
|
128 intensity of the corresponding cell of the image."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
123 [world imagepath property]
|
129 [world imagepath property]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
124 (let [heightmap (filter-image
|
130 (let [heightmap (filter-image
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
125 (load-image imagepath)
|
131 (load-image imagepath)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
126 (filters/grayscale))]
|
132 (filters/grayscale))]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="8 out of 8 forms covered">
|
<span class="covered" title="8 out of 8 forms covered">
|
||||||
127 (map-world world tag-property (list property heightmap))))
|
133 (map-world world tag-property (list property heightmap))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
302
docs/cloverage/mw_engine/render.clj.html
Normal file
302
docs/cloverage/mw_engine/render.clj.html
Normal 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 (ns mw-engine.render
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
002 "Render a world as HTML.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
003
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
004 Adapted (simplified) from mw-ui.render-world; this is for visualisation, not
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
005 interaction."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
006 ;; TODO: but possibly it would be better if there is to be a newer version of
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
007 ;; mw-ui, to base it on this.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
008 (:require [hiccup2.core :refer [html]])
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
009 )
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
010
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
011 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
012 ;;;;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
013 ;;;; This program is free software; you can redistribute it and/or
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
014 ;;;; modify it under the terms of the GNU General Public License
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
015 ;;;; as published by the Free Software Foundation; either version 2
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
016 ;;;; of the License, or (at your option) any later version.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
017 ;;;;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
018 ;;;; This program is distributed in the hope that it will be useful,
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
019 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
020 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
021 ;;;; GNU General Public License for more details.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
022 ;;;;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
023 ;;;; You should have received a copy of the GNU General Public License
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
024 ;;;; along with this program; if not, write to the Free Software
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
025 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
026 ;;;; USA.
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
027 ;;;;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
028 ;;;; Copyright (C) 2024 Simon Brooke
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
029 ;;;;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
030 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
031
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
|
032 (def ^:dynamic *state-images-relative-path* "img/tiles/")
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
033
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
034 (defn format-css-class
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
035 "Format this statekey, assumed to be a keyword indicating a state in the
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
036 world, into a CSS class"
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
037 [statekey]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
038 (name statekey))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
039
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
040 (defn format-image-path
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
041 "Render this statekey, assumed to be a keyword indicating a state in the
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
042 world, into a path which should recover the corresponding image file."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
043 [statekey]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 7 forms covered">
|
||||||
|
044 (format "%s%s.png" *state-images-relative-path* (format-css-class statekey)))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
045
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
046 (defn format-mouseover [cell]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
047 (str cell))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
048
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
049 (defn render-cell
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
050 "Render this world cell as a Hiccup table cell."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
051 [cell]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
|
052 (let [state (:state cell)]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 11 forms covered">
|
||||||
|
053 [:td {:class (format-css-class state) :title (format-mouseover cell)}
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
054
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 11 forms covered">
|
||||||
|
055 [:img {:alt (:state cell) :src (format-image-path state)}]]))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
056
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
057
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
058 (defn render-world-row
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
059 "Render this world row as a Hiccup table row."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
060 [row]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 10 forms covered">
|
||||||
|
061 (apply vector (cons :tr (map render-cell row))))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
062
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
063 (defn render-world-table
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
064 "Render this `world` as a complete HTML table in a DIV. If
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
065 `state-images-relative-path` is passed, use that to override the default path."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
066 ([world]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
067 [:div {:class "world"}
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
068 (apply vector
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
069 (cons :table
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
|
070 (map render-world-row world)))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
071 [:p
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 10 forms covered">
|
||||||
|
072 (str "Generation " (:generation (first (flatten world))))]])
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
073 ([world state-images-relative-path]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 10 forms covered">
|
||||||
|
074 (binding [*state-images-relative-path* state-images-relative-path]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
075 (render-world-table world))))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
076
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
077 (defn render-world-page
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
078 ([world]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
079 [:html
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
080 [:head
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
081 [:title "Rendered world"]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
082 [:style "div.world table, div.world table tr td {
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
083 padding: 0;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
084 margin: 0;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
085 border-collapse: collapse;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
086 border: none;}"]]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
|
087 [:body
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
088 (render-world-table world)]])
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
089 ([world state-images-relative-path]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 10 forms covered">
|
||||||
|
090 (binding [*state-images-relative-path* state-images-relative-path]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
091 (render-world-page world))))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
092
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
093 (defn world->html-file
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
094 ([world output-path]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 18 forms covered">
|
||||||
|
095 (spit output-path (str (html (render-world-page world)))))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
096 ([world output-path state-images-relative-path]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 10 forms covered">
|
||||||
|
097 (binding [*state-images-relative-path* state-images-relative-path]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
|
098 (world->html-file world output-path))))
|
||||||
|
</span><br/>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -17,10 +17,10 @@
|
||||||
004 mw-engine.utils
|
004 mw-engine.utils
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
005 (:require
|
005 (:require [clojure.math.combinatorics :as combo]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
006 [clojure.math.combinatorics :as combo]))
|
006 [clojure.string :refer [join]]))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
007
|
007
|
||||||
|
@ -101,7 +101,7 @@
|
||||||
032 "Return 'true' if elt is a member of col, else 'false'."
|
032 "Return 'true' if elt is a member of col, else 'false'."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
033 [elt col]
|
033 [elt col]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 6 forms covered">
|
<span class="not-covered" title="0 out of 6 forms covered">
|
||||||
034 (contains? (set col) elt))
|
034 (contains? (set col) elt))
|
||||||
|
@ -124,7 +124,7 @@
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
040 (let [value (map property)]
|
040 (let [value (map property)]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="5 out of 6 forms covered">
|
<span class="covered" title="6 out of 6 forms covered">
|
||||||
041 (if (integer? value) value 0)))
|
041 (if (integer? value) value 0)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
@ -424,8 +424,8 @@
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
140
|
140
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="136 out of 136 forms covered">
|
||||||
141 (defn get-num
|
141 (defmacro get-num
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
142 "Get the value of a property expected to be a number from a map; if not
|
142 "Get the value of a property expected to be a number from a map; if not
|
||||||
|
@ -445,20 +445,20 @@
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
147 [map key]
|
147 [map key]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
148 (if (map? map)
|
148 `(if (map? ~map)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="4 out of 4 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
149 (let [v (map key)]
|
149 (let [~'v (~map ~key)]
|
||||||
</span><br/>
|
|
||||||
<span class="covered" title="12 out of 12 forms covered">
|
|
||||||
150 (cond (and v (number? v)) v
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
151 :else 0))
|
150 (cond (and ~'v (number? ~'v)) ~'v
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
152 (throw (Exception. "No map passed?"))))
|
151 :else 0))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
152 (throw (Exception. "No map passed?"))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
153
|
153
|
||||||
|
@ -907,5 +907,239 @@
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
301 world))
|
301 world))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
302
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
303 (defn rule-type
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
304 "Return the rule-type of this compiled `rule`."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
305 [rule]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="5 out of 5 forms covered">
|
||||||
|
306 (:rule-type (meta rule)))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
307
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
308 (defn add-history-event
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
309 "If `cell` is non-nil, expect it to be a map representing a cell; add
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
310 to its history an an event recording the firing of this rule. If
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
311 `detail` is passed, treat it as a map of additional data to be
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
312 added to the event."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
313 ([cell rule]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="8 out of 8 forms covered">
|
||||||
|
314 (when cell (add-history-event cell rule {})))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
315 ([result rule detail]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
316 (when result
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
|
317 (let [rule-meta (meta rule)
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="7 out of 7 forms covered">
|
||||||
|
318 event {:rule (:source rule-meta)
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
319 :rule-type (:rule-type rule-meta)
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
320 :generation (get-int-or-zero
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
321 result
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
322 :generation)}
|
||||||
|
</span><br/>
|
||||||
|
<span class="partial" title="6 out of 7 forms covered">
|
||||||
|
323 event' (if detail (merge event detail) event)]
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
324 (merge result
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="4 out of 4 forms covered">
|
||||||
|
325 {:history (concat
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
326 (:history result)
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
|
327 (list event'))})))))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
328
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
329 (defn- event-narrative [event]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 11 forms covered">
|
||||||
|
330 (case (:rule-type event)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
331 :production (:rule event)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
332 :flow (format "%s %f units of %s %s %d,%d:\n %s"
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
333 (name (:direction event))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
334 (:quantity event)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
335 (:property event)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 8 forms covered">
|
||||||
|
336 (if (= :sent (:direction event)) "to" "from")
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
337 (:x (:other event))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
338 (:y (:other event))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
339 (:rule event))))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
340
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
341 (defn history-string
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
342 "Return the history of this `cell` as a string for presentation to the user."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
343 [cell]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
344 (join "\n"
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 12 forms covered">
|
||||||
|
345 (map #(format "%6d: %s" (:generation %) (event-narrative %))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
346 (:history cell))))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
347
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
348 (defn- extend-summary [summary rs rl event]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
349 (str summary
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 6 forms covered">
|
||||||
|
350 (if rs (format "%d-%d (%d occurances): %s\n" rs
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
351 (:generation event)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
352 rl
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
353 (event-narrative event))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 6 forms covered">
|
||||||
|
354 (format "%d: %s\n" (:generation event)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
|
355 (event-narrative event)))))
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
356
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
357 (defn summarise-history
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
358 "Return, as a string, a shorter summary of the history of this cell"
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
359 [cell]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 10 forms covered">
|
||||||
|
360 (loop [history (rest (:history cell))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
361 event (first (:history cell))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
362 prev nil
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
363 rs nil
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
364 rl 0
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
365 summary ""]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 12 forms covered">
|
||||||
|
366 (cond (nil? event) (extend-summary summary rs rl prev)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 8 forms covered">
|
||||||
|
367 (= (:rule event) (:rule prev)) (recur
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
368 (rest history)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
369 (first history)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
370 event
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
371 (or rs (:generation event))
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
372 (inc rl)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
373 summary)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
374 :else (recur (rest history)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
375 (first history)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
376 event
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
377 nil
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
378 0
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
379 (extend-summary summary rs (inc rl) event)))))
|
||||||
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -115,161 +115,227 @@
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
037
|
037
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="30 out of 30 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
038 (defmacro make-cell
|
038 (defn cell?
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
039 "Create a minimal default cell at x, y
|
039 "Return `true` if `obj` is a cell, as understood by MicroWorld, else `false`."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
040 [obj]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 16 forms covered">
|
||||||
|
041 (and (map? obj) ;; it's a map...
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
042 ;; TODO: it's worth checking (and this does not) that cells have the
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
043 ;; right co-ordinates!
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
044 (pos-int? (:x obj)) ;; with an x co-ordinate...
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
045 (pos-int? (:y obj)) ;; and a y co-ordinate...
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
|
046 (keyword? (:state obj)))) ;; and a state which is a keyword.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
040
|
047
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
|
048 (defn world?
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
041 * `x` the x coordinate at which this cell is created;
|
049 "Return `true` if `obj` is a world, as understood by MicroWorld, else `false`."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
042 * `y` the y coordinate at which this cell is created."
|
050 [obj]
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 16 forms covered">
|
||||||
|
051 (and (coll? obj) ;; it's a collection...
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
|
052 (every? coll? obj) ;; of collections...
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 9 forms covered">
|
||||||
|
053 (= 1 (count (set (map count obj)))) ;; all of which are the same length...
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
054 (every? cell? (flatten obj)))) ;; and every element of each of those is a cell.
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
055
|
||||||
|
</span><br/>
|
||||||
|
<span class="covered" title="30 out of 30 forms covered">
|
||||||
|
056 (defmacro make-cell
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
043 [x y]
|
057 "Create a minimal default cell at x, y
|
||||||
|
</span><br/>
|
||||||
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
|
058
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
059 * `x` the x coordinate at which this cell is created;
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
060 * `y` the y coordinate at which this cell is created."
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
061 [x y]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="2 out of 2 forms covered">
|
<span class="covered" title="2 out of 2 forms covered">
|
||||||
044 `{:x ~x :y ~y :state :new})
|
062 `{:x ~x :y ~y :state :new})
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
045
|
063
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
046 (defn make-world
|
064 (defn make-world
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
047 "Make a world width cells from east to west, and height cells from north to
|
065 "Make a world width cells from east to west, and height cells from north to
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
048 south.
|
066 south.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
049
|
067
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
050 * `width` a natural number representing the width of the matrix to be created;
|
068 * `width` a natural number representing the width of the matrix to be created;
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
051 * `height` a natural number representing the height of the matrix to be created."
|
069 * `height` a natural number representing the height of the matrix to be created."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
052 [width height]
|
070 [width height]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
053 (apply vector
|
071 (apply vector
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
054 (map (fn [h]
|
072 (map (fn [h]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="16 out of 16 forms covered">
|
<span class="covered" title="16 out of 16 forms covered">
|
||||||
055 (apply vector (map #(make-cell % h) (range width))))
|
073 (apply vector (map #(make-cell % h) (range width))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="3 out of 3 forms covered">
|
<span class="covered" title="3 out of 3 forms covered">
|
||||||
056 (range height))))
|
074 (range height))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
057
|
075
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
058 (defn truncate-state
|
076 (defn truncate-state
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
059 "Truncate the print name of the state of this cell to at most limit characters."
|
077 "Truncate the print name of the state of this cell to at most limit characters."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
060 [cell limit]
|
078 [cell limit]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
061 (let [s (:state cell)]
|
079 (let [s (:state cell)]
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 13 forms covered">
|
|
||||||
062 (cond (> (count (str s)) limit) (subs s 0 limit)
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
063 :else s)))
|
080 (try
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 15 forms covered">
|
||||||
|
081 (cond (> (count (str s)) limit) (subs (name s) 0 limit)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
082 :else s)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
|
083 (catch Exception any
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
|
084 (throw (ex-info (.getMessage any)
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 5 forms covered">
|
||||||
|
085 {:cell cell
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
086 :limit limit
|
||||||
|
</span><br/>
|
||||||
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
|
087 :exception-class (.getClass any)}))))))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
064
|
088
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
065 (defn format-cell
|
089 (defn format-cell
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
066 "Return a formatted string summarising the current state of this cell."
|
090 "Return a formatted string summarising the current state of this cell."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
067 [cell]
|
091 [cell]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
068 (format "%10s(%2d/%2d)"
|
092 (format "%10s"
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
<span class="not-covered" title="0 out of 4 forms covered">
|
||||||
069 (truncate-state cell 10)
|
093 (truncate-state cell 10)))
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
|
||||||
070 (population cell :deer)
|
|
||||||
</span><br/>
|
|
||||||
<span class="not-covered" title="0 out of 4 forms covered">
|
|
||||||
071 (population cell :wolves)))
|
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
072
|
094
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="covered" title="1 out of 1 forms covered">
|
<span class="covered" title="1 out of 1 forms covered">
|
||||||
073 (defn- format-world-row
|
095 (defn- format-world-row
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
074 "Format one row in the state of a world for printing."
|
096 "Format one row in the state of a world for printing."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
075 [row]
|
097 [row]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 6 forms covered">
|
<span class="not-covered" title="0 out of 6 forms covered">
|
||||||
076 (string/join (map format-cell row)))
|
098 (string/join (map format-cell row)))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
077
|
099
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="partial" title="1 out of 2 forms covered">
|
<span class="partial" title="1 out of 2 forms covered">
|
||||||
078 (defn print-world
|
100 (defn print-world
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
079 "Print the current state of this world, and return nil.
|
101 "Print the current state of this world, and return nil.
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="blank" title="0 out of 0 forms covered">
|
<span class="blank" title="0 out of 0 forms covered">
|
||||||
080
|
102
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
081 * `world` a world as defined above."
|
103 * `world` a world as defined above."
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
082 [world]
|
104 [world]
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
083 (println)
|
105 (println)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
084 (dorun
|
106 (dorun
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
085 (map
|
107 (map
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 2 forms covered">
|
<span class="not-covered" title="0 out of 2 forms covered">
|
||||||
086 #(println
|
108 #(println
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 3 forms covered">
|
<span class="not-covered" title="0 out of 3 forms covered">
|
||||||
087 (format-world-row %))
|
109 (format-world-row %))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-covered" title="0 out of 1 forms covered">
|
<span class="not-covered" title="0 out of 1 forms covered">
|
||||||
088 world))
|
110 world))
|
||||||
</span><br/>
|
</span><br/>
|
||||||
<span class="not-tracked" title="0 out of 0 forms covered">
|
<span class="not-tracked" title="0 out of 0 forms covered">
|
||||||
089 nil)
|
111 nil)
|
||||||
</span><br/>
|
</span><br/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
:doc/format :markdown}
|
:doc/format :markdown}
|
||||||
:output-path "docs/codox"
|
:output-path "docs/codox"
|
||||||
:source-uri "https://github.com/simon-brooke/mw-engine/blob/master/{filepath}#L{line}"}
|
: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/clojurescript "1.11.60" :scope "provided"]
|
||||||
[org.clojure/math.combinatorics "0.2.0"]
|
[org.clojure/math.combinatorics "0.2.0"]
|
||||||
[org.clojure/tools.trace "0.7.11"]
|
[org.clojure/tools.trace "0.7.11"]
|
||||||
|
|
BIN
resources/heightmaps/20x20/crucible.png
Normal file
BIN
resources/heightmaps/20x20/crucible.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/heightmaps/20x20/crucible.xcf
Normal file
BIN
resources/heightmaps/20x20/crucible.xcf
Normal file
Binary file not shown.
1
resources/test.edn
Normal file
1
resources/test.edn
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{:hello "goodbye"}
|
|
@ -22,7 +22,8 @@
|
||||||
further rules can be applied to that cell."
|
further rules can be applied to that cell."
|
||||||
:author "Simon Brooke"}
|
:author "Simon Brooke"}
|
||||||
mw-engine.core
|
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]]
|
[mw-engine.utils :refer [add-history-event get-int-or-zero map-world rule-type]]
|
||||||
[taoensso.timbre :as l]))
|
[taoensso.timbre :as l]))
|
||||||
|
|
||||||
|
@ -54,6 +55,10 @@
|
||||||
memory problems. Make it optional, but by default false."
|
memory problems. Make it optional, but by default false."
|
||||||
false)
|
false)
|
||||||
|
|
||||||
|
(def known-rule-types
|
||||||
|
"Types of rules we know about."
|
||||||
|
#{:ad-hoc :flow :production})
|
||||||
|
|
||||||
(defn apply-rule
|
(defn apply-rule
|
||||||
"Apply a single `rule` to a `cell`. What this is about is that I want to be able,
|
"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
|
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!
|
;; Yes, that `list` is there for a reason!
|
||||||
(list
|
(list
|
||||||
(filter
|
(filter
|
||||||
#(= :production (rule-type %))
|
#(#{:ad-hoc :production} (rule-type %))
|
||||||
rules))))
|
rules))))
|
||||||
|
|
||||||
(defn run-world
|
(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;
|
* `world` a world as discussed above;
|
||||||
* `init-rules` a sequence of rules as defined above, to be run once to initialise the world;
|
* `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;
|
* `rules` a sequence of rules as defined above, to be run iteratively for each generation;
|
||||||
* `generations` an (integer) number of generations.
|
* `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.
|
be executed.
|
||||||
|
|
||||||
Return the final generation of the world."
|
Return the final generation of the world."
|
||||||
([world rules generations]
|
([world rules generations]
|
||||||
(run-world world rules rules (dec generations)))
|
(run-world world rules rules (dec generations)))
|
||||||
([world init-rules rules generations]
|
([world init-rules rules generations]
|
||||||
(reduce (fn [world iteration]
|
|
||||||
(l/info "Running iteration " iteration)
|
(let [found-types (map rule-type (concat init-rules rules))]
|
||||||
(let [w' (transform-world world rules)]
|
(if (every? known-rule-types found-types)
|
||||||
(flow-world w' rules)))
|
(reduce (fn [world iteration]
|
||||||
(transform-world world init-rules)
|
(l/info "Running iteration " iteration)
|
||||||
(range generations))))
|
(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})))))))
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
compute drainage on a world, assumed to have altitudes already set
|
compute drainage on a world, assumed to have altitudes already set
|
||||||
from a heightmap."
|
from a heightmap."
|
||||||
:author "Simon Brooke"}
|
:author "Simon Brooke"}
|
||||||
mw-engine.drainage
|
mw-engine.drainage
|
||||||
(:require [mw-engine.core :refer [run-world]]
|
(: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
|
[mw-engine.utils :refer [get-int-or-zero get-least-cell get-neighbours
|
||||||
get-neighbours-with-property-value
|
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
|
"Compute rainfall for a cell with this `gradient` west-east, given
|
||||||
`remaining` drops to distribute, and this overall map width."
|
`remaining` drops to distribute, and this overall map width."
|
||||||
[gradient remaining map-width]
|
[gradient remaining map-width]
|
||||||
(cond
|
(cond
|
||||||
;; if there's no rain left in the cloud, it can't fall;
|
;; if there's no rain left in the cloud, it can't fall;
|
||||||
(zero? remaining)
|
(zero? remaining)
|
||||||
0
|
0
|
||||||
(pos? gradient)
|
(pos? gradient)
|
||||||
;; rain, on prevailing westerly wind, falls preferentially on rising ground;
|
;; 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...
|
;; rain falls randomly across the width of the map...
|
||||||
(zero? (int (rand map-width))) 1
|
(zero? (int (rand map-width))) 1
|
||||||
:else
|
:else
|
||||||
0))
|
0))
|
||||||
|
|
||||||
(defn rain-row
|
(defn rain-row
|
||||||
"Return a row like this `row`, across which rainfall has been distributed;
|
"Return a row like this `row`, across which rainfall has been distributed;
|
||||||
|
@ -71,12 +72,12 @@
|
||||||
rising (- alt previous-altitude)
|
rising (- alt previous-altitude)
|
||||||
fall (rainfall rising drops-in-cloud map-width)]
|
fall (rainfall rising drops-in-cloud map-width)]
|
||||||
(cons
|
(cons
|
||||||
(assoc cell :rainfall fall)
|
(assoc cell :rainfall fall)
|
||||||
(rain-row (rest row) map-width alt (- drops-in-cloud fall))))
|
(rain-row (rest row) map-width alt (- drops-in-cloud fall))))
|
||||||
:else
|
:else
|
||||||
(map
|
(map
|
||||||
#(assoc % :rainfall 0)
|
#(assoc % :rainfall 0)
|
||||||
row))))
|
row))))
|
||||||
|
|
||||||
|
|
||||||
(defn rain-world
|
(defn rain-world
|
||||||
|
@ -84,8 +85,8 @@
|
||||||
rain more on west-facing slopes, and less to the east of high ground"
|
rain more on west-facing slopes, and less to the east of high ground"
|
||||||
[world]
|
[world]
|
||||||
(map
|
(map
|
||||||
rain-row
|
rain-row
|
||||||
world))
|
world))
|
||||||
|
|
||||||
|
|
||||||
(defn flow-contributors
|
(defn flow-contributors
|
||||||
|
@ -95,14 +96,14 @@
|
||||||
[cell world]
|
[cell world]
|
||||||
(filter #(map? %)
|
(filter #(map? %)
|
||||||
(map
|
(map
|
||||||
(fn [n]
|
(fn [n]
|
||||||
(cond
|
(cond
|
||||||
(= cell (get-least-cell (get-neighbours world n) :altitude)) n
|
(= cell (get-least-cell (get-neighbours world n) :altitude)) n
|
||||||
(and (= (:altitude cell) (:altitude n))
|
(and (= (:altitude cell) (:altitude n))
|
||||||
(> (or (:flow n) 0) (or (:flow cell) 0))) n))
|
(> (or (:flow n) 0) (or (:flow cell) 0))) n))
|
||||||
(get-neighbours-with-property-value
|
(get-neighbours-with-property-value
|
||||||
world (:x cell) (:y cell) 1 :altitude
|
world (:x cell) (:y cell) 1 :altitude
|
||||||
(or (:altitude cell) 0) >=))))
|
(or (:altitude cell) 0) >=))))
|
||||||
|
|
||||||
|
|
||||||
(defn is-hollow
|
(defn is-hollow
|
||||||
|
@ -116,17 +117,17 @@
|
||||||
altitude (get-int-or-zero cell :altitude)]
|
altitude (get-int-or-zero cell :altitude)]
|
||||||
(= (count neighbours)
|
(= (count neighbours)
|
||||||
(count (get-neighbours-with-property-value
|
(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
|
(defn flood-hollow
|
||||||
"Raise the altitude of a copy of this `cell` of this `world` to the altitude
|
"Raise the altitude of a copy of this `cell` of this `world` to the altitude
|
||||||
of the lowest of its `neighbours`."
|
of the lowest of its `neighbours`."
|
||||||
([_world cell neighbours]
|
([_world cell neighbours]
|
||||||
(let [lowest (get-least-cell neighbours :altitude)]
|
(let [lowest (get-least-cell neighbours :altitude)]
|
||||||
(merge cell {:state :water :altitude (:altitude lowest)})))
|
(merge cell {:state :water :altitude (:altitude lowest)})))
|
||||||
([world cell]
|
([world cell]
|
||||||
(flood-hollow world cell (get-neighbours world cell))))
|
(flood-hollow world cell (get-neighbours world cell))))
|
||||||
|
|
||||||
|
|
||||||
(defn flood-hollows
|
(defn flood-hollows
|
||||||
|
@ -146,14 +147,21 @@
|
||||||
`flow-world-nr`."
|
`flow-world-nr`."
|
||||||
[cell world]
|
[cell world]
|
||||||
(when (= (- max-altitude (get-int-or-zero cell :generation))
|
(when (= (- max-altitude (get-int-or-zero cell :generation))
|
||||||
(get-int-or-zero cell :altitude))
|
(get-int-or-zero cell :altitude))
|
||||||
(merge cell
|
(let [contributors (flow-contributors cell world)]
|
||||||
{:flow (reduce +
|
(when contributors
|
||||||
(map
|
(merge cell
|
||||||
#(+ (get-int-or-zero % :rainfall)
|
{:flow (reduce +
|
||||||
(get-int-or-zero % :flow))
|
(map
|
||||||
(flow-contributors cell world)))})))
|
#(+ (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
|
(def flow
|
||||||
"Compute the total flow upstream of this `cell` in this `world`, and return a cell identical
|
"Compute the total flow upstream of this `cell` in this `world`, and return a cell identical
|
||||||
|
@ -165,20 +173,19 @@
|
||||||
(memoize
|
(memoize
|
||||||
(fn [cell world]
|
(fn [cell world]
|
||||||
(cond
|
(cond
|
||||||
(not (nil? (:flow cell))) cell
|
(not (nil? (:flow cell))) cell
|
||||||
(<= (or (:altitude cell) 0) *sealevel*) cell
|
(<= (or (:altitude cell) 0) *sealevel*) cell
|
||||||
:else
|
:else
|
||||||
(merge cell
|
(merge cell
|
||||||
{:flow (+ (:rainfall cell)
|
{:flow (+ (:rainfall cell)
|
||||||
(apply +
|
(apply +
|
||||||
(map (fn [neighbour] (:flow (flow neighbour world)))
|
(map (fn [neighbour] (:flow (flow neighbour world)))
|
||||||
(flow-contributors cell world))))})))))
|
(flow-contributors cell world))))})))))
|
||||||
|
|
||||||
|
|
||||||
(defn flow-world-nr
|
(defn flow-world-nr
|
||||||
"Experimental non-recursive flow-world algorithm"
|
"Experimental non-recursive flow-world algorithm"
|
||||||
[world]
|
[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
|
(defn flow-world
|
||||||
"Return a world like this `world`, but with cells tagged with the amount of
|
"Return a world like this `world`, but with cells tagged with the amount of
|
||||||
|
@ -189,8 +196,7 @@
|
||||||
(defn explore-lake
|
(defn explore-lake
|
||||||
"Return a sequence of cells starting with this `cell` in this `world` which
|
"Return a sequence of cells starting with this `cell` in this `world` which
|
||||||
form a contiguous lake"
|
form a contiguous lake"
|
||||||
[_world _cell]
|
[_world _cell])
|
||||||
)
|
|
||||||
|
|
||||||
(defn is-lake?
|
(defn is-lake?
|
||||||
"If this `cell` in this `world` is not part of a lake, return nil. If it is,
|
"If this `cell` in this `world` is not part of a lake, return nil. If it is,
|
||||||
|
@ -198,20 +204,21 @@
|
||||||
[world cell]
|
[world cell]
|
||||||
(if
|
(if
|
||||||
;; if it's already tagged as a lake, it's a lake
|
;; if it's already tagged as a lake, it's a lake
|
||||||
(:lake cell) cell
|
(:lake cell) cell
|
||||||
(let
|
(let
|
||||||
[outflow (apply min (map :altitude (get-neighbours world cell)))]
|
[outflow (apply min (map :altitude (get-neighbours world cell)))]
|
||||||
(when-not
|
(when-not
|
||||||
(> (:altitude cell) outflow)
|
(> (:altitude cell) outflow)
|
||||||
(assoc cell :lake true)))))
|
(assoc cell :lake true :state :lake)))))
|
||||||
|
|
||||||
|
|
||||||
(defn find-lakes
|
(defn find-lakes
|
||||||
[_world]
|
[_world])
|
||||||
)
|
|
||||||
|
|
||||||
(defn run-drainage
|
(defn run-drainage
|
||||||
"Create a world from the heightmap `hmap`, rain on it, and then compute river
|
"Create a world from the heightmap `hmap`, rain on it, and then compute river
|
||||||
flows."
|
flows."
|
||||||
[hmap]
|
[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")
|
|
@ -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
|
(defn tag-property
|
||||||
"Set the value of this `property` of this cell from the corresponding pixel of this `heightmap`.
|
"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.
|
If the heightmap you supply is smaller than the world, this will break.
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
"Format this statekey, assumed to be a keyword indicating a state in the
|
"Format this statekey, assumed to be a keyword indicating a state in the
|
||||||
world, into a CSS class"
|
world, into a CSS class"
|
||||||
[statekey]
|
[statekey]
|
||||||
(name statekey))
|
(when statekey (name statekey)))
|
||||||
|
|
||||||
(defn format-image-path
|
(defn format-image-path
|
||||||
"Render this statekey, assumed to be a keyword indicating a state in the
|
"Render this statekey, assumed to be a keyword indicating a state in the
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
:author "Simon Brooke"}
|
:author "Simon Brooke"}
|
||||||
mw-engine.utils
|
mw-engine.utils
|
||||||
(:require [clojure.math.combinatorics :as combo]
|
(: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))
|
(map-world world function nil))
|
||||||
([world function additional-args]
|
([world function additional-args]
|
||||||
(into []
|
(into []
|
||||||
(pmap (fn [row]
|
(pmap* (fn [row]
|
||||||
(into [] (map
|
(into [] (map
|
||||||
#(apply function
|
#(apply function
|
||||||
(cons world (cons % additional-args)))
|
(cons world (cons % additional-args)))
|
||||||
|
|
|
@ -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)))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue