Some work on flow, but mainly tidyup.

This commit is contained in:
Simon Brooke 2023-07-11 08:22:54 +01:00
parent 4f35557b38
commit 866c00bea0
37 changed files with 5840 additions and 623 deletions

View file

@ -0,0 +1,40 @@
.covered {
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
background-color: #558B55;
}
.not-covered {
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
background-color: red;
}
.partial {
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
background-color: orange;
}
.not-tracked {
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
}
.blank {
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
}
td {
padding-right: 10px;
}
td.with-bar {
width: 250px;
text-align: center;
}
td.with-number {
text-align: right;
}
td.ns-name {
min-width: 150px;
padding-right: 25px;
}

157
docs/cloverage/index.html Normal file
View file

@ -0,0 +1,157 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="./coverage.css"/>
<title>Coverage Summary</title>
</head>
<body>
<table>
<thead><tr>
<td class="ns-name"> Namespace </td>
<td class="with-bar"> Forms </td>
<td class="with-number">Forms %</td>
<td class="with-bar"> Lines </td>
<td class="with-number">Lines %</td>
<td class="with-number">Total</td><td class="with-number">Blank</td><td class="with-number">Instrumented</td>
</tr></thead>
<tr>
<td><a href="mw_engine/core.clj.html">mw-engine.core</a></td><td class="with-bar"><div class="covered"
style="width:33.116883116883116%;
float:left;"> 51 </div><div class="not-covered"
style="width:66.88311688311688%;
float:left;"> 103 </div></td>
<td class="with-number">33.12 %</td>
<td class="with-bar"><div class="covered"
style="width:36.36363636363637%;
float:left;"> 12 </div><div class="partial"
style="width:3.0303030303030303%;
float:left;"> 1 </div><div class="not-covered"
style="width:60.60606060606061%;
float:left;"> 20 </div></td>
<td class="with-number">39.39 %</td>
<td class="with-number">115</td><td class="with-number">15</td><td class="with-number">33</td>
</tr>
<tr>
<td><a href="mw_engine/display.clj.html">mw-engine.display</a></td><td class="with-bar"><div class="covered"
style="width:10.227272727272727%;
float:left;"> 9 </div><div class="not-covered"
style="width:89.77272727272727%;
float:left;"> 79 </div></td>
<td class="with-number">10.23 %</td>
<td class="with-bar"><div class="covered"
style="width:42.10526315789474%;
float:left;"> 8 </div><div class="not-covered"
style="width:57.89473684210526%;
float:left;"> 11 </div></td>
<td class="with-number">42.11 %</td>
<td class="with-number">65</td><td class="with-number">8</td><td class="with-number">19</td>
</tr>
<tr>
<td><a href="mw_engine/drainage.clj.html">mw-engine.drainage</a></td><td class="with-bar"><div class="covered"
style="width:22.62210796915167%;
float:left;"> 88 </div><div class="not-covered"
style="width:77.37789203084833%;
float:left;"> 301 </div></td>
<td class="with-number">22.62 %</td>
<td class="with-bar"><div class="covered"
style="width:34.44444444444444%;
float:left;"> 31 </div><div class="not-covered"
style="width:65.55555555555556%;
float:left;"> 59 </div></td>
<td class="with-number">34.44 %</td>
<td class="with-number">217</td><td class="with-number">30</td><td class="with-number">90</td>
</tr>
<tr>
<td><a href="mw_engine/flow.clj.html">mw-engine.flow</a></td><td class="with-bar"><div class="covered"
style="width:86.62790697674419%;
float:left;"> 447 </div><div class="not-covered"
style="width:13.372093023255815%;
float:left;"> 69 </div></td>
<td class="with-number">86.63 %</td>
<td class="with-bar"><div class="covered"
style="width:85.45454545454545%;
float:left;"> 47 </div><div class="partial"
style="width:7.2727272727272725%;
float:left;"> 4 </div><div class="not-covered"
style="width:7.2727272727272725%;
float:left;"> 4 </div></td>
<td class="with-number">92.73 %</td>
<td class="with-number">141</td><td class="with-number">15</td><td class="with-number">55</td>
</tr>
<tr>
<td><a href="mw_engine/heightmap.clj.html">mw-engine.heightmap</a></td><td class="with-bar"><div class="covered"
style="width:92.51700680272108%;
float:left;"> 136 </div><div class="not-covered"
style="width:7.482993197278912%;
float:left;"> 11 </div></td>
<td class="with-number">92.52 %</td>
<td class="with-bar"><div class="covered"
style="width:90.9090909090909%;
float:left;"> 40 </div><div class="partial"
style="width:4.545454545454546%;
float:left;"> 2 </div><div class="not-covered"
style="width:4.545454545454546%;
float:left;"> 2 </div></td>
<td class="with-number">95.45 %</td>
<td class="with-number">127</td><td class="with-number">11</td><td class="with-number">44</td>
</tr>
<tr>
<td><a href="mw_engine/natural_rules.clj.html">mw-engine.natural-rules</a></td><td class="with-bar"><div class="covered"
style="width:7.774390243902439%;
float:left;"> 51 </div><div class="not-covered"
style="width:92.22560975609755%;
float:left;"> 605 </div></td>
<td class="with-number">7.77 %</td>
<td class="with-bar"><div class="covered"
style="width:33.0188679245283%;
float:left;"> 35 </div><div class="partial"
style="width:4.716981132075472%;
float:left;"> 5 </div><div class="not-covered"
style="width:62.264150943396224%;
float:left;"> 66 </div></td>
<td class="with-number">37.74 %</td>
<td class="with-number">184</td><td class="with-number">14</td><td class="with-number">106</td>
</tr>
<tr>
<td><a href="mw_engine/utils.clj.html">mw-engine.utils</a></td><td class="with-bar"><div class="covered"
style="width:69.88847583643123%;
float:left;"> 376 </div><div class="not-covered"
style="width:30.111524163568774%;
float:left;"> 162 </div></td>
<td class="with-number">69.89 %</td>
<td class="with-bar"><div class="covered"
style="width:73.21428571428571%;
float:left;"> 82 </div><div class="partial"
style="width:0.8928571428571429%;
float:left;"> 1 </div><div class="not-covered"
style="width:25.892857142857142%;
float:left;"> 29 </div></td>
<td class="with-number">74.11 %</td>
<td class="with-number">301</td><td class="with-number">35</td><td class="with-number">112</td>
</tr>
<tr>
<td><a href="mw_engine/world.clj.html">mw-engine.world</a></td><td class="with-bar"><div class="covered"
style="width:54.310344827586206%;
float:left;"> 63 </div><div class="not-covered"
style="width:45.689655172413794%;
float:left;"> 53 </div></td>
<td class="with-number">54.31 %</td>
<td class="with-bar"><div class="covered"
style="width:42.30769230769231%;
float:left;"> 11 </div><div class="partial"
style="width:3.8461538461538463%;
float:left;"> 1 </div><div class="not-covered"
style="width:53.84615384615385%;
float:left;"> 14 </div></td>
<td class="with-number">46.15 %</td>
<td class="with-number">89</td><td class="with-number">12</td><td class="with-number">26</td>
</tr>
<tr><td>Totals:</td>
<td class="with-bar"></td>
<td class="with-number">46.89 %</td>
<td class="with-bar"></td>
<td class="with-number">57.73 %</td>
</tr>
</table>
</body>
</html>

View file

@ -0,0 +1,353 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> mw_engine/core.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;^{:doc&nbsp;&quot;Functions&nbsp;to&nbsp;transform&nbsp;a&nbsp;world&nbsp;and&nbsp;run&nbsp;rules.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Every&nbsp;rule&nbsp;is&nbsp;a&nbsp;function&nbsp;of&nbsp;two&nbsp;arguments,&nbsp;a&nbsp;cell&nbsp;and&nbsp;a&nbsp;world.&nbsp;If&nbsp;the&nbsp;rule
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fires,&nbsp;it&nbsp;returns&nbsp;a&nbsp;new&nbsp;cell,&nbsp;which&nbsp;should&nbsp;have&nbsp;the&nbsp;same&nbsp;values&nbsp;for&nbsp;`:x`&nbsp;and
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`:y`&nbsp;as&nbsp;the&nbsp;old&nbsp;cell.&nbsp;Anything&nbsp;else&nbsp;can&nbsp;be&nbsp;modified.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
006&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;While&nbsp;any&nbsp;function&nbsp;of&nbsp;two&nbsp;arguments&nbsp;can&nbsp;be&nbsp;used&nbsp;as&nbsp;a&nbsp;rule,&nbsp;a&nbsp;special&nbsp;high
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;level&nbsp;rule&nbsp;language&nbsp;is&nbsp;provided&nbsp;by&nbsp;the&nbsp;`mw-parser`&nbsp;package,&nbsp;which&nbsp;compiles
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rules&nbsp;expressed&nbsp;in&nbsp;a&nbsp;subset&nbsp;of&nbsp;English&nbsp;rules&nbsp;into&nbsp;suitable&nbsp;functions.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
010&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;cell&nbsp;is&nbsp;a&nbsp;map&nbsp;containing&nbsp;at&nbsp;least&nbsp;values&nbsp;for&nbsp;the&nbsp;keys&nbsp;:x,&nbsp;:y,&nbsp;and&nbsp;:state;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;transformation&nbsp;should&nbsp;not&nbsp;alter&nbsp;the&nbsp;values&nbsp;of&nbsp;:x&nbsp;or&nbsp;:y,&nbsp;and&nbsp;should&nbsp;not
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;a&nbsp;cell&nbsp;without&nbsp;a&nbsp;keyword&nbsp;as&nbsp;the&nbsp;value&nbsp;of&nbsp;:state.&nbsp;Anything&nbsp;else&nbsp;is
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;legal.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
015&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;world&nbsp;is&nbsp;a&nbsp;two&nbsp;dimensional&nbsp;matrix&nbsp;(sequence&nbsp;of&nbsp;sequences)&nbsp;of&nbsp;cells,&nbsp;such
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;every&nbsp;cell&#x27;s&nbsp;`:x`&nbsp;and&nbsp;`:y`&nbsp;properties&nbsp;reflect&nbsp;its&nbsp;place&nbsp;in&nbsp;the&nbsp;matrix.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;See&nbsp;`world.clj`.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
019&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Each&nbsp;time&nbsp;the&nbsp;world&nbsp;is&nbsp;transformed&nbsp;(see&nbsp;`transform-world`),&nbsp;for&nbsp;each&nbsp;cell,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rules&nbsp;are&nbsp;applied&nbsp;in&nbsp;turn&nbsp;until&nbsp;one&nbsp;matches.&nbsp;Once&nbsp;one&nbsp;rule&nbsp;has&nbsp;matched&nbsp;no
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;further&nbsp;rules&nbsp;can&nbsp;be&nbsp;applied&nbsp;to&nbsp;that&nbsp;cell.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:author&nbsp;&quot;Simon&nbsp;Brooke&quot;}
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;&nbsp;mw-engine.core
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[mw-engine.utils&nbsp;:refer&nbsp;[get-int-or-zero&nbsp;map-world]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[taoensso.timbre&nbsp;:as&nbsp;l]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
027&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;;;;;&nbsp;mw-engine:&nbsp;the&nbsp;state&#x2F;transition&nbsp;engine&nbsp;of&nbsp;MicroWorld.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;;;;;&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2014&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
050&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
051&nbsp;&nbsp;(defn&nbsp;apply-rule
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&quot;Apply&nbsp;a&nbsp;single&nbsp;`rule`&nbsp;to&nbsp;a&nbsp;`cell`.&nbsp;What&nbsp;this&nbsp;is&nbsp;about&nbsp;is&nbsp;that&nbsp;I&nbsp;want&nbsp;to&nbsp;be&nbsp;able,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;debugging&nbsp;purposes,&nbsp;to&nbsp;tag&nbsp;a&nbsp;cell&nbsp;with&nbsp;the&nbsp;rule&nbsp;text&nbsp;of&nbsp;the&nbsp;rule&nbsp;which
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fired&nbsp;(and&nbsp;especially&nbsp;so&nbsp;when&nbsp;an&nbsp;exception&nbsp;is&nbsp;thrown.&nbsp;So&nbsp;a&nbsp;rule&nbsp;may&nbsp;be&nbsp;either
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;an&nbsp;ifn,&nbsp;or&nbsp;a&nbsp;list&nbsp;(ifn&nbsp;source-text).&nbsp;This&nbsp;function&nbsp;deals&nbsp;with&nbsp;despatching
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;on&nbsp;those&nbsp;two&nbsp;possibilities.&nbsp;`world`&nbsp;is&nbsp;also&nbsp;passed&nbsp;in&nbsp;in&nbsp;order&nbsp;to&nbsp;be&nbsp;able
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;access&nbsp;neighbours.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;cell&nbsp;rule]
</span><br/>
<span class="partial" title="2 out of 3 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(ifn?&nbsp;rule)&nbsp;(apply-rule&nbsp;world&nbsp;cell&nbsp;rule&nbsp;nil)
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(seq?&nbsp;rule)&nbsp;(let&nbsp;[[afn&nbsp;src]&nbsp;rule]&nbsp;(apply-rule&nbsp;world&nbsp;cell&nbsp;afn&nbsp;src))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;cell&nbsp;rule&nbsp;source]
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[result&nbsp;(apply&nbsp;rule&nbsp;(list&nbsp;cell&nbsp;world))]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;result&nbsp;source)&nbsp;(merge&nbsp;result&nbsp;{:rule&nbsp;source})
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;result))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
067&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
068&nbsp;&nbsp;(defn-&nbsp;apply-rules
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&quot;Derive&nbsp;a&nbsp;cell&nbsp;from&nbsp;this&nbsp;`cell`&nbsp;of&nbsp;this&nbsp;`world`&nbsp;by&nbsp;applying&nbsp;these&nbsp;`rules`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;cell&nbsp;rules]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(empty?&nbsp;rules)&nbsp;cell
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(let&nbsp;[result&nbsp;(apply-rule&nbsp;world&nbsp;cell&nbsp;(first&nbsp;rules))]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;result&nbsp;result
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(apply-rules&nbsp;world&nbsp;cell&nbsp;(rest&nbsp;rules))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
075&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
076&nbsp;&nbsp;(defn-&nbsp;transform-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&quot;Derive&nbsp;a&nbsp;cell&nbsp;from&nbsp;this&nbsp;`cell`&nbsp;of&nbsp;this&nbsp;`world`&nbsp;by&nbsp;applying&nbsp;these&nbsp;`rules`.&nbsp;If&nbsp;an
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exception&nbsp;is&nbsp;thrown,&nbsp;cache&nbsp;its&nbsp;message&nbsp;on&nbsp;the&nbsp;cell&nbsp;and&nbsp;set&nbsp;it&#x27;s&nbsp;state&nbsp;to&nbsp;error&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;cell&nbsp;rules]
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply-rules&nbsp;world&nbsp;cell&nbsp;rules)
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:generation&nbsp;(+&nbsp;(get-int-or-zero&nbsp;cell&nbsp;:generation)&nbsp;1)})
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:error
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(format&nbsp;&quot;%s&nbsp;at&nbsp;generation&nbsp;%d&nbsp;when&nbsp;in&nbsp;state&nbsp;%s&quot;
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.getMessage&nbsp;e)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:generation&nbsp;cell)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:state&nbsp;cell))
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:stacktrace&nbsp;(map&nbsp;#(.toString&nbsp;%)&nbsp;(.getStackTrace&nbsp;e))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:state&nbsp;:error}))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
092&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
093&nbsp;&nbsp;(defn&nbsp;transform-world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;world&nbsp;derived&nbsp;from&nbsp;this&nbsp;`world`&nbsp;by&nbsp;applying&nbsp;these&nbsp;`rules`&nbsp;to&nbsp;each&nbsp;cell.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;rules]
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;transform-cell&nbsp;(list&nbsp;rules))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
097&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
098&nbsp;&nbsp;(defn&nbsp;run-world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;&quot;Run&nbsp;this&nbsp;world&nbsp;with&nbsp;these&nbsp;rules&nbsp;for&nbsp;this&nbsp;number&nbsp;of&nbsp;generations.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
100&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world&nbsp;as&nbsp;discussed&nbsp;above;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`init-rules`&nbsp;a&nbsp;sequence&nbsp;of&nbsp;rules&nbsp;as&nbsp;defined&nbsp;above,&nbsp;to&nbsp;be&nbsp;run&nbsp;once&nbsp;to&nbsp;initialise&nbsp;the&nbsp;world;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`rules`&nbsp;a&nbsp;sequence&nbsp;of&nbsp;rules&nbsp;as&nbsp;defined&nbsp;above,&nbsp;to&nbsp;be&nbsp;run&nbsp;iteratively&nbsp;for&nbsp;each&nbsp;generation;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`generations`&nbsp;an&nbsp;(integer)&nbsp;number&nbsp;of&nbsp;generations.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
105&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;Return&nbsp;the&nbsp;final&nbsp;generation&nbsp;of&nbsp;the&nbsp;world.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;init-rules&nbsp;rules&nbsp;generations]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;(reduce&nbsp;(fn&nbsp;[world&nbsp;iteration]
</span><br/>
<span class="not-covered" title="0 out of 17 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(l&#x2F;info&nbsp;&quot;Running&nbsp;iteration&nbsp;&quot;&nbsp;iteration)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(transform-world&nbsp;world&nbsp;rules))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(transform-world&nbsp;world&nbsp;init-rules)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(range&nbsp;generations)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
113&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
114&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
115&nbsp;&nbsp;
</span><br/>
</body>
</html>

View file

@ -0,0 +1,203 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> mw_engine/display.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;^{:doc&nbsp;&quot;Simple&nbsp;functions&nbsp;to&nbsp;allow&nbsp;a&nbsp;world&nbsp;to&nbsp;be&nbsp;visualised.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:author&nbsp;&quot;Simon&nbsp;Brooke&quot;}
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;mw-engine.display)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
004&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;;;;;&nbsp;mw-engine:&nbsp;the&nbsp;state&#x2F;transition&nbsp;engine&nbsp;of&nbsp;MicroWorld.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;;;;;&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2014&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
027&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
028&nbsp;&nbsp;(def&nbsp;^:dynamic&nbsp;*image-base*
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;&nbsp;&nbsp;&quot;Base&nbsp;url&nbsp;(i.e.,&nbsp;url&nbsp;of&nbsp;directory)&nbsp;from&nbsp;which&nbsp;to&nbsp;load&nbsp;tile&nbsp;images.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;&nbsp;&nbsp;&quot;img&#x2F;tiles&quot;)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
031&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
032&nbsp;&nbsp;(defn&nbsp;format-css-class
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;&quot;Format&nbsp;this&nbsp;`state`,&nbsp;assumed&nbsp;to&nbsp;be&nbsp;a&nbsp;keyword&nbsp;indicating&nbsp;a&nbsp;state&nbsp;in&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world,&nbsp;into&nbsp;a&nbsp;CSS&nbsp;class&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;&nbsp;&nbsp;[state]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;(subs&nbsp;(str&nbsp;state)&nbsp;1))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
037&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
038&nbsp;&nbsp;(defn&nbsp;format-image-path
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&quot;Render&nbsp;this&nbsp;`state`,&nbsp;assumed&nbsp;to&nbsp;be&nbsp;a&nbsp;keyword&nbsp;indicating&nbsp;a&nbsp;state&nbsp;in&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world,&nbsp;into&nbsp;a&nbsp;path&nbsp;which&nbsp;should&nbsp;recover&nbsp;the&nbsp;corresponding&nbsp;image&nbsp;file.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;[state]
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;(format&nbsp;&quot;%s&#x2F;%s.png&quot;&nbsp;*image-base*&nbsp;(format-css-class&nbsp;state)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
043&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
044&nbsp;&nbsp;(defn&nbsp;format-mouseover&nbsp;[cell]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;(str&nbsp;cell))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
046&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
047&nbsp;&nbsp;(defn&nbsp;render-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&quot;Render&nbsp;this&nbsp;world&nbsp;cell&nbsp;as&nbsp;a&nbsp;Hiccup&nbsp;table&nbsp;cell.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;[cell]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[state&nbsp;(:state&nbsp;cell)]
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:td&nbsp;{:class&nbsp;(format-css-class&nbsp;state)&nbsp;:title&nbsp;(format-mouseover&nbsp;cell)}
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:a&nbsp;{:href&nbsp;(format&nbsp;&quot;inspect?x=%d&amp;y=%d&quot;&nbsp;(:x&nbsp;cell)&nbsp;(:y&nbsp;cell))}
</span><br/>
<span class="not-covered" title="0 out of 15 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[:img&nbsp;{:alt&nbsp;(:state&nbsp;cell)&nbsp;:width&nbsp;32&nbsp;:height&nbsp;32&nbsp;:src&nbsp;(format-image-path&nbsp;state)}]]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
054&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
055&nbsp;&nbsp;(defn&nbsp;render-world-row
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&quot;Render&nbsp;this&nbsp;world&nbsp;`row`&nbsp;as&nbsp;a&nbsp;Hiccup&nbsp;table&nbsp;row.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;[row]
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;vector&nbsp;(cons&nbsp;:tr&nbsp;(map&nbsp;render-cell&nbsp;row))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
059&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
060&nbsp;&nbsp;(defn&nbsp;render-world-table
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&quot;Render&nbsp;this&nbsp;`world`&nbsp;as&nbsp;a&nbsp;Hiccup&nbsp;table.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;[world]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;vector
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;:table
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;render-world-row&nbsp;world))))
</span><br/>
</body>
</html>

View file

@ -0,0 +1,659 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> mw_engine/drainage.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;^{:doc&nbsp;&quot;Experimental,&nbsp;probably&nbsp;of&nbsp;no&nbsp;interest&nbsp;to&nbsp;anyone&nbsp;else;&nbsp;attempt&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;compute&nbsp;drainage&nbsp;on&nbsp;a&nbsp;world,&nbsp;assumed&nbsp;to&nbsp;have&nbsp;altitudes&nbsp;already&nbsp;set
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;a&nbsp;heightmap.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:author&nbsp;&quot;Simon&nbsp;Brooke&quot;}
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;mw-engine.drainage
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[mw-engine.core&nbsp;:refer&nbsp;[run-world]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[mw-engine.heightmap&nbsp;:as&nbsp;heightmap]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[mw-engine.utils&nbsp;:refer&nbsp;[get-int-or-zero&nbsp;get-least-cell&nbsp;get-neighbours
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get-neighbours-with-property-value
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map-world]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
011&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;;;;;&nbsp;mw-engine:&nbsp;the&nbsp;state&#x2F;transition&nbsp;engine&nbsp;of&nbsp;MicroWorld.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;;;;;&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2014&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
034&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
035&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
036&nbsp;&nbsp;(def&nbsp;^:dynamic&nbsp;*sealevel*&nbsp;10)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
037&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;;;&nbsp;forward&nbsp;declaration&nbsp;of&nbsp;flow,&nbsp;to&nbsp;allow&nbsp;for&nbsp;a&nbsp;wee&nbsp;bit&nbsp;of&nbsp;mutual&nbsp;recursion.
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
039&nbsp;&nbsp;(declare&nbsp;flow)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
040&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
041&nbsp;&nbsp;(defn&nbsp;rainfall
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&quot;Compute&nbsp;rainfall&nbsp;for&nbsp;a&nbsp;cell&nbsp;with&nbsp;this&nbsp;`gradient`&nbsp;west-east,&nbsp;given
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;`remaining`&nbsp;drops&nbsp;to&nbsp;distribute,&nbsp;and&nbsp;this&nbsp;overall&nbsp;map&nbsp;width.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;[gradient&nbsp;remaining&nbsp;map-width]
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;if&nbsp;there&#x27;s&nbsp;no&nbsp;rain&nbsp;left&nbsp;in&nbsp;the&nbsp;cloud,&nbsp;it&nbsp;can&#x27;t&nbsp;fall;
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(zero?&nbsp;remaining)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pos?&nbsp;gradient)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;rain,&nbsp;on&nbsp;prevailing&nbsp;westerly&nbsp;wind,&nbsp;falls&nbsp;preferentially&nbsp;on&nbsp;rising&nbsp;ground;
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(int&nbsp;(rand&nbsp;gradient))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;rain&nbsp;falls&nbsp;randomly&nbsp;across&nbsp;the&nbsp;width&nbsp;of&nbsp;the&nbsp;map...
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(zero?&nbsp;(int&nbsp;(rand&nbsp;map-width)))&nbsp;1
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
056&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
057&nbsp;&nbsp;(defn&nbsp;rain-row
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;row&nbsp;like&nbsp;this&nbsp;`row`,&nbsp;across&nbsp;which&nbsp;rainfall&nbsp;has&nbsp;been&nbsp;distributed;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;`rain-probability`&nbsp;is&nbsp;specified,&nbsp;it&nbsp;is&nbsp;the&nbsp;probable&nbsp;rainfall&nbsp;on&nbsp;a&nbsp;cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;no&nbsp;gradient.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;([row]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rain-row&nbsp;row&nbsp;1))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;([row&nbsp;rain-probability]
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rain-row&nbsp;row&nbsp;(count&nbsp;row)&nbsp;0&nbsp;(int&nbsp;(*&nbsp;(count&nbsp;row)&nbsp;rain-probability))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;([row&nbsp;map-width&nbsp;previous-altitude&nbsp;drops-in-cloud]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(empty?&nbsp;row)&nbsp;nil
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pos?&nbsp;drops-in-cloud)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[cell&nbsp;(first&nbsp;row)
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alt&nbsp;(or&nbsp;(:altitude&nbsp;cell)&nbsp;0)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rising&nbsp;(-&nbsp;alt&nbsp;previous-altitude)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fall&nbsp;(rainfall&nbsp;rising&nbsp;drops-in-cloud&nbsp;map-width)]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;cell&nbsp;:rainfall&nbsp;fall)
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rain-row&nbsp;(rest&nbsp;row)&nbsp;map-width&nbsp;alt&nbsp;(-&nbsp;drops-in-cloud&nbsp;fall))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(assoc&nbsp;%&nbsp;:rainfall&nbsp;0)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
080&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
081&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
082&nbsp;&nbsp;(defn&nbsp;rain-world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&quot;Simulate&nbsp;rainfall&nbsp;on&nbsp;this&nbsp;`world`.&nbsp;TODO:&nbsp;Doesn&#x27;t&nbsp;really&nbsp;work&nbsp;just&nbsp;now&nbsp;-&nbsp;should
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rain&nbsp;more&nbsp;on&nbsp;west-facing&nbsp;slopes,&nbsp;and&nbsp;less&nbsp;to&nbsp;the&nbsp;east&nbsp;of&nbsp;high&nbsp;ground&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;[world]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rain-row
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
089&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
090&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
091&nbsp;&nbsp;(defn&nbsp;flow-contributors
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;list&nbsp;of&nbsp;the&nbsp;cells&nbsp;in&nbsp;this&nbsp;`world`&nbsp;which&nbsp;are&nbsp;higher&nbsp;than&nbsp;this
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;`cell`&nbsp;and&nbsp;for&nbsp;which&nbsp;this&nbsp;cell&nbsp;is&nbsp;the&nbsp;lowest&nbsp;neighbour,&nbsp;or&nbsp;which&nbsp;are&nbsp;at&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;same&nbsp;altitude&nbsp;and&nbsp;have&nbsp;greater&nbsp;flow&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;[cell&nbsp;world]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;(filter&nbsp;#(map?&nbsp;%)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[n]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;cell&nbsp;(get-least-cell&nbsp;(get-neighbours&nbsp;world&nbsp;n)&nbsp;:altitude))&nbsp;n
</span><br/>
<span class="not-covered" title="0 out of 12 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(=&nbsp;(:altitude&nbsp;cell)&nbsp;(:altitude&nbsp;n))
</span><br/>
<span class="not-covered" title="0 out of 17 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;(or&nbsp;(:flow&nbsp;n)&nbsp;0)&nbsp;(or&nbsp;(:flow&nbsp;cell)&nbsp;0)))&nbsp;n))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-neighbours-with-property-value
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world&nbsp;(:x&nbsp;cell)&nbsp;(:y&nbsp;cell)&nbsp;1&nbsp;:altitude
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(:altitude&nbsp;cell)&nbsp;0)&nbsp;&gt;=))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
106&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
107&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
108&nbsp;&nbsp;(defn&nbsp;is-hollow
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&quot;Detects&nbsp;point&nbsp;hollows&nbsp;-&nbsp;that&nbsp;is,&nbsp;individual&nbsp;cells&nbsp;all&nbsp;of&nbsp;whose&nbsp;neighbours
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;are&nbsp;higher.&nbsp;Return&nbsp;true&nbsp;if&nbsp;this&nbsp;`cell`&nbsp;has&nbsp;an&nbsp;altitude&nbsp;lower&nbsp;than&nbsp;any&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;its&nbsp;neighbours&nbsp;in&nbsp;this&nbsp;`world`&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;cell]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;quicker&nbsp;to&nbsp;count&nbsp;the&nbsp;elements&nbsp;of&nbsp;the&nbsp;list&nbsp;and&nbsp;compare&nbsp;equality&nbsp;of&nbsp;numbers
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;than&nbsp;recursive&nbsp;equality&nbsp;check&nbsp;on&nbsp;members,&nbsp;I&nbsp;think.&nbsp;But&nbsp;worth&nbsp;benchmarking.
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
115&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[neighbours&nbsp;(get-neighbours&nbsp;world&nbsp;cell)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;altitude&nbsp;(get-int-or-zero&nbsp;cell&nbsp;:altitude)]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(count&nbsp;neighbours)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(count&nbsp;(get-neighbours-with-property-value
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world&nbsp;(:x&nbsp;cell)&nbsp;(:y&nbsp;cell)&nbsp;1&nbsp;:altitude&nbsp;altitude&nbsp;&gt;)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
120&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
121&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
122&nbsp;&nbsp;(defn&nbsp;flood-hollow
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
123&nbsp;&nbsp;&nbsp;&nbsp;&quot;Raise&nbsp;the&nbsp;altitude&nbsp;of&nbsp;a&nbsp;copy&nbsp;of&nbsp;this&nbsp;`cell`&nbsp;of&nbsp;this&nbsp;`world`&nbsp;to&nbsp;the&nbsp;altitude
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;of&nbsp;the&nbsp;lowest&nbsp;of&nbsp;its&nbsp;`neighbours`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;([_world&nbsp;cell&nbsp;neighbours]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
126&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[lowest&nbsp;(get-least-cell&nbsp;neighbours&nbsp;:altitude)]
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
127&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:state&nbsp;:water&nbsp;:altitude&nbsp;(:altitude&nbsp;lowest)})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
128&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;cell]
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
129&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(flood-hollow&nbsp;world&nbsp;cell&nbsp;(get-neighbours&nbsp;world&nbsp;cell))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
130&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
131&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
132&nbsp;&nbsp;(defn&nbsp;flood-hollows
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
133&nbsp;&nbsp;&nbsp;&nbsp;&quot;Flood&nbsp;all&nbsp;local&nbsp;hollows&nbsp;in&nbsp;this&nbsp;`world`.&nbsp;At&nbsp;this&nbsp;stage&nbsp;only&nbsp;floods&nbsp;single
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
134&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cell&nbsp;hollows.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
135&nbsp;&nbsp;&nbsp;&nbsp;[world]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
136&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
137&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(if&nbsp;(is-hollow&nbsp;%1&nbsp;%2)&nbsp;(flood-hollow&nbsp;%1&nbsp;%2)&nbsp;%2)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
138&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
139&nbsp;&nbsp;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
140&nbsp;&nbsp;(def&nbsp;max-altitude&nbsp;255)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
141&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
142&nbsp;&nbsp;(defn&nbsp;flow-nr
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
143&nbsp;&nbsp;&nbsp;&nbsp;&quot;Experimental&nbsp;non&nbsp;recursive&nbsp;flow&nbsp;algorithm,&nbsp;needs&nbsp;to&nbsp;be&nbsp;run&nbsp;on&nbsp;a&nbsp;world&nbsp;as
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
144&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;many&nbsp;times&nbsp;as&nbsp;there&nbsp;are&nbsp;distinct&nbsp;altitude&nbsp;values.&nbsp;This&nbsp;algorithm&nbsp;works&nbsp;only
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
145&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;applied&nbsp;sequentially&nbsp;from&nbsp;the&nbsp;highest&nbsp;altitude&nbsp;to&nbsp;the&nbsp;lowest,&nbsp;see
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
146&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`flow-world-nr`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
147&nbsp;&nbsp;&nbsp;&nbsp;[cell&nbsp;world]
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
148&nbsp;&nbsp;&nbsp;&nbsp;(when&nbsp;(=&nbsp;(-&nbsp;max-altitude&nbsp;(get-int-or-zero&nbsp;cell&nbsp;:generation))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
149&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-int-or-zero&nbsp;cell&nbsp;:altitude))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
150&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
151&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:flow&nbsp;(reduce&nbsp;+
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
152&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
153&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(+&nbsp;(get-int-or-zero&nbsp;%&nbsp;:rainfall)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
154&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-int-or-zero&nbsp;%&nbsp;:flow))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(flow-contributors&nbsp;cell&nbsp;world)))})))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
156&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
157&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
158&nbsp;&nbsp;(def&nbsp;flow
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
159&nbsp;&nbsp;&nbsp;&nbsp;&quot;Compute&nbsp;the&nbsp;total&nbsp;flow&nbsp;upstream&nbsp;of&nbsp;this&nbsp;`cell`&nbsp;in&nbsp;this&nbsp;`world`,&nbsp;and&nbsp;return&nbsp;a&nbsp;cell&nbsp;identical
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
160&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;this&nbsp;one&nbsp;but&nbsp;having&nbsp;a&nbsp;value&nbsp;of&nbsp;its&nbsp;flow&nbsp;property&nbsp;set&nbsp;from&nbsp;that&nbsp;computation.&nbsp;The&nbsp;function&nbsp;is
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
161&nbsp;&nbsp;&nbsp;&nbsp;memoised&nbsp;because&nbsp;the&nbsp;consequence&nbsp;of&nbsp;mapping&nbsp;a&nbsp;recursive&nbsp;function&nbsp;across&nbsp;an&nbsp;array&nbsp;is&nbsp;that&nbsp;many
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
162&nbsp;&nbsp;&nbsp;&nbsp;cells&nbsp;will&nbsp;be&nbsp;revisited&nbsp;-&nbsp;potentially&nbsp;many&nbsp;times.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
163&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
164&nbsp;&nbsp;&nbsp;&nbsp;Flow&nbsp;comes&nbsp;from&nbsp;a&nbsp;higher&nbsp;cell&nbsp;to&nbsp;a&nbsp;lower&nbsp;only&nbsp;if&nbsp;the&nbsp;lower&nbsp;is&nbsp;the&nbsp;lowest&nbsp;neighbour&nbsp;of&nbsp;the&nbsp;higher.&quot;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
165&nbsp;&nbsp;&nbsp;&nbsp;(memoize
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
166&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;world]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
167&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
168&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(not&nbsp;(nil?&nbsp;(:flow&nbsp;cell)))&nbsp;cell
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
169&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;=&nbsp;(or&nbsp;(:altitude&nbsp;cell)&nbsp;0)&nbsp;*sealevel*)&nbsp;cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
170&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
171&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
172&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{:flow&nbsp;(+&nbsp;(:rainfall&nbsp;cell)
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
173&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;+
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
174&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;(fn&nbsp;[neighbour]&nbsp;(:flow&nbsp;(flow&nbsp;neighbour&nbsp;world)))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
175&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(flow-contributors&nbsp;cell&nbsp;world))))})))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
176&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
177&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
178&nbsp;&nbsp;(defn&nbsp;flow-world-nr
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
179&nbsp;&nbsp;&nbsp;&nbsp;&quot;Experimental&nbsp;non-recursive&nbsp;flow-world&nbsp;algorithm&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
180&nbsp;&nbsp;&nbsp;&nbsp;[world]
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
181&nbsp;&nbsp;&nbsp;&nbsp;(run-world&nbsp;world&nbsp;nil&nbsp;(list&nbsp;flow-nr)&nbsp;max-altitude))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
182&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
183&nbsp;&nbsp;(defn&nbsp;flow-world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
184&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;world&nbsp;like&nbsp;this&nbsp;`world`,&nbsp;but&nbsp;with&nbsp;cells&nbsp;tagged&nbsp;with&nbsp;the&nbsp;amount&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
185&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;water&nbsp;flowing&nbsp;through&nbsp;them.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
186&nbsp;&nbsp;&nbsp;&nbsp;[world]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
187&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;(rain-world&nbsp;world)&nbsp;flow))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
188&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
189&nbsp;&nbsp;(defn&nbsp;explore-lake
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
190&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;sequence&nbsp;of&nbsp;cells&nbsp;starting&nbsp;with&nbsp;this&nbsp;`cell`&nbsp;in&nbsp;this&nbsp;`world`&nbsp;which
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
191&nbsp;&nbsp;&nbsp;&nbsp;form&nbsp;a&nbsp;contiguous&nbsp;lake&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
192&nbsp;&nbsp;&nbsp;&nbsp;[_world&nbsp;_cell]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
193&nbsp;&nbsp;&nbsp;&nbsp;)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
194&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
195&nbsp;&nbsp;(defn&nbsp;is-lake?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
196&nbsp;&nbsp;&nbsp;&nbsp;&quot;If&nbsp;this&nbsp;`cell`&nbsp;in&nbsp;this&nbsp;`world`&nbsp;is&nbsp;not&nbsp;part&nbsp;of&nbsp;a&nbsp;lake,&nbsp;return&nbsp;nil.&nbsp;If&nbsp;it&nbsp;is,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
197&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;a&nbsp;cell&nbsp;like&nbsp;this&nbsp;`cell`&nbsp;tagged&nbsp;as&nbsp;part&nbsp;of&nbsp;a&nbsp;lake.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
198&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;cell]
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
199&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
200&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;if&nbsp;it&#x27;s&nbsp;already&nbsp;tagged&nbsp;as&nbsp;a&nbsp;lake,&nbsp;it&#x27;s&nbsp;a&nbsp;lake
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
201&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(:lake&nbsp;cell)&nbsp;cell
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
202&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
203&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[outflow&nbsp;(apply&nbsp;min&nbsp;(map&nbsp;:altitude&nbsp;(get-neighbours&nbsp;world&nbsp;cell)))]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
204&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(when-not
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
205&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;(:altitude&nbsp;cell)&nbsp;outflow)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
206&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(assoc&nbsp;cell&nbsp;:lake&nbsp;true)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
207&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
208&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
209&nbsp;&nbsp;(defn&nbsp;find-lakes
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
210&nbsp;&nbsp;&nbsp;&nbsp;[_world]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
211&nbsp;&nbsp;&nbsp;&nbsp;)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
212&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
213&nbsp;&nbsp;(defn&nbsp;run-drainage
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
214&nbsp;&nbsp;&nbsp;&nbsp;&quot;Create&nbsp;a&nbsp;world&nbsp;from&nbsp;the&nbsp;heightmap&nbsp;`hmap`,&nbsp;rain&nbsp;on&nbsp;it,&nbsp;and&nbsp;then&nbsp;compute&nbsp;river
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
215&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flows.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
216&nbsp;&nbsp;&nbsp;&nbsp;[hmap]
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
217&nbsp;&nbsp;&nbsp;&nbsp;(flow-world&nbsp;(rain-world&nbsp;(flood-hollows&nbsp;(heightmap&#x2F;apply-heightmap&nbsp;hmap)))))
</span><br/>
</body>
</html>

View file

@ -0,0 +1,431 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> mw_engine/flow.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;mw-engine.flow
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&quot;Allow&nbsp;flows&nbsp;of&nbsp;values&nbsp;between&nbsp;cells&nbsp;in&nbsp;the&nbsp;world.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;design&nbsp;here&nbsp;is:&nbsp;a&nbsp;flow&nbsp;object&nbsp;is&nbsp;a&nbsp;map&nbsp;with&nbsp;the&nbsp;following&nbsp;properties:
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
005&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;`:source`,&nbsp;whose&nbsp;value&nbsp;is&nbsp;a&nbsp;location;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;`:destination`,&nbsp;whose&nbsp;value&nbsp;is&nbsp;a&nbsp;location;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.&nbsp;`:property`,&nbsp;whose&nbsp;value&nbsp;is&nbsp;a&nbsp;keyword;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4.&nbsp;`:quantity`,&nbsp;whose&nbsp;value&nbsp;is&nbsp;a&nbsp;positive&nbsp;real&nbsp;number.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
010&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;location&nbsp;object&nbsp;is&nbsp;a&nbsp;map&nbsp;with&nbsp;the&nbsp;following&nbsp;properties:
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
012&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.&nbsp;`:x`,&nbsp;whose&nbsp;value&nbsp;is&nbsp;a&nbsp;natural&nbsp;number&nbsp;not&nbsp;greater&nbsp;than&nbsp;the&nbsp;extent&nbsp;of&nbsp;the&nbsp;world;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.&nbsp;`:y`,&nbsp;whose&nbsp;value&nbsp;is&nbsp;a&nbsp;natural&nbsp;number&nbsp;not&nbsp;greater&nbsp;than&nbsp;the&nbsp;extent&nbsp;of&nbsp;the&nbsp;world.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
015&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;To&nbsp;execute&nbsp;a&nbsp;flow&nbsp;is&nbsp;transfer&nbsp;the&nbsp;quantity&nbsp;specified&nbsp;of&nbsp;the&nbsp;property&nbsp;specified
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;the&nbsp;cell&nbsp;at&nbsp;the&nbsp;source&nbsp;specified&nbsp;to&nbsp;the&nbsp;cell&nbsp;at&nbsp;the&nbsp;destination&nbsp;specified;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;the&nbsp;source&nbsp;doesn&#x27;t&nbsp;have&nbsp;sufficient&nbsp;of&nbsp;the&nbsp;property,&nbsp;then&nbsp;all&nbsp;it&nbsp;has&nbsp;should
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;transferred,&nbsp;but&nbsp;no&nbsp;more:&nbsp;properties&nbsp;to&nbsp;be&nbsp;flowed&nbsp;cannot&nbsp;be&nbsp;pulled&nbsp;negative.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Flowing&nbsp;values&nbsp;through&nbsp;the&nbsp;world&nbsp;is&nbsp;consequently&nbsp;a&nbsp;two&nbsp;stage&nbsp;process:&nbsp;firstly
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;there&#x27;s&nbsp;a&nbsp;planning&nbsp;stage,&nbsp;in&nbsp;which&nbsp;all&nbsp;the&nbsp;flows&nbsp;to&nbsp;be&nbsp;executed&nbsp;are&nbsp;computed
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;without&nbsp;changing&nbsp;the&nbsp;world,&nbsp;and&nbsp;then&nbsp;an&nbsp;execution&nbsp;stage,&nbsp;where&nbsp;they&#x27;re&nbsp;all&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;executed.&nbsp;This&nbsp;namespace&nbsp;deals&nbsp;with&nbsp;mainly&nbsp;with&nbsp;execution.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[mw-engine.utils&nbsp;:refer&nbsp;[get-cell&nbsp;get-num&nbsp;in-bounds?&nbsp;merge-cell]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[taoensso.timbre&nbsp;:refer&nbsp;[info&nbsp;warn]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
027&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;;;;;&nbsp;mw-engine:&nbsp;the&nbsp;state&#x2F;transition&nbsp;engine&nbsp;of&nbsp;MicroWorld.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;;;;;&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2014&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
050&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
051&nbsp;&nbsp;(defn&nbsp;coordinate?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;`true`&nbsp;if&nbsp;this&nbsp;object&nbsp;`o`&nbsp;is&nbsp;a&nbsp;valid&nbsp;coordinate&nbsp;with&nbsp;respect&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;`world`,&nbsp;else&nbsp;`false`.&nbsp;Assumes&nbsp;square&nbsp;worlds.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;[o&nbsp;world]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="covered" title="14 out of 14 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(or&nbsp;(zero?&nbsp;o)&nbsp;(pos-int?&nbsp;o))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;&nbsp;o&nbsp;(count&nbsp;world)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
</span><br/>
<span class="covered" title="20 out of 20 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Not&nbsp;a&nbsp;valid&nbsp;coordinate:&nbsp;%s;&nbsp;%s&quot;&nbsp;o&nbsp;(.getMessage&nbsp;e)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
061&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
062&nbsp;&nbsp;(defn&nbsp;location?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;`true`&nbsp;if&nbsp;this&nbsp;object&nbsp;`o`&nbsp;is&nbsp;a&nbsp;location&nbsp;as&nbsp;defined&nbsp;above&nbsp;with&nbsp;respect&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;`world`,&nbsp;else&nbsp;`false`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;[o&nbsp;world]
</span><br/>
<span class="partial" title="1 out of 2 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="partial" title="14 out of 16 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(map?&nbsp;o)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(integer?&nbsp;(:x&nbsp;o))
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(integer?&nbsp;(:y&nbsp;o))
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(in-bounds?&nbsp;world&nbsp;(:x&nbsp;o)&nbsp;(:y&nbsp;o)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
</span><br/>
<span class="not-covered" title="0 out of 20 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Not&nbsp;a&nbsp;valid&nbsp;location:&nbsp;%s;&nbsp;%s&quot;&nbsp;o&nbsp;(.getMessage&nbsp;e)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
074&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
075&nbsp;&nbsp;(defn&nbsp;flow?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;`true`&nbsp;if&nbsp;this&nbsp;object&nbsp;`o`&nbsp;is&nbsp;a&nbsp;flow&nbsp;as&nbsp;defined&nbsp;above&nbsp;with&nbsp;respect&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;`world`,&nbsp;else&nbsp;`false`.&nbsp;Assumes&nbsp;square&nbsp;worlds.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;[o&nbsp;world]
</span><br/>
<span class="partial" title="1 out of 2 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="partial" title="16 out of 20 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(map?&nbsp;o)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(location?&nbsp;(:source&nbsp;o)&nbsp;world)
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(location?&nbsp;(:destination&nbsp;o)&nbsp;world)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(keyword?&nbsp;(:property&nbsp;o))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pos?&nbsp;(:quantity&nbsp;o)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
</span><br/>
<span class="not-covered" title="0 out of 20 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Not&nbsp;a&nbsp;valid&nbsp;flow:&nbsp;%s;&nbsp;%s&quot;&nbsp;o&nbsp;(.getMessage&nbsp;e)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
088&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
089&nbsp;&nbsp;(defn&nbsp;execute
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;world&nbsp;like&nbsp;this&nbsp;`world`,&nbsp;except&nbsp;with&nbsp;the&nbsp;quantity&nbsp;of&nbsp;the&nbsp;property
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;described&nbsp;in&nbsp;this&nbsp;`flow`&nbsp;object&nbsp;transferred&nbsp;from&nbsp;the&nbsp;source&nbsp;of&nbsp;that&nbsp;flow
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;its&nbsp;destination.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;flow]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;(try
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[sx&nbsp;(-&gt;&nbsp;flow&nbsp;:source&nbsp;:x)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sy&nbsp;(-&gt;&nbsp;flow&nbsp;:source&nbsp;:y)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;source&nbsp;(get-cell&nbsp;world&nbsp;sx&nbsp;sy)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dx&nbsp;(-&gt;&nbsp;flow&nbsp;:destination&nbsp;:x)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dy&nbsp;(-&gt;&nbsp;flow&nbsp;:destination&nbsp;:y)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dest&nbsp;(get-cell&nbsp;world&nbsp;dx&nbsp;dy)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;(:property&nbsp;flow)
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q&nbsp;(min&nbsp;(:quantity&nbsp;flow)&nbsp;(get-num&nbsp;source&nbsp;p))
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s&#x27;&nbsp;(assoc&nbsp;source&nbsp;p&nbsp;(-&nbsp;(source&nbsp;p)&nbsp;q))
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d&#x27;&nbsp;(assoc&nbsp;dest&nbsp;p&nbsp;(+&nbsp;(get-num&nbsp;dest&nbsp;p)&nbsp;q))]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(=&nbsp;q&nbsp;(:quantity&nbsp;flow))
</span><br/>
<span class="covered" title="18 out of 18 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(info&nbsp;(format&nbsp;&quot;Moving&nbsp;%f&nbsp;units&nbsp;of&nbsp;%s&nbsp;from&nbsp;%d,%d&nbsp;to&nbsp;%d,%d&quot;
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(float&nbsp;q)&nbsp;(name&nbsp;p)&nbsp;sx&nbsp;sy&nbsp;dx&nbsp;dy))
</span><br/>
<span class="covered" title="18 out of 18 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Moving&nbsp;%s&nbsp;from&nbsp;%d,%d&nbsp;to&nbsp;%d,%d;&nbsp;%f&nbsp;units&nbsp;ordered&nbsp;but&nbsp;only&nbsp;%f&nbsp;available&quot;
</span><br/>
<span class="covered" title="13 out of 13 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(name&nbsp;p)&nbsp;sx&nbsp;sy&nbsp;dx&nbsp;dy&nbsp;(float&nbsp;(:quantity&nbsp;flow))&nbsp;(float&nbsp;q))))
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge-cell&nbsp;(merge-cell&nbsp;world&nbsp;s&#x27;)&nbsp;d&#x27;))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(catch&nbsp;Exception&nbsp;e
</span><br/>
<span class="not-covered" title="0 out of 20 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(warn&nbsp;(format&nbsp;&quot;Failed&nbsp;to&nbsp;execute&nbsp;flow&nbsp;%s:&nbsp;%s&quot;&nbsp;flow&nbsp;(.getMessage&nbsp;e)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;return&nbsp;the&nbsp;world&nbsp;unmodified.
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
115&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
116&nbsp;&nbsp;(defn&nbsp;execute-flows
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;world&nbsp;like&nbsp;this&nbsp;`world`,&nbsp;but&nbsp;with&nbsp;each&nbsp;of&nbsp;these&nbsp;flows&nbsp;executed.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;flows]
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;(reduce&nbsp;execute&nbsp;world&nbsp;(filter&nbsp;#(flow?&nbsp;%&nbsp;world)&nbsp;flows)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
120&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
121&nbsp;&nbsp;;;&nbsp;building&nbsp;blocks&nbsp;for&nbsp;compiled&nbsp;flow&nbsp;rules
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
122&nbsp;&nbsp;
</span><br/>
<span class="covered" title="32 out of 32 forms covered">
123&nbsp;&nbsp;(defmacro&nbsp;create-location
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;[cell]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;`(select-keys&nbsp;~cell&nbsp;[:x&nbsp;:y]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
126&nbsp;&nbsp;
</span><br/>
<span class="covered" title="56 out of 56 forms covered">
127&nbsp;&nbsp;(defmacro&nbsp;create-flow-quantity
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
128&nbsp;&nbsp;&nbsp;&nbsp;[source&nbsp;dest&nbsp;prop&nbsp;quantity]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
129&nbsp;&nbsp;&nbsp;&nbsp;`{:source&nbsp;(create-location&nbsp;~source)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
130&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:destination&nbsp;(create-location&nbsp;~dest)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
131&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:prop&nbsp;~prop
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
132&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:quantity&nbsp;~quantity})
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
133&nbsp;&nbsp;
</span><br/>
<span class="covered" title="48 out of 48 forms covered">
134&nbsp;&nbsp;(defmacro&nbsp;create-flow-fraction
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
135&nbsp;&nbsp;&nbsp;&nbsp;[source&nbsp;dest&nbsp;prop&nbsp;fraction]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
136&nbsp;&nbsp;&nbsp;&nbsp;`(create-flow-quantity&nbsp;~source&nbsp;~dest&nbsp;~prop
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
137&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*&nbsp;~fraction&nbsp;(get-num&nbsp;~source&nbsp;~prop))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
138&nbsp;&nbsp;
</span><br/>
<span class="covered" title="36 out of 36 forms covered">
139&nbsp;&nbsp;(defmacro&nbsp;create-flow-percent
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
140&nbsp;&nbsp;&nbsp;&nbsp;[source&nbsp;dest&nbsp;prop&nbsp;percent]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
141&nbsp;&nbsp;&nbsp;&nbsp;`(create-flow-fraction&nbsp;~source&nbsp;~dest&nbsp;~prop&nbsp;(&#x2F;&nbsp;~percent&nbsp;100)))
</span><br/>
</body>
</html>

View file

@ -0,0 +1,389 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> mw_engine/heightmap.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;^{:doc&nbsp;&quot;Functions&nbsp;to&nbsp;apply&nbsp;a&nbsp;heightmap&nbsp;to&nbsp;a&nbsp;world.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Heightmaps&nbsp;are&nbsp;considered&nbsp;only&nbsp;as&nbsp;greyscale&nbsp;images,&nbsp;so&nbsp;colour&nbsp;is&nbsp;redundent
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(will&nbsp;be&nbsp;ignored).&nbsp;Darker&nbsp;shades&nbsp;are&nbsp;higher.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:author&nbsp;&quot;Simon&nbsp;Brooke&quot;}
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;mw-engine.heightmap
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[mikera.image.core&nbsp;:refer&nbsp;[load-image&nbsp;filter-image]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[mikera.image.filters&nbsp;:as&nbsp;filters]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[mw-engine.utils&nbsp;:refer&nbsp;[get-int&nbsp;get-neighbours&nbsp;map-world]]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[mw-engine.world&nbsp;:refer&nbsp;[make-world]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
011&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;;;;;&nbsp;mw-engine:&nbsp;the&nbsp;state&#x2F;transition&nbsp;engine&nbsp;of&nbsp;MicroWorld.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;;;;;&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2014&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
034&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
035&nbsp;&nbsp;(defn&nbsp;tag-property
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;&nbsp;&nbsp;&quot;Set&nbsp;the&nbsp;value&nbsp;of&nbsp;this&nbsp;`property`&nbsp;of&nbsp;this&nbsp;cell&nbsp;from&nbsp;the&nbsp;corresponding&nbsp;pixel&nbsp;of&nbsp;this&nbsp;`heightmap`.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;the&nbsp;heightmap&nbsp;you&nbsp;supply&nbsp;is&nbsp;smaller&nbsp;than&nbsp;the&nbsp;world,&nbsp;this&nbsp;will&nbsp;break.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
038&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;not&nbsp;actually&nbsp;used,&nbsp;but&nbsp;present&nbsp;to&nbsp;enable&nbsp;this&nbsp;function&nbsp;to&nbsp;be
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;passed&nbsp;as&nbsp;an&nbsp;argument&nbsp;to&nbsp;`mw-engine.utils&#x2F;map-world`,&nbsp;q.v.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`cell`&nbsp;a&nbsp;cell,&nbsp;as&nbsp;discussed&nbsp;in&nbsp;world.clj,&nbsp;q.v.&nbsp;Alternatively,&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`property`&nbsp;the&nbsp;property&nbsp;(normally&nbsp;a&nbsp;keyword)&nbsp;whose&nbsp;value&nbsp;will&nbsp;be&nbsp;set&nbsp;on&nbsp;the&nbsp;cell.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`heightmap`&nbsp;an&nbsp;(ideally)&nbsp;greyscale&nbsp;image,&nbsp;whose&nbsp;x&nbsp;and&nbsp;y&nbsp;dimensions&nbsp;should
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exceed&nbsp;those&nbsp;of&nbsp;the&nbsp;world&nbsp;of&nbsp;which&nbsp;the&nbsp;`cell`&nbsp;forms&nbsp;part.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;([_&nbsp;cell&nbsp;property&nbsp;heightmap]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(tag-property&nbsp;cell&nbsp;property&nbsp;heightmap))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;([cell&nbsp;property&nbsp;heightmap]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{property
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(+&nbsp;(get-int&nbsp;cell&nbsp;property)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(-&nbsp;256
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(abs
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(mod
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(.getRGB&nbsp;heightmap
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-int&nbsp;cell&nbsp;:x)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-int&nbsp;cell&nbsp;:y))&nbsp;256))))})))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
057&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
058&nbsp;&nbsp;(defn&nbsp;tag-gradient
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&quot;Set&nbsp;the&nbsp;`gradient`&nbsp;property&nbsp;of&nbsp;this&nbsp;`cell`&nbsp;of&nbsp;this&nbsp;`world`&nbsp;to&nbsp;the&nbsp;difference&nbsp;in
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;altitude&nbsp;between&nbsp;its&nbsp;highest&nbsp;and&nbsp;lowest&nbsp;neghbours.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;cell]
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[heights&nbsp;(remove&nbsp;nil?&nbsp;(map&nbsp;:altitude&nbsp;(get-neighbours&nbsp;world&nbsp;cell)))
</span><br/>
<span class="partial" title="5 out of 6 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;highest&nbsp;(cond&nbsp;(empty?&nbsp;heights)&nbsp;0&nbsp;;;&nbsp;shouldn&#x27;t&nbsp;happen
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(apply&nbsp;max&nbsp;heights))
</span><br/>
<span class="partial" title="5 out of 6 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lowest&nbsp;(cond&nbsp;(empty?&nbsp;heights)&nbsp;0&nbsp;;;&nbsp;shouldn&#x27;t
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(apply&nbsp;min&nbsp;heights))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gradient&nbsp;(-&nbsp;highest&nbsp;lowest)]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:gradient&nbsp;gradient})))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
069&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
070&nbsp;&nbsp;(defn&nbsp;tag-gradients
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&quot;Set&nbsp;the&nbsp;`gradient`&nbsp;property&nbsp;of&nbsp;each&nbsp;cell&nbsp;in&nbsp;this&nbsp;`world`&nbsp;to&nbsp;the&nbsp;difference&nbsp;in
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;altitude&nbsp;between&nbsp;its&nbsp;highest&nbsp;and&nbsp;lowest&nbsp;neghbours.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;[world]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;tag-gradient))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
075&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
076&nbsp;&nbsp;(defn&nbsp;tag-altitude
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&quot;Set&nbsp;the&nbsp;altitude&nbsp;of&nbsp;this&nbsp;cell&nbsp;from&nbsp;the&nbsp;corresponding&nbsp;pixel&nbsp;of&nbsp;this&nbsp;heightmap.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;the&nbsp;heightmap&nbsp;you&nbsp;supply&nbsp;is&nbsp;smaller&nbsp;than&nbsp;the&nbsp;world,&nbsp;this&nbsp;will&nbsp;break.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
079&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;not&nbsp;actually&nbsp;used,&nbsp;but&nbsp;present&nbsp;to&nbsp;enable&nbsp;this&nbsp;function&nbsp;to&nbsp;be
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;passed&nbsp;as&nbsp;an&nbsp;argument&nbsp;to&nbsp;`mw-engine.utils&#x2F;map-world`,&nbsp;q.v.;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`cell`&nbsp;a&nbsp;cell,&nbsp;as&nbsp;discussed&nbsp;in&nbsp;world.clj,&nbsp;q.v.&nbsp;Alternatively,&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`heightmap`&nbsp;an&nbsp;(ideally)&nbsp;greyscale&nbsp;image,&nbsp;whose&nbsp;x&nbsp;and&nbsp;y&nbsp;dimensions&nbsp;should
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exceed&nbsp;those&nbsp;of&nbsp;the&nbsp;world&nbsp;of&nbsp;which&nbsp;the&nbsp;`cell`&nbsp;forms&nbsp;part.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;([_&nbsp;cell&nbsp;heightmap]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(tag-property&nbsp;cell&nbsp;:altitude&nbsp;heightmap))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;([cell&nbsp;heightmap]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(tag-property&nbsp;cell&nbsp;:altitude&nbsp;heightmap)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
089&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
090&nbsp;&nbsp;(defn&nbsp;apply-heightmap
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&quot;Apply&nbsp;the&nbsp;image&nbsp;file&nbsp;loaded&nbsp;from&nbsp;this&nbsp;path&nbsp;to&nbsp;this&nbsp;world,&nbsp;and&nbsp;return&nbsp;a&nbsp;world&nbsp;whose
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;altitudes&nbsp;are&nbsp;modified&nbsp;(added&nbsp;to)&nbsp;by&nbsp;the&nbsp;altitudes&nbsp;in&nbsp;the&nbsp;heightmap.&nbsp;It&nbsp;is&nbsp;assumed&nbsp;that
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;heightmap&nbsp;is&nbsp;at&nbsp;least&nbsp;as&nbsp;large&nbsp;in&nbsp;x&nbsp;and&nbsp;y&nbsp;dimensions&nbsp;as&nbsp;the&nbsp;world.&nbsp;Note&nbsp;that,&nbsp;in
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;addition&nbsp;to&nbsp;setting&nbsp;the&nbsp;`:altitude`&nbsp;of&nbsp;each&nbsp;cell,&nbsp;this&nbsp;function&nbsp;also&nbsp;sets&nbsp;the&nbsp;`:gradient`.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
095&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world,&nbsp;as&nbsp;defined&nbsp;in&nbsp;`world.clj`,&nbsp;q.v.;&nbsp;if&nbsp;world&nbsp;is&nbsp;not&nbsp;supplied,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;world&nbsp;the&nbsp;size&nbsp;of&nbsp;the&nbsp;heightmap&nbsp;will&nbsp;be&nbsp;created;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`imagepath`&nbsp;a&nbsp;file&nbsp;path&nbsp;or&nbsp;URL&nbsp;which&nbsp;indicates&nbsp;an&nbsp;(ideally&nbsp;greyscale)&nbsp;image&nbsp;file.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
099&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;imagepath]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[heightmap&nbsp;(filter-image
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(load-image&nbsp;imagepath)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(filters&#x2F;grayscale))]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;tag-altitude&nbsp;(list&nbsp;heightmap))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tag-gradient)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;([imagepath]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[heightmap&nbsp;(filter-image
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(load-image&nbsp;imagepath)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(filters&#x2F;grayscale))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world&nbsp;(make-world&nbsp;(.getWidth&nbsp;heightmap)&nbsp;(.getHeight&nbsp;heightmap))]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;tag-altitude&nbsp;(list&nbsp;heightmap))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tag-gradient))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
114&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
115&nbsp;&nbsp;(defn&nbsp;apply-valuemap
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&quot;Generalised&nbsp;from&nbsp;apply-heightmap,&nbsp;set&nbsp;an&nbsp;arbitrary&nbsp;property&nbsp;on&nbsp;each&nbsp;cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;of&nbsp;this&nbsp;`world`&nbsp;from&nbsp;the&nbsp;values&nbsp;in&nbsp;this&nbsp;(ideally&nbsp;greyscale)&nbsp;heightmap.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
118&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world,&nbsp;as&nbsp;defined&nbsp;in&nbsp;`world.clj`,&nbsp;q.v.;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`imagepath`&nbsp;a&nbsp;file&nbsp;path&nbsp;or&nbsp;URL&nbsp;which&nbsp;indicates&nbsp;an&nbsp;(ideally&nbsp;greyscale)&nbsp;image&nbsp;file;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`property`&nbsp;the&nbsp;property&nbsp;of&nbsp;each&nbsp;cell&nbsp;whose&nbsp;value&nbsp;should&nbsp;be&nbsp;added&nbsp;to&nbsp;from&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
122&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intensity&nbsp;of&nbsp;the&nbsp;corresponding&nbsp;cell&nbsp;of&nbsp;the&nbsp;image.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
123&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;imagepath&nbsp;property]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[heightmap&nbsp;(filter-image
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(load-image&nbsp;imagepath)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
126&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(filters&#x2F;grayscale))]
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
127&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;tag-property&nbsp;(list&nbsp;property&nbsp;heightmap))))
</span><br/>
</body>
</html>

View file

@ -0,0 +1,560 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> mw_engine/natural_rules.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;^{:doc&nbsp;&quot;A&nbsp;set&nbsp;of&nbsp;MicroWorld&nbsp;rules&nbsp;describing&nbsp;a&nbsp;simplified&nbsp;natural&nbsp;ecosystem.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
002&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Since&nbsp;the&nbsp;completion&nbsp;of&nbsp;the&nbsp;rule&nbsp;language&nbsp;this&nbsp;is&nbsp;more&nbsp;or&nbsp;less&nbsp;obsolete&nbsp;-
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;there&nbsp;are&nbsp;still&nbsp;a&nbsp;few&nbsp;things&nbsp;that&nbsp;you&nbsp;can&nbsp;do&nbsp;with&nbsp;rules&nbsp;written&nbsp;in&nbsp;Clojure
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;you&nbsp;can&#x27;t&nbsp;do&nbsp;in&nbsp;the&nbsp;rule&nbsp;language,&nbsp;but&nbsp;not&nbsp;many&nbsp;and&nbsp;I&nbsp;doubt&nbsp;they&#x27;re
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;important.&nbsp;&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:author&nbsp;&quot;&nbsp;Simon&nbsp;Brooke&nbsp;&quot;}
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;mw-engine.natural-rules
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[mw-engine.utils&nbsp;:refer&nbsp;[get-int&nbsp;get-neighbours&nbsp;get-neighbours-with-state&nbsp;member?]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
010&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;;;;;&nbsp;mw-engine:&nbsp;the&nbsp;state&#x2F;transition&nbsp;engine&nbsp;of&nbsp;MicroWorld.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;;;;;&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2014&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
033&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;;;&nbsp;treeline&nbsp;at&nbsp;arbitrary&nbsp;altitude.
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
035&nbsp;&nbsp;(def&nbsp;treeline&nbsp;150)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
036&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;;;&nbsp;waterline&nbsp;also&nbsp;at&nbsp;arbitrary&nbsp;altitude.
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
038&nbsp;&nbsp;(def&nbsp;waterline&nbsp;10)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
039&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;;;&nbsp;and&nbsp;finally&nbsp;snowline&nbsp;is&nbsp;also&nbsp;arbitrary.
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
041&nbsp;&nbsp;(def&nbsp;snowline&nbsp;200)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
042&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;;;&nbsp;Rare&nbsp;chance&nbsp;of&nbsp;lightning&nbsp;strikes
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
044&nbsp;&nbsp;(def&nbsp;lightning-probability&nbsp;500)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
045&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;;;&nbsp;rules&nbsp;describing&nbsp;vegetation
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
047&nbsp;&nbsp;(def&nbsp;vegetation-rules
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;(list
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;Randomly,&nbsp;birds&nbsp;plant&nbsp;tree&nbsp;seeds&nbsp;into&nbsp;grassland.
</span><br/>
<span class="partial" title="1 out of 23 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]&nbsp;(cond&nbsp;(and&nbsp;(=&nbsp;(:state&nbsp;cell)&nbsp;:grassland)(&lt;&nbsp;(rand&nbsp;10)&nbsp;1))(merge&nbsp;cell&nbsp;{:state&nbsp;:heath})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;heath&nbsp;below&nbsp;the&nbsp;treeline&nbsp;grows&nbsp;gradually&nbsp;into&nbsp;forest,&nbsp;providing&nbsp;browsing&nbsp;pressure&nbsp;is&nbsp;not&nbsp;to&nbsp;high
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(and
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(:state&nbsp;cell)&nbsp;:heath)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;browsing&nbsp;limit&nbsp;really&nbsp;ought&nbsp;to&nbsp;vary&nbsp;with&nbsp;soil&nbsp;fertility,&nbsp;but...
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;&nbsp;(+&nbsp;(get-int&nbsp;cell&nbsp;:deer)(get-int&nbsp;cell&nbsp;:sheep))&nbsp;6)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;&nbsp;(get-int&nbsp;cell&nbsp;:altitude)&nbsp;treeline))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:state&nbsp;:scrub})))
</span><br/>
<span class="partial" title="1 out of 14 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]&nbsp;(cond&nbsp;(=&nbsp;(:state&nbsp;cell)&nbsp;:scrub)&nbsp;(merge&nbsp;cell&nbsp;{:state&nbsp;:forest})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;Forest&nbsp;on&nbsp;fertile&nbsp;land&nbsp;grows&nbsp;to&nbsp;climax
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(:state&nbsp;cell)&nbsp;:forest)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;(get-int&nbsp;cell&nbsp;:fertility)&nbsp;10))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:state&nbsp;:climax})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;Climax&nbsp;forest&nbsp;occasionally&nbsp;catches&nbsp;fire&nbsp;(e.g.&nbsp;lightning&nbsp;strikes)
</span><br/>
<span class="partial" title="1 out of 23 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]&nbsp;(cond&nbsp;(and&nbsp;(=&nbsp;(:state&nbsp;cell)&nbsp;:climax)(&lt;&nbsp;(rand&nbsp;lightning-probability)&nbsp;1))&nbsp;(merge&nbsp;cell&nbsp;{:state&nbsp;:fire})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;Climax&nbsp;forest&nbsp;neighbouring&nbsp;fires&nbsp;is&nbsp;likely&nbsp;to&nbsp;catch&nbsp;fire
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;world]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 14 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(=&nbsp;(:state&nbsp;cell)&nbsp;:climax)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;&nbsp;(rand&nbsp;3)&nbsp;1)
</span><br/>
<span class="not-covered" title="0 out of 14 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(not&nbsp;(empty?&nbsp;(get-neighbours-with-state&nbsp;world&nbsp;(:x&nbsp;cell)&nbsp;(:y&nbsp;cell)&nbsp;1&nbsp;:fire))))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:state&nbsp;:fire})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;After&nbsp;fire&nbsp;we&nbsp;get&nbsp;waste
</span><br/>
<span class="partial" title="1 out of 14 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]&nbsp;(cond&nbsp;(=&nbsp;(:state&nbsp;cell)&nbsp;:fire)&nbsp;(merge&nbsp;cell&nbsp;{:state&nbsp;:waste})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;And&nbsp;after&nbsp;waste&nbsp;we&nbsp;get&nbsp;pioneer&nbsp;species;&nbsp;if&nbsp;there&#x27;s&nbsp;a&nbsp;woodland&nbsp;seed
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;source,&nbsp;it&#x27;s&nbsp;going&nbsp;to&nbsp;be&nbsp;heath,&nbsp;otherwise&nbsp;grassland.
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;world]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(=&nbsp;(:state&nbsp;cell)&nbsp;:waste)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(not
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(empty?
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(flatten
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-neighbours-with-state&nbsp;world&nbsp;(:x&nbsp;cell)&nbsp;(:y&nbsp;cell)&nbsp;1&nbsp;:scrub)
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-neighbours-with-state&nbsp;world&nbsp;(:x&nbsp;cell)&nbsp;(:y&nbsp;cell)&nbsp;1&nbsp;:forest)
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-neighbours-with-state&nbsp;world&nbsp;(:x&nbsp;cell)&nbsp;(:y&nbsp;cell)&nbsp;1&nbsp;:climax))))))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:state&nbsp;:heath})))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(=&nbsp;(:state&nbsp;cell)&nbsp;:waste)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:state&nbsp;:grassland})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;Forest&nbsp;increases&nbsp;soil&nbsp;fertility
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]
</span><br/>
<span class="not-covered" title="0 out of 8 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(member?&nbsp;(:state&nbsp;cell)&nbsp;&#x27;(:forest&nbsp;:climax))
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:fertility&nbsp;(+&nbsp;(get-int&nbsp;cell&nbsp;:fertility)&nbsp;1)})))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
098&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
099&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
100&nbsp;&nbsp;;;&nbsp;rules&nbsp;describing&nbsp;herbivore&nbsp;behaviour
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
101&nbsp;&nbsp;(def&nbsp;herbivore-rules
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;(list
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;if&nbsp;there&nbsp;are&nbsp;too&nbsp;many&nbsp;deer&nbsp;for&nbsp;the&nbsp;fertility&nbsp;of&nbsp;the&nbsp;area&nbsp;to&nbsp;sustain,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;some&nbsp;die&nbsp;or&nbsp;move&nbsp;on.
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(&gt;&nbsp;(get-int&nbsp;cell&nbsp;:deer)&nbsp;(get-int&nbsp;cell&nbsp;:fertility))
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:deer&nbsp;(get-int&nbsp;cell&nbsp;:fertility)})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;deer&nbsp;arrive&nbsp;occasionally&nbsp;at&nbsp;the&nbsp;edge&nbsp;of&nbsp;the&nbsp;map.
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;world]
</span><br/>
<span class="not-covered" title="0 out of 23 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(and&nbsp;(&lt;&nbsp;(count&nbsp;(get-neighbours&nbsp;world&nbsp;cell))&nbsp;8)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;&nbsp;(rand&nbsp;50)&nbsp;1)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;(get-int&nbsp;cell&nbsp;:fertility)&nbsp;0)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(get-int&nbsp;cell&nbsp;:deer)&nbsp;0))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:deer&nbsp;2})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
115&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;deer&nbsp;gradually&nbsp;spread&nbsp;through&nbsp;the&nbsp;world&nbsp;by&nbsp;breeding&nbsp;or&nbsp;migrating.
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;world]
</span><br/>
<span class="not-covered" title="0 out of 15 forms covered">
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[n&nbsp;(apply&nbsp;+&nbsp;(map&nbsp;#(get-int&nbsp;%&nbsp;:deer)&nbsp;(get-neighbours&nbsp;world&nbsp;cell)))]
</span><br/>
<span class="not-covered" title="0 out of 12 forms covered">
118&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(and
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;&nbsp;(get-int&nbsp;cell&nbsp;:fertility)&nbsp;0)
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(get-int&nbsp;cell&nbsp;:deer)&nbsp;0)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;=&nbsp;n&nbsp;2))
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
122&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:deer&nbsp;(int&nbsp;(&#x2F;&nbsp;n&nbsp;2))}))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
123&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;deer&nbsp;breed.
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
126&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;=&nbsp;(get-int&nbsp;cell&nbsp;:deer)&nbsp;2)
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
127&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:deer&nbsp;(int&nbsp;(*&nbsp;(:deer&nbsp;cell)&nbsp;2))})))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
128&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
129&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;rules&nbsp;describing&nbsp;predator&nbsp;behaviour
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
130&nbsp;&nbsp;&nbsp;&nbsp;(def&nbsp;predator-rules
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
131&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
132&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;wolves&nbsp;eat&nbsp;deer
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
133&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
134&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
135&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;=&nbsp;(get-int&nbsp;cell&nbsp;:wolves)&nbsp;1)
</span><br/>
<span class="not-covered" title="0 out of 16 forms covered">
136&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:deer&nbsp;(max&nbsp;0&nbsp;(-&nbsp;(get-int&nbsp;cell&nbsp;:deer)&nbsp;(get-int&nbsp;cell&nbsp;:wolves)))})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
137&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;not&nbsp;more&nbsp;than&nbsp;eight&nbsp;wolves&nbsp;in&nbsp;a&nbsp;pack,&nbsp;for&nbsp;now&nbsp;(hack&nbsp;because&nbsp;wolves&nbsp;are&nbsp;not&nbsp;dying)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
138&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;world]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
139&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(&gt;&nbsp;(get-int&nbsp;cell&nbsp;:wolves)&nbsp;8)&nbsp;(merge&nbsp;cell&nbsp;{:wolves&nbsp;8})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
140&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;if&nbsp;there&nbsp;are&nbsp;not&nbsp;enough&nbsp;deer&nbsp;to&nbsp;sustain&nbsp;the&nbsp;get-int&nbsp;of&nbsp;wolves,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
141&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;some&nbsp;wolves&nbsp;die&nbsp;or&nbsp;move&nbsp;on.&nbsp;(doesn&#x27;t&nbsp;seem&nbsp;to&nbsp;be&nbsp;working?)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
142&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
143&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(&gt;&nbsp;(get-int&nbsp;cell&nbsp;:wolves)&nbsp;(get-int&nbsp;cell&nbsp;:deer))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
144&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:wolves&nbsp;0})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
145&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;wolves&nbsp;arrive&nbsp;occasionally&nbsp;at&nbsp;the&nbsp;edge&nbsp;of&nbsp;the&nbsp;map.
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
146&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;world]
</span><br/>
<span class="not-covered" title="0 out of 23 forms covered">
147&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(and&nbsp;(&lt;&nbsp;(count&nbsp;(get-neighbours&nbsp;world&nbsp;cell))&nbsp;8)
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&lt;&nbsp;(rand&nbsp;50)&nbsp;1)
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
149&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(not&nbsp;(=&nbsp;(:state&nbsp;cell)&nbsp;:water))
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
150&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(get-int&nbsp;cell&nbsp;:wolves)&nbsp;0))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
151&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:wolves&nbsp;2})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
152&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;wolves&nbsp;gradually&nbsp;spread&nbsp;through&nbsp;the&nbsp;world&nbsp;by&nbsp;breeding&nbsp;or&nbsp;migrating.
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
153&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;world]
</span><br/>
<span class="not-covered" title="0 out of 15 forms covered">
154&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[n&nbsp;(apply&nbsp;+&nbsp;(map&nbsp;#(get-int&nbsp;%&nbsp;:wolves)&nbsp;(get-neighbours&nbsp;world&nbsp;cell)))]
</span><br/>
<span class="not-covered" title="0 out of 12 forms covered">
155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(and
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
156&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(not&nbsp;(=&nbsp;(:state&nbsp;cell)&nbsp;:water))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
157&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(get-int&nbsp;cell&nbsp;:wolves)&nbsp;0)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
158&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;=&nbsp;n&nbsp;2))
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
159&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:wolves&nbsp;2}))))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
160&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;wolves&nbsp;breed.
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
161&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
162&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
163&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(&gt;=&nbsp;(get-int&nbsp;cell&nbsp;:wolves)&nbsp;2)
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
164&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:wolves&nbsp;(int&nbsp;(*&nbsp;(:wolves&nbsp;cell)&nbsp;2))})))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
165&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
166&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
167&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;rules&nbsp;which&nbsp;initialise&nbsp;the&nbsp;world
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
168&nbsp;&nbsp;&nbsp;&nbsp;(def&nbsp;init-rules
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
169&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
170&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;below&nbsp;the&nbsp;waterline,&nbsp;we&nbsp;have&nbsp;water.
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
171&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]
</span><br/>
<span class="not-covered" title="0 out of 23 forms covered">
172&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(and&nbsp;(=&nbsp;(:state&nbsp;cell)&nbsp;:new)&nbsp;(&lt;&nbsp;(get-int&nbsp;cell&nbsp;:altitude)&nbsp;waterline))&nbsp;(merge&nbsp;cell&nbsp;{:state&nbsp;:water})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
173&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;above&nbsp;the&nbsp;snowline,&nbsp;we&nbsp;have&nbsp;snow.
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
174&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]
</span><br/>
<span class="not-covered" title="0 out of 23 forms covered">
175&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(and&nbsp;(=&nbsp;(:state&nbsp;cell)&nbsp;:new)&nbsp;(&gt;&nbsp;(get-int&nbsp;cell&nbsp;:altitude)&nbsp;snowline))&nbsp;(merge&nbsp;cell&nbsp;{:state&nbsp;:snow})))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
176&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;in&nbsp;between,&nbsp;we&nbsp;have&nbsp;a&nbsp;wasteland.
</span><br/>
<span class="partial" title="1 out of 14 forms covered">
177&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[cell&nbsp;_]&nbsp;(cond&nbsp;(=&nbsp;(:state&nbsp;cell)&nbsp;:new)&nbsp;(merge&nbsp;cell&nbsp;{:state&nbsp;:grassland})))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
178&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
179&nbsp;&nbsp;
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
180&nbsp;&nbsp;(def&nbsp;natural-rules&nbsp;(flatten
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
181&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
182&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vegetation-rules
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
183&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;herbivore-rules
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
184&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;predator-rules)))
</span><br/>
</body>
</html>

View file

@ -0,0 +1,911 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> mw_engine/utils.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;^{:doc&nbsp;&quot;&nbsp;Utility&nbsp;functions&nbsp;needed&nbsp;by&nbsp;MicroWorld&nbsp;and,&nbsp;specifically,&nbsp;in&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interpretation&nbsp;of&nbsp;MicroWorld&nbsp;rule.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:author&nbsp;&quot;Simon&nbsp;Brooke&quot;}
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;mw-engine.utils
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
005&nbsp;&nbsp;&nbsp;&nbsp;(:require
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[clojure.math.combinatorics&nbsp;:as&nbsp;combo]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
007&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;;;;;&nbsp;mw-engine:&nbsp;the&nbsp;state&#x2F;transition&nbsp;engine&nbsp;of&nbsp;MicroWorld.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
014&nbsp;&nbsp;;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;;;;;&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2014&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
030&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
031&nbsp;&nbsp;(defn&nbsp;member?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;&#x27;true&#x27;&nbsp;if&nbsp;elt&nbsp;is&nbsp;a&nbsp;member&nbsp;of&nbsp;col,&nbsp;else&nbsp;&#x27;false&#x27;.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;&nbsp;&nbsp;[elt&nbsp;col]&nbsp;
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
034&nbsp;&nbsp;&nbsp;&nbsp;(contains?&nbsp;(set&nbsp;col)&nbsp;elt))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
035&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
036&nbsp;&nbsp;(defn&nbsp;get-int-or-zero
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;the&nbsp;value&nbsp;of&nbsp;this&nbsp;`property`&nbsp;from&nbsp;this&nbsp;`map`&nbsp;if&nbsp;it&nbsp;is&nbsp;a&nbsp;integer;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;otherwise&nbsp;return&nbsp;zero.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;[map&nbsp;property]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
040&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[value&nbsp;(map&nbsp;property)]
</span><br/>
<span class="partial" title="5 out of 6 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(integer?&nbsp;value)&nbsp;value&nbsp;0)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
042&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
043&nbsp;&nbsp;(defn&nbsp;init-generation
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;cell&nbsp;like&nbsp;this&nbsp;`cell`,&nbsp;but&nbsp;having&nbsp;a&nbsp;value&nbsp;for&nbsp;:generation,&nbsp;zero&nbsp;if
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;cell&nbsp;passed&nbsp;had&nbsp;no&nbsp;integer&nbsp;value&nbsp;for&nbsp;generation,&nbsp;otherwise&nbsp;the&nbsp;value
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;taken&nbsp;from&nbsp;the&nbsp;cell&nbsp;passed.&nbsp;The&nbsp;`world`&nbsp;argument&nbsp;is&nbsp;present&nbsp;only&nbsp;for
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;consistency&nbsp;with&nbsp;the&nbsp;rule&nbsp;engine&nbsp;and&nbsp;is&nbsp;ignored.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;[_&nbsp;cell]
</span><br/>
<span class="not-covered" title="0 out of 9 forms covered">
049&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{:generation&nbsp;(get-int-or-zero&nbsp;cell&nbsp;:generation)}))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
050&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
051&nbsp;&nbsp;(defn&nbsp;in-bounds
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;x,&nbsp;y&nbsp;are&nbsp;in&nbsp;bounds&nbsp;for&nbsp;this&nbsp;world&nbsp;(i.e.,&nbsp;there&nbsp;is&nbsp;a&nbsp;cell&nbsp;at&nbsp;x,&nbsp;y)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;false.&nbsp;*DEPRECATED*:&nbsp;it&#x27;s&nbsp;a&nbsp;predicate,&nbsp;prefer&nbsp;`in-bounds?`.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
054&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world&nbsp;as&nbsp;defined&nbsp;in&nbsp;[world.clj](mw-engine.world.html);
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`x`&nbsp;a&nbsp;number&nbsp;which&nbsp;may&nbsp;or&nbsp;may&nbsp;not&nbsp;be&nbsp;a&nbsp;valid&nbsp;x&nbsp;coordinate&nbsp;within&nbsp;that&nbsp;world;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`y`&nbsp;a&nbsp;number&nbsp;which&nbsp;may&nbsp;or&nbsp;may&nbsp;not&nbsp;be&nbsp;a&nbsp;valid&nbsp;y&nbsp;coordinate&nbsp;within&nbsp;that&nbsp;world.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;{:deprecated&nbsp;&quot;1.1.7&quot;}
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;x&nbsp;y]
</span><br/>
<span class="not-covered" title="0 out of 28 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(&gt;=&nbsp;x&nbsp;0)&nbsp;(&gt;=&nbsp;y&nbsp;0)&nbsp;(&lt;&nbsp;y&nbsp;(count&nbsp;world))&nbsp;(&lt;&nbsp;x&nbsp;(count&nbsp;(first&nbsp;world)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
061&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
062&nbsp;&nbsp;(defn&nbsp;in-bounds?
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&quot;True&nbsp;if&nbsp;x,&nbsp;y&nbsp;are&nbsp;in&nbsp;bounds&nbsp;for&nbsp;this&nbsp;world&nbsp;(i.e.,&nbsp;there&nbsp;is&nbsp;a&nbsp;cell&nbsp;at&nbsp;x,&nbsp;y)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;false.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
065&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world&nbsp;as&nbsp;defined&nbsp;in&nbsp;[world.clj](mw-engine.world.html);
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`x`&nbsp;a&nbsp;number&nbsp;which&nbsp;may&nbsp;or&nbsp;may&nbsp;not&nbsp;be&nbsp;a&nbsp;valid&nbsp;x&nbsp;coordinate&nbsp;within&nbsp;that&nbsp;world;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`y`&nbsp;a&nbsp;number&nbsp;which&nbsp;may&nbsp;or&nbsp;may&nbsp;not&nbsp;be&nbsp;a&nbsp;valid&nbsp;y&nbsp;coordinate&nbsp;within&nbsp;that&nbsp;world.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;{:added&nbsp;&quot;1.1.7&quot;}
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;x&nbsp;y]
</span><br/>
<span class="covered" title="28 out of 28 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(&gt;=&nbsp;x&nbsp;0)&nbsp;(&gt;=&nbsp;y&nbsp;0)&nbsp;(&lt;&nbsp;y&nbsp;(count&nbsp;world))&nbsp;(&lt;&nbsp;x&nbsp;(count&nbsp;(first&nbsp;world)))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
072&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
073&nbsp;&nbsp;(defn&nbsp;map-world-n-n
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&quot;Wholly&nbsp;non-parallel&nbsp;map&nbsp;world&nbsp;implementation;&nbsp;see&nbsp;documentation&nbsp;for&nbsp;`map-world`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;function]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world-n-n&nbsp;world&nbsp;function&nbsp;nil))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;function&nbsp;additional-args]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(into&nbsp;[]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;(fn&nbsp;[row]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(into&nbsp;[]&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(apply&nbsp;function
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;world&nbsp;(cons&nbsp;%&nbsp;additional-args)))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row)))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
085&nbsp;&nbsp;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
086&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
087&nbsp;&nbsp;(defn&nbsp;map-world-p-p
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&quot;Wholly&nbsp;parallel&nbsp;map-world&nbsp;implementation;&nbsp;see&nbsp;documentation&nbsp;for&nbsp;`map-world`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;function]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world-p-p&nbsp;world&nbsp;function&nbsp;nil))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
091&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;function&nbsp;additional-args]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
092&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(into&nbsp;[]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
093&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pmap&nbsp;(fn&nbsp;[row]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
094&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(into&nbsp;[]&nbsp;(pmap
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
095&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(apply&nbsp;function
</span><br/>
<span class="not-covered" title="0 out of 7 forms covered">
096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;world&nbsp;(cons&nbsp;%&nbsp;additional-args)))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
097&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row)))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
098&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
099&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
100&nbsp;&nbsp;(defn&nbsp;map-world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
101&nbsp;&nbsp;&nbsp;&nbsp;&quot;Apply&nbsp;this&nbsp;`function`&nbsp;to&nbsp;each&nbsp;cell&nbsp;in&nbsp;this&nbsp;`world`&nbsp;to&nbsp;produce&nbsp;a&nbsp;new&nbsp;world.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
102&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;arguments&nbsp;to&nbsp;the&nbsp;function&nbsp;will&nbsp;be&nbsp;the&nbsp;world,&nbsp;the&nbsp;cell,&nbsp;and&nbsp;any
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
103&nbsp;&nbsp;&nbsp;&nbsp;`additional-args`&nbsp;supplied.&nbsp;Note&nbsp;that&nbsp;we&nbsp;parallel&nbsp;map&nbsp;over&nbsp;rows&nbsp;but
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
104&nbsp;&nbsp;&nbsp;&nbsp;just&nbsp;map&nbsp;over&nbsp;cells&nbsp;within&nbsp;a&nbsp;row.&nbsp;That&#x27;s&nbsp;because&nbsp;it&nbsp;isn&#x27;t&nbsp;worth&nbsp;starting
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
105&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;new&nbsp;thread&nbsp;for&nbsp;each&nbsp;cell,&nbsp;but&nbsp;there&nbsp;may&nbsp;be&nbsp;efficiency&nbsp;gains&nbsp;in
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
106&nbsp;&nbsp;&nbsp;&nbsp;running&nbsp;rows&nbsp;in&nbsp;parallel.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
107&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;function]
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world&nbsp;function&nbsp;nil))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
109&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;function&nbsp;additional-args]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(into&nbsp;[]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pmap&nbsp;(fn&nbsp;[row]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(into&nbsp;[]&nbsp;(map
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(apply&nbsp;function
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;world&nbsp;(cons&nbsp;%&nbsp;additional-args)))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
115&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row)))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
116&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
117&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
118&nbsp;&nbsp;(defn&nbsp;get-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
119&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;the&nbsp;cell&nbsp;a&nbsp;x,&nbsp;y&nbsp;in&nbsp;this&nbsp;world,&nbsp;if&nbsp;any.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
120&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
121&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world&nbsp;as&nbsp;defined&nbsp;in&nbsp;[world.clj](mw-engine.world.html);
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
122&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`x`&nbsp;a&nbsp;number&nbsp;which&nbsp;may&nbsp;or&nbsp;may&nbsp;not&nbsp;be&nbsp;a&nbsp;valid&nbsp;x&nbsp;coordinate&nbsp;within&nbsp;that&nbsp;world;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
123&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`y`&nbsp;a&nbsp;number&nbsp;which&nbsp;may&nbsp;or&nbsp;may&nbsp;not&nbsp;be&nbsp;a&nbsp;valid&nbsp;y&nbsp;coordinate&nbsp;within&nbsp;that&nbsp;world.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
124&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;x&nbsp;y]
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
125&nbsp;&nbsp;&nbsp;&nbsp;(when&nbsp;(in-bounds?&nbsp;world&nbsp;x&nbsp;y)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
126&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(nth&nbsp;(nth&nbsp;world&nbsp;y)&nbsp;x)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
127&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
128&nbsp;&nbsp;(defn&nbsp;get-int
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
129&nbsp;&nbsp;&nbsp;&nbsp;&quot;Get&nbsp;the&nbsp;value&nbsp;of&nbsp;a&nbsp;property&nbsp;expected&nbsp;to&nbsp;be&nbsp;an&nbsp;integer&nbsp;from&nbsp;a&nbsp;map;&nbsp;if&nbsp;not
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
130&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;present&nbsp;(or&nbsp;not&nbsp;an&nbsp;integer)&nbsp;return&nbsp;0.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
131&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
132&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`map`&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
133&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`key`&nbsp;a&nbsp;symbol&nbsp;or&nbsp;keyword,&nbsp;presumed&nbsp;to&nbsp;be&nbsp;a&nbsp;key&nbsp;into&nbsp;the&nbsp;`map`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
134&nbsp;&nbsp;&nbsp;&nbsp;[map&nbsp;key]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
135&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(map?&nbsp;map)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
136&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[v&nbsp;(map&nbsp;key)]
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
137&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(and&nbsp;v&nbsp;(integer?&nbsp;v))&nbsp;v
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
138&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;0))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
139&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(Exception.&nbsp;&quot;No&nbsp;map&nbsp;passed?&quot;))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
140&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
141&nbsp;&nbsp;(defn&nbsp;get-num
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
142&nbsp;&nbsp;&nbsp;&nbsp;&quot;Get&nbsp;the&nbsp;value&nbsp;of&nbsp;a&nbsp;property&nbsp;expected&nbsp;to&nbsp;be&nbsp;a&nbsp;number&nbsp;from&nbsp;a&nbsp;map;&nbsp;if&nbsp;not
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
143&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;present&nbsp;(or&nbsp;not&nbsp;a&nbsp;number)&nbsp;return&nbsp;0.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
144&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
145&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`map`&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
146&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`key`&nbsp;a&nbsp;symbol&nbsp;or&nbsp;keyword,&nbsp;presumed&nbsp;to&nbsp;be&nbsp;a&nbsp;key&nbsp;into&nbsp;the&nbsp;`map`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
147&nbsp;&nbsp;&nbsp;&nbsp;[map&nbsp;key]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
148&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(map?&nbsp;map)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
149&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[v&nbsp;(map&nbsp;key)]
</span><br/>
<span class="covered" title="12 out of 12 forms covered">
150&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(and&nbsp;v&nbsp;(number?&nbsp;v))&nbsp;v
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
151&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;0))
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
152&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(throw&nbsp;(Exception.&nbsp;&quot;No&nbsp;map&nbsp;passed?&quot;))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
153&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
154&nbsp;&nbsp;(defn&nbsp;population
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
155&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;the&nbsp;population&nbsp;of&nbsp;this&nbsp;species&nbsp;in&nbsp;this&nbsp;cell.&nbsp;Currently&nbsp;a&nbsp;synonym&nbsp;for
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
156&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`get-int`,&nbsp;but&nbsp;may&nbsp;not&nbsp;always&nbsp;be&nbsp;(depending&nbsp;whether&nbsp;species&nbsp;are&nbsp;later
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
157&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;implemented&nbsp;as&nbsp;actors)
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
158&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
159&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`cell`&nbsp;a&nbsp;map;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
160&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`species`&nbsp;a&nbsp;keyword&nbsp;representing&nbsp;a&nbsp;species&nbsp;which&nbsp;may&nbsp;populate&nbsp;that&nbsp;cell.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
161&nbsp;&nbsp;&nbsp;&nbsp;[cell&nbsp;species]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
162&nbsp;&nbsp;&nbsp;&nbsp;(get-int&nbsp;cell&nbsp;species))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
163&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
164&nbsp;&nbsp;(def&nbsp;memo-get-neighbours
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
165&nbsp;&nbsp;&nbsp;&nbsp;&quot;Memoised&nbsp;get&nbsp;neighbours&nbsp;is&nbsp;more&nbsp;efficient&nbsp;when&nbsp;running&nbsp;deeply&nbsp;recursive
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
166&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;algorithms&nbsp;on&nbsp;the&nbsp;same&nbsp;world.&nbsp;But&nbsp;it&#x27;s&nbsp;less&nbsp;efficient&nbsp;when&nbsp;running&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
167&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;engine&nbsp;in&nbsp;its&nbsp;normal&nbsp;iterative&nbsp;style,&nbsp;because&nbsp;then&nbsp;we&nbsp;will&nbsp;rarely&nbsp;call
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
168&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get&nbsp;naighbours&nbsp;on&nbsp;the&nbsp;same&nbsp;cell&nbsp;of&nbsp;the&nbsp;same&nbsp;world&nbsp;twice.&quot;
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
169&nbsp;&nbsp;&nbsp;&nbsp;(memoize
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
170&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[world&nbsp;x&nbsp;y&nbsp;depth]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
171&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(remove&nbsp;nil?
</span><br/>
<span class="covered" title="14 out of 14 forms covered">
172&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;#(get-cell&nbsp;world&nbsp;(first&nbsp;%)&nbsp;(first&nbsp;(rest&nbsp;%)))
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
173&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(remove&nbsp;#(=&nbsp;%&nbsp;(list&nbsp;x&nbsp;y))
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
174&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(combo&#x2F;cartesian-product
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
175&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(range&nbsp;(-&nbsp;x&nbsp;depth)&nbsp;(+&nbsp;x&nbsp;depth&nbsp;1))
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
176&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(range&nbsp;(-&nbsp;y&nbsp;depth)&nbsp;(+&nbsp;y&nbsp;depth&nbsp;1)))))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
177&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
178&nbsp;&nbsp;(defn&nbsp;get-neighbours
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
179&nbsp;&nbsp;&nbsp;&nbsp;&quot;Get&nbsp;the&nbsp;neighbours&nbsp;to&nbsp;distance&nbsp;depth&nbsp;of&nbsp;a&nbsp;cell&nbsp;in&nbsp;this&nbsp;world.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
180&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
181&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Several&nbsp;overloads:
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
182&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world,&nbsp;as&nbsp;described&nbsp;in&nbsp;[world.clj](mw-engine.world.html);
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
183&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`cell`&nbsp;a&nbsp;cell&nbsp;within&nbsp;that&nbsp;world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
184&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets&nbsp;immediate&nbsp;neighbours&nbsp;of&nbsp;the&nbsp;specified&nbsp;cell.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
185&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
186&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world,&nbsp;as&nbsp;described&nbsp;in[world.clj](mw-engine.world.html);
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
187&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`cell`&nbsp;a&nbsp;cell&nbsp;within&nbsp;that&nbsp;world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
188&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`depth`&nbsp;an&nbsp;integer&nbsp;representing&nbsp;the&nbsp;depth&nbsp;to&nbsp;search&nbsp;from&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
189&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`cell`
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
190&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets&nbsp;neighbours&nbsp;within&nbsp;the&nbsp;specified&nbsp;distance&nbsp;of&nbsp;the&nbsp;cell.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
191&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
192&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world,&nbsp;as&nbsp;described&nbsp;in[world.clj](mw-engine.world.html);
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
193&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`x`&nbsp;an&nbsp;integer&nbsp;representing&nbsp;an&nbsp;x&nbsp;coordinate&nbsp;in&nbsp;that&nbsp;world;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
194&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`y`&nbsp;an&nbsp;integer&nbsp;representing&nbsp;an&nbsp;y&nbsp;coordinate&nbsp;in&nbsp;that&nbsp;world;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
195&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`depth`&nbsp;an&nbsp;integer&nbsp;representing&nbsp;the&nbsp;distance&nbsp;from&nbsp;[x,y]&nbsp;that
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
196&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;should&nbsp;be&nbsp;searched
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
197&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets&nbsp;the&nbsp;neighbours&nbsp;within&nbsp;the&nbsp;specified&nbsp;distance&nbsp;of&nbsp;the&nbsp;cell&nbsp;at
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
198&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;coordinates&nbsp;[x,y]&nbsp;in&nbsp;this&nbsp;world.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
199&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;x&nbsp;y&nbsp;depth]
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
200&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(memo-get-neighbours&nbsp;world&nbsp;x&nbsp;y&nbsp;depth))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
201&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;cell&nbsp;depth]
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
202&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(memo-get-neighbours&nbsp;world&nbsp;(:x&nbsp;cell)&nbsp;(:y&nbsp;cell)&nbsp;depth))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
203&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;cell]
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
204&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(memo-get-neighbours&nbsp;world&nbsp;(:x&nbsp;cell)&nbsp;(:y&nbsp;cell)&nbsp;1)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
205&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
206&nbsp;&nbsp;(defn&nbsp;get-neighbours-with-property-value
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
207&nbsp;&nbsp;&nbsp;&nbsp;&quot;Get&nbsp;the&nbsp;neighbours&nbsp;to&nbsp;distance&nbsp;depth&nbsp;of&nbsp;the&nbsp;cell&nbsp;at&nbsp;x,&nbsp;y&nbsp;in&nbsp;this&nbsp;world&nbsp;which
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
208&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;have&nbsp;this&nbsp;value&nbsp;for&nbsp;this&nbsp;property.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
209&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
210&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world,&nbsp;as&nbsp;described&nbsp;in&nbsp;[world.clj](mw-engine.world.html);
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
211&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`cell`&nbsp;a&nbsp;cell&nbsp;within&nbsp;that&nbsp;world;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
212&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`depth`&nbsp;an&nbsp;integer&nbsp;representing&nbsp;the&nbsp;distance&nbsp;from&nbsp;[x,y]&nbsp;that
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
213&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;should&nbsp;be&nbsp;searched&nbsp;(optional);
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
214&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`property`&nbsp;a&nbsp;keyword&nbsp;representing&nbsp;a&nbsp;property&nbsp;of&nbsp;the&nbsp;neighbours;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
215&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`value`&nbsp;a&nbsp;value&nbsp;of&nbsp;that&nbsp;property&nbsp;(or,&nbsp;possibly,&nbsp;the&nbsp;name&nbsp;of&nbsp;another);
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
216&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`op`&nbsp;a&nbsp;comparator&nbsp;function&nbsp;to&nbsp;use&nbsp;in&nbsp;place&nbsp;of&nbsp;`=`&nbsp;(optional).
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
217&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
218&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;It&nbsp;gets&nbsp;messy.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
219&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;x&nbsp;y&nbsp;depth&nbsp;property&nbsp;value&nbsp;op]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
220&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(filter
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
221&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(eval
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
222&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(list&nbsp;op
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
223&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(or&nbsp;(get&nbsp;%&nbsp;property)&nbsp;(get-int&nbsp;%&nbsp;property))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
224&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value))
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
225&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-neighbours&nbsp;world&nbsp;x&nbsp;y&nbsp;depth)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
226&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;x&nbsp;y&nbsp;depth&nbsp;property&nbsp;value]
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
227&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-neighbours-with-property-value&nbsp;world&nbsp;x&nbsp;y&nbsp;depth&nbsp;property&nbsp;value&nbsp;=))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
228&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;cell&nbsp;depth&nbsp;property&nbsp;value]
</span><br/>
<span class="not-covered" title="0 out of 10 forms covered">
229&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-neighbours-with-property-value&nbsp;world&nbsp;(:x&nbsp;cell)&nbsp;(:y&nbsp;cell)&nbsp;depth
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
230&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;value))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
231&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;cell&nbsp;property&nbsp;value]
</span><br/>
<span class="not-covered" title="0 out of 5 forms covered">
232&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-neighbours-with-property-value&nbsp;world&nbsp;cell&nbsp;1
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
233&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;value)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
234&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
235&nbsp;&nbsp;(defn&nbsp;get-neighbours-with-state
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
236&nbsp;&nbsp;&nbsp;&nbsp;&quot;Get&nbsp;the&nbsp;neighbours&nbsp;to&nbsp;distance&nbsp;depth&nbsp;of&nbsp;the&nbsp;cell&nbsp;at&nbsp;x,&nbsp;y&nbsp;in&nbsp;this&nbsp;world&nbsp;which
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
237&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;have&nbsp;this&nbsp;state.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
238&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
239&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world,&nbsp;as&nbsp;described&nbsp;in&nbsp;[world.clj](mw-engine.world.html);
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
240&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`cell`&nbsp;a&nbsp;cell&nbsp;within&nbsp;that&nbsp;world;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
241&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`depth`&nbsp;an&nbsp;integer&nbsp;representing&nbsp;the&nbsp;distance&nbsp;from&nbsp;[x,y]&nbsp;that
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
242&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;should&nbsp;be&nbsp;searched;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
243&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`state`&nbsp;a&nbsp;keyword&nbsp;representing&nbsp;a&nbsp;state&nbsp;in&nbsp;the&nbsp;world.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
244&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;x&nbsp;y&nbsp;depth&nbsp;state]
</span><br/>
<span class="not-covered" title="0 out of 14 forms covered">
245&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(filter&nbsp;#(=&nbsp;(:state&nbsp;%)&nbsp;state)&nbsp;(get-neighbours&nbsp;world&nbsp;x&nbsp;y&nbsp;depth)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
246&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;cell&nbsp;depth&nbsp;state]
</span><br/>
<span class="not-covered" title="0 out of 11 forms covered">
247&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-neighbours-with-state&nbsp;world&nbsp;(:x&nbsp;cell)&nbsp;(:y&nbsp;cell)&nbsp;depth&nbsp;state))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
248&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;cell&nbsp;state]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
249&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(get-neighbours-with-state&nbsp;world&nbsp;cell&nbsp;1&nbsp;state)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
250&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
251&nbsp;&nbsp;(defn&nbsp;get-least-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
252&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;the&nbsp;cell&nbsp;from&nbsp;among&nbsp;these&nbsp;`cells`&nbsp;which&nbsp;has&nbsp;the&nbsp;lowest&nbsp;numeric&nbsp;value
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
253&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;this&nbsp;`property`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
254&nbsp;&nbsp;&nbsp;&nbsp;[cells&nbsp;property]
</span><br/>
<span class="covered" title="14 out of 14 forms covered">
255&nbsp;&nbsp;&nbsp;&nbsp;(first&nbsp;(sort-by&nbsp;property&nbsp;(filter&nbsp;#(number?&nbsp;(property&nbsp;%))&nbsp;cells))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
256&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
257&nbsp;&nbsp;(defn&nbsp;get-most-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
258&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;the&nbsp;cell&nbsp;from&nbsp;among&nbsp;these&nbsp;`cells`&nbsp;which&nbsp;has&nbsp;the&nbsp;highest&nbsp;numeric&nbsp;value
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
259&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;this&nbsp;`property`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
260&nbsp;&nbsp;&nbsp;&nbsp;[cells&nbsp;property]
</span><br/>
<span class="covered" title="14 out of 14 forms covered">
261&nbsp;&nbsp;&nbsp;&nbsp;(last&nbsp;(sort-by&nbsp;property&nbsp;(filter&nbsp;#(number?&nbsp;(property&nbsp;%))&nbsp;cells))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
262&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
263&nbsp;&nbsp;(defn-&nbsp;set-cell-property
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
264&nbsp;&nbsp;&nbsp;&nbsp;&quot;If&nbsp;this&nbsp;`cell`s&nbsp;x&nbsp;and&nbsp;y&nbsp;properties&nbsp;are&nbsp;equal&nbsp;to&nbsp;these&nbsp;`x`&nbsp;and&nbsp;`y`&nbsp;values,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
265&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;a&nbsp;cell&nbsp;like&nbsp;this&nbsp;cell&nbsp;but&nbsp;with&nbsp;the&nbsp;value&nbsp;of&nbsp;this&nbsp;`property`&nbsp;set&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
266&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;`value`.&nbsp;Otherwise,&nbsp;just&nbsp;return&nbsp;this&nbsp;`cell`.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
267&nbsp;&nbsp;&nbsp;&nbsp;[cell&nbsp;x&nbsp;y&nbsp;property&nbsp;value]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
268&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="covered" title="14 out of 14 forms covered">
269&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(=&nbsp;x&nbsp;(:x&nbsp;cell))&nbsp;(=&nbsp;y&nbsp;(:y&nbsp;cell)))
</span><br/>
<span class="covered" title="8 out of 8 forms covered">
270&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;cell&nbsp;{property&nbsp;value&nbsp;:rule&nbsp;&quot;Set&nbsp;by&nbsp;user&quot;})
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
271&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;cell))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
272&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
273&nbsp;&nbsp;(defn&nbsp;set-property
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
274&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;world&nbsp;like&nbsp;this&nbsp;`world`&nbsp;but&nbsp;with&nbsp;the&nbsp;value&nbsp;of&nbsp;exactly&nbsp;one&nbsp;`property`
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
275&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;of&nbsp;one&nbsp;`cell`&nbsp;changed&nbsp;to&nbsp;this&nbsp;`value`&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
276&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;cell&nbsp;property&nbsp;value]
</span><br/>
<span class="covered" title="11 out of 11 forms covered">
277&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(set-property&nbsp;world&nbsp;(:x&nbsp;cell)&nbsp;(:y&nbsp;cell)&nbsp;property&nbsp;value))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
278&nbsp;&nbsp;&nbsp;&nbsp;([world&nbsp;x&nbsp;y&nbsp;property&nbsp;value]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
279&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
280&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vector&nbsp;;;&nbsp;we&nbsp;want&nbsp;a&nbsp;vector&nbsp;of&nbsp;vectors,&nbsp;not&nbsp;a&nbsp;list&nbsp;of&nbsp;lists,&nbsp;for&nbsp;efficiency
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
281&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
282&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fn&nbsp;[row]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
283&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
284&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vector
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
285&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;#(set-cell-property&nbsp;%&nbsp;x&nbsp;y&nbsp;property&nbsp;value)
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
286&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row)))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
287&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
288&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
289&nbsp;&nbsp;(defn&nbsp;merge-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
290&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;world&nbsp;like&nbsp;this&nbsp;`world`,&nbsp;but&nbsp;merge&nbsp;the&nbsp;values&nbsp;from&nbsp;this&nbsp;`cell`&nbsp;with
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
291&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;those&nbsp;from&nbsp;the&nbsp;cell&nbsp;in&nbsp;the&nbsp;world&nbsp;with&nbsp;the&nbsp;same&nbsp;co-ordinates&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
292&nbsp;&nbsp;&nbsp;&nbsp;[world&nbsp;cell]
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
293&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(in-bounds?&nbsp;world&nbsp;(:x&nbsp;cell)&nbsp;(:y&nbsp;cell))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
294&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map-world&nbsp;world
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
295&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(if
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
296&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
297&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(:x&nbsp;cell)&nbsp;(:x&nbsp;%2))
</span><br/>
<span class="covered" title="6 out of 6 forms covered">
298&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;(:y&nbsp;cell)&nbsp;(:y&nbsp;%2)))
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
299&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(merge&nbsp;%2&nbsp;cell)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
300&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%2))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
301&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world))
</span><br/>
</body>
</html>

View file

@ -0,0 +1,275 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="../coverage.css"/> <title> mw_engine/world.clj </title>
</head>
<body>
<span class="covered" title="1 out of 1 forms covered">
001&nbsp;&nbsp;(ns&nbsp;^{:doc&nbsp;&quot;Functions&nbsp;to&nbsp;create&nbsp;and&nbsp;to&nbsp;print&nbsp;two&nbsp;dimensional&nbsp;cellular&nbsp;automata.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
002&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
003&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nothing&nbsp;in&nbsp;this&nbsp;namespace&nbsp;should&nbsp;determine&nbsp;what&nbsp;states&nbsp;are&nbsp;possible&nbsp;within
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
004&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;automaton,&nbsp;except&nbsp;for&nbsp;the&nbsp;initial&nbsp;state,&nbsp;:new.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
005&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
006&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;cell&nbsp;is&nbsp;a&nbsp;map&nbsp;containing&nbsp;at&nbsp;least&nbsp;values&nbsp;for&nbsp;the&nbsp;keys&nbsp;`:x`,&nbsp;`:y`,&nbsp;and&nbsp;`:state`.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
007&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;world&nbsp;is&nbsp;a&nbsp;two&nbsp;dimensional&nbsp;matrix&nbsp;(sequence&nbsp;of&nbsp;sequences)&nbsp;of&nbsp;cells,&nbsp;such
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;every&nbsp;cell&#x27;s&nbsp;`:x`&nbsp;and&nbsp;`:y`&nbsp;properties&nbsp;reflect&nbsp;its&nbsp;place&nbsp;in&nbsp;the&nbsp;matrix.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
010&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:author&nbsp;&quot;Simon&nbsp;Brooke&quot;}
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
011&nbsp;&nbsp;&nbsp;mw-engine.world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
012&nbsp;&nbsp;&nbsp;&nbsp;(:require&nbsp;[clojure.string&nbsp;:as&nbsp;string]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
013&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[mw-engine.utils&nbsp;:refer&nbsp;[population]]))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
014&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
015&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
016&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
017&nbsp;&nbsp;;;;;&nbsp;mw-engine:&nbsp;the&nbsp;state&#x2F;transition&nbsp;engine&nbsp;of&nbsp;MicroWorld.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
018&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
019&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and&#x2F;or
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
020&nbsp;&nbsp;;;;;&nbsp;modify&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
021&nbsp;&nbsp;;;;;&nbsp;as&nbsp;published&nbsp;by&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
022&nbsp;&nbsp;;;;;&nbsp;of&nbsp;the&nbsp;License,&nbsp;or&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
023&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
024&nbsp;&nbsp;;;;;&nbsp;This&nbsp;program&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
025&nbsp;&nbsp;;;;;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
026&nbsp;&nbsp;;;;;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
027&nbsp;&nbsp;;;;;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
028&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
029&nbsp;&nbsp;;;;;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;;;;;&nbsp;along&nbsp;with&nbsp;this&nbsp;program;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;;;;;&nbsp;Foundation,&nbsp;Inc.,&nbsp;51&nbsp;Franklin&nbsp;Street,&nbsp;Fifth&nbsp;Floor,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02110-1301,
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;;;;;&nbsp;USA.
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;;;;;&nbsp;Copyright&nbsp;(C)&nbsp;2014&nbsp;Simon&nbsp;Brooke
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;;;;;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
037&nbsp;&nbsp;
</span><br/>
<span class="covered" title="30 out of 30 forms covered">
038&nbsp;&nbsp;(defmacro&nbsp;make-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;&nbsp;&nbsp;&quot;Create&nbsp;a&nbsp;minimal&nbsp;default&nbsp;cell&nbsp;at&nbsp;x,&nbsp;y
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
040&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`x`&nbsp;the&nbsp;x&nbsp;coordinate&nbsp;at&nbsp;which&nbsp;this&nbsp;cell&nbsp;is&nbsp;created;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
042&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`y`&nbsp;the&nbsp;y&nbsp;coordinate&nbsp;at&nbsp;which&nbsp;this&nbsp;cell&nbsp;is&nbsp;created.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
043&nbsp;&nbsp;&nbsp;&nbsp;[x&nbsp;y]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;`{:x&nbsp;~x&nbsp;:y&nbsp;~y&nbsp;:state&nbsp;:new})
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
045&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
046&nbsp;&nbsp;(defn&nbsp;make-world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&quot;Make&nbsp;a&nbsp;world&nbsp;width&nbsp;cells&nbsp;from&nbsp;east&nbsp;to&nbsp;west,&nbsp;and&nbsp;height&nbsp;cells&nbsp;from&nbsp;north&nbsp;to
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;south.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
049&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
050&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`width`&nbsp;a&nbsp;natural&nbsp;number&nbsp;representing&nbsp;the&nbsp;width&nbsp;of&nbsp;the&nbsp;matrix&nbsp;to&nbsp;be&nbsp;created;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
051&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`height`&nbsp;a&nbsp;natural&nbsp;number&nbsp;representing&nbsp;the&nbsp;height&nbsp;of&nbsp;the&nbsp;matrix&nbsp;to&nbsp;be&nbsp;created.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;&nbsp;&nbsp;[width&nbsp;height]
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;vector
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map&nbsp;(fn&nbsp;[h]
</span><br/>
<span class="covered" title="16 out of 16 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;vector&nbsp;(map&nbsp;#(make-cell&nbsp;%&nbsp;h)&nbsp;(range&nbsp;width))))
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(range&nbsp;height))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
057&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
058&nbsp;&nbsp;(defn&nbsp;truncate-state
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;&quot;Truncate&nbsp;the&nbsp;print&nbsp;name&nbsp;of&nbsp;the&nbsp;state&nbsp;of&nbsp;this&nbsp;cell&nbsp;to&nbsp;at&nbsp;most&nbsp;limit&nbsp;characters.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;[cell&nbsp;limit]
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[s&nbsp;(:state&nbsp;cell)]
</span><br/>
<span class="not-covered" title="0 out of 13 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(&gt;&nbsp;(count&nbsp;(str&nbsp;s))&nbsp;limit)&nbsp;(subs&nbsp;s&nbsp;0&nbsp;limit)
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;s)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
064&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
065&nbsp;&nbsp;(defn&nbsp;format-cell
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&quot;Return&nbsp;a&nbsp;formatted&nbsp;string&nbsp;summarising&nbsp;the&nbsp;current&nbsp;state&nbsp;of&nbsp;this&nbsp;cell.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;[cell]
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;(format&nbsp;&quot;%10s(%2d&#x2F;%2d)&quot;
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(truncate-state&nbsp;cell&nbsp;10)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(population&nbsp;cell&nbsp;:deer)
</span><br/>
<span class="not-covered" title="0 out of 4 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(population&nbsp;cell&nbsp;:wolves)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
072&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
073&nbsp;&nbsp;(defn-&nbsp;format-world-row
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&quot;Format&nbsp;one&nbsp;row&nbsp;in&nbsp;the&nbsp;state&nbsp;of&nbsp;a&nbsp;world&nbsp;for&nbsp;printing.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;[row]
</span><br/>
<span class="not-covered" title="0 out of 6 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;(string&#x2F;join&nbsp;(map&nbsp;format-cell&nbsp;row)))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
077&nbsp;&nbsp;
</span><br/>
<span class="partial" title="1 out of 2 forms covered">
078&nbsp;&nbsp;(defn&nbsp;print-world
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&quot;Print&nbsp;the&nbsp;current&nbsp;state&nbsp;of&nbsp;this&nbsp;world,&nbsp;and&nbsp;return&nbsp;nil.
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
080&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;`world`&nbsp;a&nbsp;world&nbsp;as&nbsp;defined&nbsp;above.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;[world]
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;(println)
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;(dorun
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
085&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(map
</span><br/>
<span class="not-covered" title="0 out of 2 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#(println
</span><br/>
<span class="not-covered" title="0 out of 3 forms covered">
087&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(format-world-row&nbsp;%))
</span><br/>
<span class="not-covered" title="0 out of 1 forms covered">
088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
089&nbsp;&nbsp;&nbsp;&nbsp;nil)
</span><br/>
</body>
</html>

551
docs/codox/css/default.css Normal file
View file

@ -0,0 +1,551 @@
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 15px;
}
pre, code {
font-family: Monaco, DejaVu Sans Mono, Consolas, monospace;
font-size: 9pt;
margin: 15px 0;
}
h1 {
font-weight: normal;
font-size: 29px;
margin: 10px 0 2px 0;
padding: 0;
}
h2 {
font-weight: normal;
font-size: 25px;
}
h5.license {
margin: 9px 0 22px 0;
color: #555;
font-weight: normal;
font-size: 12px;
font-style: italic;
}
.document h1, .namespace-index h1 {
font-size: 32px;
margin-top: 12px;
}
#header, #content, .sidebar {
position: fixed;
}
#header {
top: 0;
left: 0;
right: 0;
height: 22px;
color: #f5f5f5;
padding: 5px 7px;
}
#content {
top: 32px;
right: 0;
bottom: 0;
overflow: auto;
background: #fff;
color: #333;
padding: 0 18px;
}
.sidebar {
position: fixed;
top: 32px;
bottom: 0;
overflow: auto;
}
.sidebar.primary {
background: #e2e2e2;
border-right: solid 1px #cccccc;
left: 0;
width: 250px;
}
.sidebar.secondary {
background: #f2f2f2;
border-right: solid 1px #d7d7d7;
left: 251px;
width: 200px;
}
#content.namespace-index, #content.document {
left: 251px;
}
#content.namespace-docs {
left: 452px;
}
#content.document {
padding-bottom: 10%;
}
#header {
background: #3f3f3f;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.4);
z-index: 100;
}
#header h1 {
margin: 0;
padding: 0;
font-size: 18px;
font-weight: lighter;
text-shadow: -1px -1px 0px #333;
}
#header h1 .project-version {
font-weight: normal;
}
.project-version {
padding-left: 0.15em;
}
#header a, .sidebar a {
display: block;
text-decoration: none;
}
#header a {
color: #f5f5f5;
}
.sidebar a {
color: #333;
}
#header h2 {
float: right;
font-size: 9pt;
font-weight: normal;
margin: 4px 3px;
padding: 0;
color: #bbb;
}
#header h2 a {
display: inline;
}
.sidebar h3 {
margin: 0;
padding: 10px 13px 0 13px;
font-size: 19px;
font-weight: lighter;
}
.sidebar h3 a {
color: #444;
}
.sidebar h3.no-link {
color: #636363;
}
.sidebar ul {
padding: 7px 0 6px 0;
margin: 0;
}
.sidebar ul.index-link {
padding-bottom: 4px;
}
.sidebar li {
display: block;
vertical-align: middle;
}
.sidebar li a, .sidebar li .no-link {
border-left: 3px solid transparent;
padding: 0 10px;
white-space: nowrap;
}
.sidebar li .no-link {
display: block;
color: #777;
font-style: italic;
}
.sidebar li .inner {
display: inline-block;
padding-top: 7px;
height: 24px;
}
.sidebar li a, .sidebar li .tree {
height: 31px;
}
.depth-1 .inner { padding-left: 2px; }
.depth-2 .inner { padding-left: 6px; }
.depth-3 .inner { padding-left: 20px; }
.depth-4 .inner { padding-left: 34px; }
.depth-5 .inner { padding-left: 48px; }
.depth-6 .inner { padding-left: 62px; }
.sidebar li .tree {
display: block;
float: left;
position: relative;
top: -10px;
margin: 0 4px 0 0;
padding: 0;
}
.sidebar li.depth-1 .tree {
display: none;
}
.sidebar li .tree .top, .sidebar li .tree .bottom {
display: block;
margin: 0;
padding: 0;
width: 7px;
}
.sidebar li .tree .top {
border-left: 1px solid #aaa;
border-bottom: 1px solid #aaa;
height: 19px;
}
.sidebar li .tree .bottom {
height: 22px;
}
.sidebar li.branch .tree .bottom {
border-left: 1px solid #aaa;
}
.sidebar.primary li.current a {
border-left: 3px solid #a33;
color: #a33;
}
.sidebar.secondary li.current a {
border-left: 3px solid #33a;
color: #33a;
}
.namespace-index h2 {
margin: 30px 0 0 0;
}
.namespace-index h3 {
font-size: 16px;
font-weight: bold;
margin-bottom: 0;
}
.namespace-index .topics {
padding-left: 30px;
margin: 11px 0 0 0;
}
.namespace-index .topics li {
padding: 5px 0;
}
.namespace-docs h3 {
font-size: 18px;
font-weight: bold;
}
.public h3 {
margin: 0;
float: left;
}
.usage {
clear: both;
}
.public {
margin: 0;
border-top: 1px solid #e0e0e0;
padding-top: 14px;
padding-bottom: 6px;
}
.public:last-child {
margin-bottom: 20%;
}
.members .public:last-child {
margin-bottom: 0;
}
.members {
margin: 15px 0;
}
.members h4 {
color: #555;
font-weight: normal;
font-variant: small-caps;
margin: 0 0 5px 0;
}
.members .inner {
padding-top: 5px;
padding-left: 12px;
margin-top: 2px;
margin-left: 7px;
border-left: 1px solid #bbb;
}
#content .members .inner h3 {
font-size: 12pt;
}
.members .public {
border-top: none;
margin-top: 0;
padding-top: 6px;
padding-bottom: 0;
}
.members .public:first-child {
padding-top: 0;
}
h4.type,
h4.dynamic,
h4.added,
h4.deprecated {
float: left;
margin: 3px 10px 15px 0;
font-size: 15px;
font-weight: bold;
font-variant: small-caps;
}
.public h4.type,
.public h4.dynamic,
.public h4.added,
.public h4.deprecated {
font-size: 13px;
font-weight: bold;
margin: 3px 0 0 10px;
}
.members h4.type,
.members h4.added,
.members h4.deprecated {
margin-top: 1px;
}
h4.type {
color: #717171;
}
h4.dynamic {
color: #9933aa;
}
h4.added {
color: #508820;
}
h4.deprecated {
color: #880000;
}
.namespace {
margin-bottom: 30px;
}
.namespace:last-child {
margin-bottom: 10%;
}
.index {
padding: 0;
font-size: 80%;
margin: 15px 0;
line-height: 16px;
}
.index * {
display: inline;
}
.index p {
padding-right: 3px;
}
.index li {
padding-right: 5px;
}
.index ul {
padding-left: 0;
}
.type-sig {
clear: both;
color: #088;
}
.type-sig pre {
padding-top: 10px;
margin: 0;
}
.usage code {
display: block;
color: #008;
margin: 2px 0;
}
.usage code:first-child {
padding-top: 10px;
}
p {
margin: 15px 0;
}
.public p:first-child, .public pre.plaintext {
margin-top: 12px;
}
.doc {
margin: 0 0 26px 0;
clear: both;
}
.public .doc {
margin: 0;
}
.namespace-index .doc {
margin-bottom: 20px;
}
.namespace-index .namespace .doc {
margin-bottom: 10px;
}
.markdown p, .markdown li, .markdown dt, .markdown dd, .markdown td {
line-height: 22px;
}
.markdown li {
padding: 2px 0;
}
.markdown h2 {
font-weight: normal;
font-size: 25px;
margin: 30px 0 10px 0;
}
.markdown h3 {
font-weight: normal;
font-size: 20px;
margin: 30px 0 0 0;
}
.markdown h4 {
font-size: 15px;
margin: 22px 0 -4px 0;
}
.doc, .public, .namespace .index {
max-width: 680px;
overflow-x: visible;
}
.markdown pre > code {
display: block;
padding: 10px;
}
.markdown pre > code, .src-link a {
border: 1px solid #e4e4e4;
border-radius: 2px;
}
.markdown code:not(.hljs), .src-link a {
background: #f6f6f6;
}
pre.deps {
display: inline-block;
margin: 0 10px;
border: 1px solid #e4e4e4;
border-radius: 2px;
padding: 10px;
background-color: #f6f6f6;
}
.markdown hr {
border-style: solid;
border-top: none;
color: #ccc;
}
.doc ul, .doc ol {
padding-left: 30px;
}
.doc table {
border-collapse: collapse;
margin: 0 10px;
}
.doc table td, .doc table th {
border: 1px solid #dddddd;
padding: 4px 6px;
}
.doc table th {
background: #f2f2f2;
}
.doc dl {
margin: 0 10px 20px 10px;
}
.doc dl dt {
font-weight: bold;
margin: 0;
padding: 3px 0;
border-bottom: 1px solid #ddd;
}
.doc dl dd {
padding: 5px 0;
margin: 0 0 5px 10px;
}
.doc abbr {
border-bottom: 1px dotted #333;
font-variant: none;
cursor: help;
}
.src-link {
margin-bottom: 15px;
}
.src-link a {
font-size: 70%;
padding: 1px 4px;
text-decoration: none;
color: #5555bb;
}

View file

@ -0,0 +1,97 @@
/*
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
background: #f8f8f8;
}
.hljs-comment,
.hljs-quote {
color: #998;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-subst {
color: #333;
font-weight: bold;
}
.hljs-number,
.hljs-literal,
.hljs-variable,
.hljs-template-variable,
.hljs-tag .hljs-attr {
color: #008080;
}
.hljs-string,
.hljs-doctag {
color: #d14;
}
.hljs-title,
.hljs-section,
.hljs-selector-id {
color: #900;
font-weight: bold;
}
.hljs-subst {
font-weight: normal;
}
.hljs-type,
.hljs-class .hljs-title {
color: #458;
font-weight: bold;
}
.hljs-tag,
.hljs-name,
.hljs-attribute {
color: #000080;
font-weight: normal;
}
.hljs-regexp,
.hljs-link {
color: #009926;
}
.hljs-symbol,
.hljs-bullet {
color: #990073;
}
.hljs-built_in,
.hljs-builtin-name {
color: #0086b3;
}
.hljs-meta {
color: #999;
font-weight: bold;
}
.hljs-deletion {
background: #fdd;
}
.hljs-addition {
background: #dfd;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

11
docs/codox/index.html Normal file
View file

@ -0,0 +1,11 @@
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>Mw-engine 0.2.0-SNAPSHOT</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Mw-engine</span> <span class="project-version">0.2.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 current"><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to mw-engine</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mw-engine</span></div></div></li><li class="depth-2 branch"><a href="mw-engine.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.display.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>display</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.drainage.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>drainage</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.flow.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>flow</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.heightmap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>heightmap</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.natural-rules.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>natural-rules</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="mw-engine.world.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></a></li></ul></div><div class="namespace-index" id="content"><h1><span class="project-title"><span class="project-name">Mw-engine</span> <span class="project-version">0.2.0-SNAPSHOT</span></span></h1><h5 class="license">Released under the <a href="http://www.gnu.org/licenses/gpl-2.0.html">GNU General Public License v2</a></h5><div class="doc"><p>Cellular automaton world builder.</p></div><h2>Installation</h2><p>To install, add the following dependency to your project or build file:</p><pre class="deps">[mw-engine "0.2.0-SNAPSHOT"]</pre><h2>Topics</h2><ul class="topics"><li><a href="intro.html">Introduction to mw-engine</a></li></ul><h2>Namespaces</h2><div class="namespace"><h3><a href="mw-engine.core.html">mw-engine.core</a></h3><div class="doc"><div class="markdown"><p>Functions to transform a world and run rules.</p>
</div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-engine.core.html#var-apply-rule">apply-rule</a> </li><li> <a href="mw-engine.core.html#var-run-world">run-world</a> </li><li> <a href="mw-engine.core.html#var-transform-world">transform-world</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-engine.display.html">mw-engine.display</a></h3><div class="doc"><div class="markdown"><p>Simple functions to allow a world to be visualised.</p>
</div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-engine.display.html#var-*image-base*">*image-base*</a> </li><li> <a href="mw-engine.display.html#var-format-css-class">format-css-class</a> </li><li> <a href="mw-engine.display.html#var-format-image-path">format-image-path</a> </li><li> <a href="mw-engine.display.html#var-format-mouseover">format-mouseover</a> </li><li> <a href="mw-engine.display.html#var-render-cell">render-cell</a> </li><li> <a href="mw-engine.display.html#var-render-world-row">render-world-row</a> </li><li> <a href="mw-engine.display.html#var-render-world-table">render-world-table</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-engine.drainage.html">mw-engine.drainage</a></h3><div class="doc"><div class="markdown"><p>Experimental, probably of no interest to anyone else; attempt to compute drainage on a world, assumed to have altitudes already set from a heightmap.</p>
</div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-engine.drainage.html#var-*sealevel*">*sealevel*</a> </li><li> <a href="mw-engine.drainage.html#var-explore-lake">explore-lake</a> </li><li> <a href="mw-engine.drainage.html#var-find-lakes">find-lakes</a> </li><li> <a href="mw-engine.drainage.html#var-flood-hollow">flood-hollow</a> </li><li> <a href="mw-engine.drainage.html#var-flood-hollows">flood-hollows</a> </li><li> <a href="mw-engine.drainage.html#var-flow">flow</a> </li><li> <a href="mw-engine.drainage.html#var-flow-contributors">flow-contributors</a> </li><li> <a href="mw-engine.drainage.html#var-flow-nr">flow-nr</a> </li><li> <a href="mw-engine.drainage.html#var-flow-world">flow-world</a> </li><li> <a href="mw-engine.drainage.html#var-flow-world-nr">flow-world-nr</a> </li><li> <a href="mw-engine.drainage.html#var-is-hollow">is-hollow</a> </li><li> <a href="mw-engine.drainage.html#var-is-lake.3F">is-lake?</a> </li><li> <a href="mw-engine.drainage.html#var-max-altitude">max-altitude</a> </li><li> <a href="mw-engine.drainage.html#var-rain-row">rain-row</a> </li><li> <a href="mw-engine.drainage.html#var-rain-world">rain-world</a> </li><li> <a href="mw-engine.drainage.html#var-rainfall">rainfall</a> </li><li> <a href="mw-engine.drainage.html#var-run-drainage">run-drainage</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-engine.flow.html">mw-engine.flow</a></h3><div class="doc"><div class="markdown"><p>Allow flows of values between cells in the world.</p>
</div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-engine.flow.html#var-coordinate.3F">coordinate?</a> </li><li> <a href="mw-engine.flow.html#var-create-flow-fraction">create-flow-fraction</a> </li><li> <a href="mw-engine.flow.html#var-create-flow-percent">create-flow-percent</a> </li><li> <a href="mw-engine.flow.html#var-create-flow-quantity">create-flow-quantity</a> </li><li> <a href="mw-engine.flow.html#var-create-location">create-location</a> </li><li> <a href="mw-engine.flow.html#var-execute">execute</a> </li><li> <a href="mw-engine.flow.html#var-execute-flows">execute-flows</a> </li><li> <a href="mw-engine.flow.html#var-flow.3F">flow?</a> </li><li> <a href="mw-engine.flow.html#var-location.3F">location?</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-engine.heightmap.html">mw-engine.heightmap</a></h3><div class="doc"><div class="markdown"><p>Functions to apply a heightmap to a world.</p>
</div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-engine.heightmap.html#var-apply-heightmap">apply-heightmap</a> </li><li> <a href="mw-engine.heightmap.html#var-apply-valuemap">apply-valuemap</a> </li><li> <a href="mw-engine.heightmap.html#var-tag-altitude">tag-altitude</a> </li><li> <a href="mw-engine.heightmap.html#var-tag-gradient">tag-gradient</a> </li><li> <a href="mw-engine.heightmap.html#var-tag-gradients">tag-gradients</a> </li><li> <a href="mw-engine.heightmap.html#var-tag-property">tag-property</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-engine.natural-rules.html">mw-engine.natural-rules</a></h3><div class="doc"><div class="markdown"><p>A set of MicroWorld rules describing a simplified natural ecosystem.</p>
</div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-engine.natural-rules.html#var-herbivore-rules">herbivore-rules</a> </li><li> <a href="mw-engine.natural-rules.html#var-init-rules">init-rules</a> </li><li> <a href="mw-engine.natural-rules.html#var-lightning-probability">lightning-probability</a> </li><li> <a href="mw-engine.natural-rules.html#var-natural-rules">natural-rules</a> </li><li> <a href="mw-engine.natural-rules.html#var-predator-rules">predator-rules</a> </li><li> <a href="mw-engine.natural-rules.html#var-snowline">snowline</a> </li><li> <a href="mw-engine.natural-rules.html#var-treeline">treeline</a> </li><li> <a href="mw-engine.natural-rules.html#var-vegetation-rules">vegetation-rules</a> </li><li> <a href="mw-engine.natural-rules.html#var-waterline">waterline</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-engine.utils.html">mw-engine.utils</a></h3><div class="doc"><div class="markdown"><p>Utility functions needed by MicroWorld and, specifically, in the interpretation of MicroWorld rule.</p>
</div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-engine.utils.html#var-get-cell">get-cell</a> </li><li> <a href="mw-engine.utils.html#var-get-int">get-int</a> </li><li> <a href="mw-engine.utils.html#var-get-int-or-zero">get-int-or-zero</a> </li><li> <a href="mw-engine.utils.html#var-get-least-cell">get-least-cell</a> </li><li> <a href="mw-engine.utils.html#var-get-most-cell">get-most-cell</a> </li><li> <a href="mw-engine.utils.html#var-get-neighbours">get-neighbours</a> </li><li> <a href="mw-engine.utils.html#var-get-neighbours-with-property-value">get-neighbours-with-property-value</a> </li><li> <a href="mw-engine.utils.html#var-get-neighbours-with-state">get-neighbours-with-state</a> </li><li> <a href="mw-engine.utils.html#var-get-num">get-num</a> </li><li> <a href="mw-engine.utils.html#var-in-bounds">in-bounds</a> </li><li> <a href="mw-engine.utils.html#var-in-bounds.3F">in-bounds?</a> </li><li> <a href="mw-engine.utils.html#var-init-generation">init-generation</a> </li><li> <a href="mw-engine.utils.html#var-map-world">map-world</a> </li><li> <a href="mw-engine.utils.html#var-map-world-n-n">map-world-n-n</a> </li><li> <a href="mw-engine.utils.html#var-map-world-p-p">map-world-p-p</a> </li><li> <a href="mw-engine.utils.html#var-member.3F">member?</a> </li><li> <a href="mw-engine.utils.html#var-memo-get-neighbours">memo-get-neighbours</a> </li><li> <a href="mw-engine.utils.html#var-merge-cell">merge-cell</a> </li><li> <a href="mw-engine.utils.html#var-population">population</a> </li><li> <a href="mw-engine.utils.html#var-set-property">set-property</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-engine.world.html">mw-engine.world</a></h3><div class="doc"><div class="markdown"><p>Functions to create and to print two dimensional cellular automata.</p>
</div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-engine.world.html#var-format-cell">format-cell</a> </li><li> <a href="mw-engine.world.html#var-make-cell">make-cell</a> </li><li> <a href="mw-engine.world.html#var-make-world">make-world</a> </li><li> <a href="mw-engine.world.html#var-print-world">print-world</a> </li><li> <a href="mw-engine.world.html#var-truncate-state">truncate-state</a> </li></ul></div></div></div></body></html>

5
docs/codox/intro.html Normal file
View file

@ -0,0 +1,5 @@
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>Introduction to mw-engine</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Mw-engine</span> <span class="project-version">0.2.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 current"><a href="intro.html"><div class="inner"><span>Introduction to mw-engine</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mw-engine</span></div></div></li><li class="depth-2 branch"><a href="mw-engine.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.display.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>display</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.drainage.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>drainage</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.flow.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>flow</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.heightmap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>heightmap</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.natural-rules.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>natural-rules</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="mw-engine.world.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></a></li></ul></div><div class="document" id="content"><div class="doc"><div class="markdown"><h1><a href="#introduction-to-mw-engine" id="introduction-to-mw-engine"></a>Introduction to mw-engine</h1>
<p>TODO: write <a href="http://jacobian.org/writing/great-documentation/what-to-write/">great documentation</a></p>
</div></div></div></body></html>

2
docs/codox/js/highlight.min.js vendored Normal file

File diff suppressed because one or more lines are too long

4
docs/codox/js/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,112 @@
function visibleInParent(element) {
var position = $(element).position().top
return position > -50 && position < ($(element).offsetParent().height() - 50)
}
function hasFragment(link, fragment) {
return $(link).attr("href").indexOf("#" + fragment) != -1
}
function findLinkByFragment(elements, fragment) {
return $(elements).filter(function(i, e) { return hasFragment(e, fragment)}).first()
}
function scrollToCurrentVarLink(elements) {
var elements = $(elements);
var parent = elements.offsetParent();
if (elements.length == 0) return;
var top = elements.first().position().top;
var bottom = elements.last().position().top + elements.last().height();
if (top >= 0 && bottom <= parent.height()) return;
if (top < 0) {
parent.scrollTop(parent.scrollTop() + top);
}
else if (bottom > parent.height()) {
parent.scrollTop(parent.scrollTop() + bottom - parent.height());
}
}
function setCurrentVarLink() {
$('.secondary a').parent().removeClass('current')
$('.anchor').
filter(function(index) { return visibleInParent(this) }).
each(function(index, element) {
findLinkByFragment(".secondary a", element.id).
parent().
addClass('current')
});
scrollToCurrentVarLink('.secondary .current');
}
var hasStorage = (function() { try { return localStorage.getItem } catch(e) {} }())
function scrollPositionId(element) {
var directory = window.location.href.replace(/[^\/]+\.html$/, '')
return 'scroll::' + $(element).attr('id') + '::' + directory
}
function storeScrollPosition(element) {
if (!hasStorage) return;
localStorage.setItem(scrollPositionId(element) + "::x", $(element).scrollLeft())
localStorage.setItem(scrollPositionId(element) + "::y", $(element).scrollTop())
}
function recallScrollPosition(element) {
if (!hasStorage) return;
$(element).scrollLeft(localStorage.getItem(scrollPositionId(element) + "::x"))
$(element).scrollTop(localStorage.getItem(scrollPositionId(element) + "::y"))
}
function persistScrollPosition(element) {
recallScrollPosition(element)
$(element).scroll(function() { storeScrollPosition(element) })
}
function sidebarContentWidth(element) {
var widths = $(element).find('.inner').map(function() { return $(this).innerWidth() })
return Math.max.apply(Math, widths)
}
function calculateSize(width, snap, margin, minimum) {
if (width == 0) {
return 0
}
else {
return Math.max(minimum, (Math.ceil(width / snap) * snap) + (margin * 2))
}
}
function resizeSidebars() {
var primaryWidth = sidebarContentWidth('.primary')
var secondaryWidth = 0
if ($('.secondary').length != 0) {
secondaryWidth = sidebarContentWidth('.secondary')
}
// snap to grid
primaryWidth = calculateSize(primaryWidth, 32, 13, 160)
secondaryWidth = calculateSize(secondaryWidth, 32, 13, 160)
$('.primary').css('width', primaryWidth)
$('.secondary').css('width', secondaryWidth).css('left', primaryWidth + 1)
if (secondaryWidth > 0) {
$('#content').css('left', primaryWidth + secondaryWidth + 2)
}
else {
$('#content').css('left', primaryWidth + 1)
}
}
$(window).ready(resizeSidebars)
$(window).ready(setCurrentVarLink)
$(window).ready(function() { persistScrollPosition('.primary')})
$(window).ready(function() {
$('#content').scroll(setCurrentVarLink)
$(window).resize(setCurrentVarLink)
})

View file

@ -0,0 +1,19 @@
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>mw-engine.core documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Mw-engine</span> <span class="project-version">0.2.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to mw-engine</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mw-engine</span></div></div></li><li class="depth-2 branch current"><a href="mw-engine.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.display.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>display</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.drainage.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>drainage</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.flow.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>flow</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.heightmap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>heightmap</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.natural-rules.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>natural-rules</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="mw-engine.world.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="mw-engine.core.html#var-apply-rule"><div class="inner"><span>apply-rule</span></div></a></li><li class="depth-1"><a href="mw-engine.core.html#var-run-world"><div class="inner"><span>run-world</span></div></a></li><li class="depth-1"><a href="mw-engine.core.html#var-transform-world"><div class="inner"><span>transform-world</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">mw-engine.core</h1><div class="doc"><div class="markdown"><p>Functions to transform a world and run rules.</p>
<p>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 <code>:x</code> and <code>:y</code> as the old cell. Anything else can be modified.</p>
<p>While any function of two arguments can be used as a rule, a special high level rule language is provided by the <code>mw-parser</code> package, which compiles rules expressed in a subset of English rules into suitable functions.</p>
<p>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.</p>
<p>A world is a two dimensional matrix (sequence of sequences) of cells, such that every cells <code>:x</code> and <code>:y</code> properties reflect its place in the matrix. See <code>world.clj</code>.</p>
<p>Each time the world is transformed (see <code>transform-world</code>), for each cell, rules are applied in turn until one matches. Once one rule has matched no further rules can be applied to that cell.</p>
</div></div><div class="public anchor" id="var-apply-rule"><h3>apply-rule</h3><div class="usage"><code>(apply-rule world cell rule)</code><code>(apply-rule world cell rule source)</code></div><div class="doc"><div class="markdown"><p>Apply a single <code>rule</code> to a <code>cell</code>. 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. <code>world</code> is also passed in in order to be able to access neighbours.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/core.clj#L51">view source</a></div></div><div class="public anchor" id="var-run-world"><h3>run-world</h3><div class="usage"><code>(run-world world init-rules rules generations)</code></div><div class="doc"><div class="markdown"><p>Run this world with these rules for this number of generations.</p>
<ul>
<li><code>world</code> a world as discussed above;</li>
<li><code>init-rules</code> a sequence of rules as defined above, to be run once to initialise the world;</li>
<li><code>rules</code> a sequence of rules as defined above, to be run iteratively for each generation;</li>
<li><code>generations</code> an (integer) number of generations.</li>
</ul>
<p>Return the final generation of the world.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/core.clj#L98">view source</a></div></div><div class="public anchor" id="var-transform-world"><h3>transform-world</h3><div class="usage"><code>(transform-world world rules)</code></div><div class="doc"><div class="markdown"><p>Return a world derived from this <code>world</code> by applying these <code>rules</code> to each cell.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/core.clj#L93">view source</a></div></div></div></body></html>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>mw-engine.display documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Mw-engine</span> <span class="project-version">0.2.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to mw-engine</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mw-engine</span></div></div></li><li class="depth-2 branch"><a href="mw-engine.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch current"><a href="mw-engine.display.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>display</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.drainage.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>drainage</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.flow.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>flow</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.heightmap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>heightmap</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.natural-rules.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>natural-rules</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="mw-engine.world.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="mw-engine.display.html#var-*image-base*"><div class="inner"><span>*image-base*</span></div></a></li><li class="depth-1"><a href="mw-engine.display.html#var-format-css-class"><div class="inner"><span>format-css-class</span></div></a></li><li class="depth-1"><a href="mw-engine.display.html#var-format-image-path"><div class="inner"><span>format-image-path</span></div></a></li><li class="depth-1"><a href="mw-engine.display.html#var-format-mouseover"><div class="inner"><span>format-mouseover</span></div></a></li><li class="depth-1"><a href="mw-engine.display.html#var-render-cell"><div class="inner"><span>render-cell</span></div></a></li><li class="depth-1"><a href="mw-engine.display.html#var-render-world-row"><div class="inner"><span>render-world-row</span></div></a></li><li class="depth-1"><a href="mw-engine.display.html#var-render-world-table"><div class="inner"><span>render-world-table</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">mw-engine.display</h1><div class="doc"><div class="markdown"><p>Simple functions to allow a world to be visualised.</p>
</div></div><div class="public anchor" id="var-*image-base*"><h3>*image-base*</h3><h4 class="dynamic">dynamic</h4><div class="usage"></div><div class="doc"><div class="markdown"><p>Base url (i.e., url of directory) from which to load tile images.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/display.clj#L28">view source</a></div></div><div class="public anchor" id="var-format-css-class"><h3>format-css-class</h3><div class="usage"><code>(format-css-class state)</code></div><div class="doc"><div class="markdown"><p>Format this <code>state</code>, assumed to be a keyword indicating a state in the world, into a CSS class</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/display.clj#L32">view source</a></div></div><div class="public anchor" id="var-format-image-path"><h3>format-image-path</h3><div class="usage"><code>(format-image-path state)</code></div><div class="doc"><div class="markdown"><p>Render this <code>state</code>, assumed to be a keyword indicating a state in the world, into a path which should recover the corresponding image file.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/display.clj#L38">view source</a></div></div><div class="public anchor" id="var-format-mouseover"><h3>format-mouseover</h3><div class="usage"><code>(format-mouseover cell)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/display.clj#L44">view source</a></div></div><div class="public anchor" id="var-render-cell"><h3>render-cell</h3><div class="usage"><code>(render-cell cell)</code></div><div class="doc"><div class="markdown"><p>Render this world cell as a Hiccup table cell.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/display.clj#L47">view source</a></div></div><div class="public anchor" id="var-render-world-row"><h3>render-world-row</h3><div class="usage"><code>(render-world-row row)</code></div><div class="doc"><div class="markdown"><p>Render this world <code>row</code> as a Hiccup table row.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/display.clj#L55">view source</a></div></div><div class="public anchor" id="var-render-world-table"><h3>render-world-table</h3><div class="usage"><code>(render-world-table world)</code></div><div class="doc"><div class="markdown"><p>Render this <code>world</code> as a Hiccup table.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/display.clj#L60">view source</a></div></div></div></body></html>

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,27 @@
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>mw-engine.flow documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Mw-engine</span> <span class="project-version">0.2.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to mw-engine</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mw-engine</span></div></div></li><li class="depth-2 branch"><a href="mw-engine.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.display.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>display</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.drainage.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>drainage</span></div></a></li><li class="depth-2 branch current"><a href="mw-engine.flow.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>flow</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.heightmap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>heightmap</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.natural-rules.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>natural-rules</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="mw-engine.world.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="mw-engine.flow.html#var-coordinate.3F"><div class="inner"><span>coordinate?</span></div></a></li><li class="depth-1"><a href="mw-engine.flow.html#var-create-flow-fraction"><div class="inner"><span>create-flow-fraction</span></div></a></li><li class="depth-1"><a href="mw-engine.flow.html#var-create-flow-percent"><div class="inner"><span>create-flow-percent</span></div></a></li><li class="depth-1"><a href="mw-engine.flow.html#var-create-flow-quantity"><div class="inner"><span>create-flow-quantity</span></div></a></li><li class="depth-1"><a href="mw-engine.flow.html#var-create-location"><div class="inner"><span>create-location</span></div></a></li><li class="depth-1"><a href="mw-engine.flow.html#var-execute"><div class="inner"><span>execute</span></div></a></li><li class="depth-1"><a href="mw-engine.flow.html#var-execute-flows"><div class="inner"><span>execute-flows</span></div></a></li><li class="depth-1"><a href="mw-engine.flow.html#var-flow.3F"><div class="inner"><span>flow?</span></div></a></li><li class="depth-1"><a href="mw-engine.flow.html#var-location.3F"><div class="inner"><span>location?</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">mw-engine.flow</h1><div class="doc"><div class="markdown"><p>Allow flows of values between cells in the world.</p>
<p>The design here is: a flow object is a map with the following properties:</p>
<ol>
<li><code>:source</code>, whose value is a location;</li>
<li><code>:destination</code>, whose value is a location;</li>
<li><code>:property</code>, whose value is a keyword;</li>
<li><code>:quantity</code>, whose value is a positive real number.</li>
</ol>
<p>A location object is a map with the following properties:</p>
<ol>
<li><code>:x</code>, whose value is a natural number not greater than the extent of the world;</li>
<li><code>:y</code>, whose value is a natural number not greater than the extent of the world.</li>
</ol>
<p>To execute a flow is transfer the quantity specified of the property specified from the cell at the source specified to the cell at the destination specified; if the source doesnt have sufficient of the property, then all it has should be transferred, but no more: properties to be flowed cannot be pulled negative.</p>
<p>Flowing values through the world is consequently a two stage process: firstly theres a planning stage, in which all the flows to be executed are computed without changing the world, and then an execution stage, where theyre all executed. This namespace deals with mainly with execution.</p>
</div></div><div class="public anchor" id="var-coordinate.3F"><h3>coordinate?</h3><div class="usage"><code>(coordinate? o world)</code></div><div class="doc"><div class="markdown"><p>Return <code>true</code> if this object <code>o</code> is a valid coordinate with respect to this <code>world</code>, else <code>false</code>. Assumes square worlds.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/flow.clj#L51">view source</a></div></div><div class="public anchor" id="var-create-flow-fraction"><h3>create-flow-fraction</h3><h4 class="type">macro</h4><div class="usage"><code>(create-flow-fraction source dest prop fraction)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/flow.clj#L134">view source</a></div></div><div class="public anchor" id="var-create-flow-percent"><h3>create-flow-percent</h3><h4 class="type">macro</h4><div class="usage"><code>(create-flow-percent source dest prop percent)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/flow.clj#L139">view source</a></div></div><div class="public anchor" id="var-create-flow-quantity"><h3>create-flow-quantity</h3><h4 class="type">macro</h4><div class="usage"><code>(create-flow-quantity source dest prop quantity)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/flow.clj#L127">view source</a></div></div><div class="public anchor" id="var-create-location"><h3>create-location</h3><h4 class="type">macro</h4><div class="usage"><code>(create-location cell)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/flow.clj#L123">view source</a></div></div><div class="public anchor" id="var-execute"><h3>execute</h3><div class="usage"><code>(execute world flow)</code></div><div class="doc"><div class="markdown"><p>Return a world like this <code>world</code>, except with the quantity of the property described in this <code>flow</code> object transferred from the source of that flow to its destination.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/flow.clj#L89">view source</a></div></div><div class="public anchor" id="var-execute-flows"><h3>execute-flows</h3><div class="usage"><code>(execute-flows world flows)</code></div><div class="doc"><div class="markdown"><p>Return a world like this <code>world</code>, but with each of these flows executed.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/flow.clj#L116">view source</a></div></div><div class="public anchor" id="var-flow.3F"><h3>flow?</h3><div class="usage"><code>(flow? o world)</code></div><div class="doc"><div class="markdown"><p>Return <code>true</code> if this object <code>o</code> is a flow as defined above with respect to this <code>world</code>, else <code>false</code>. Assumes square worlds.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/flow.clj#L75">view source</a></div></div><div class="public anchor" id="var-location.3F"><h3>location?</h3><div class="usage"><code>(location? o world)</code></div><div class="doc"><div class="markdown"><p>Return <code>true</code> if this object <code>o</code> is a location as defined above with respect to this <code>world</code>, else <code>false</code>.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/flow.clj#L62">view source</a></div></div></div></body></html>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>mw-engine.heightmap documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Mw-engine</span> <span class="project-version">0.2.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to mw-engine</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mw-engine</span></div></div></li><li class="depth-2 branch"><a href="mw-engine.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.display.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>display</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.drainage.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>drainage</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.flow.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>flow</span></div></a></li><li class="depth-2 branch current"><a href="mw-engine.heightmap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>heightmap</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.natural-rules.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>natural-rules</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="mw-engine.world.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="mw-engine.heightmap.html#var-apply-heightmap"><div class="inner"><span>apply-heightmap</span></div></a></li><li class="depth-1"><a href="mw-engine.heightmap.html#var-apply-valuemap"><div class="inner"><span>apply-valuemap</span></div></a></li><li class="depth-1"><a href="mw-engine.heightmap.html#var-tag-altitude"><div class="inner"><span>tag-altitude</span></div></a></li><li class="depth-1"><a href="mw-engine.heightmap.html#var-tag-gradient"><div class="inner"><span>tag-gradient</span></div></a></li><li class="depth-1"><a href="mw-engine.heightmap.html#var-tag-gradients"><div class="inner"><span>tag-gradients</span></div></a></li><li class="depth-1"><a href="mw-engine.heightmap.html#var-tag-property"><div class="inner"><span>tag-property</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">mw-engine.heightmap</h1><div class="doc"><div class="markdown"><p>Functions to apply a heightmap to a world.</p>
<p>Heightmaps are considered only as greyscale images, so colour is redundent (will be ignored). Darker shades are higher.</p>
</div></div><div class="public anchor" id="var-apply-heightmap"><h3>apply-heightmap</h3><div class="usage"><code>(apply-heightmap world imagepath)</code><code>(apply-heightmap imagepath)</code></div><div class="doc"><div class="markdown"><p>Apply the image file loaded from this path to this world, and return a world whose altitudes are modified (added to) by the altitudes in the heightmap. It is assumed that the heightmap is at least as large in x and y dimensions as the world. Note that, in addition to setting the <code>:altitude</code> of each cell, this function also sets the <code>:gradient</code>.</p>
<ul>
<li><code>world</code> a world, as defined in <code>world.clj</code>, q.v.; if world is not supplied, a world the size of the heightmap will be created;</li>
<li><code>imagepath</code> a file path or URL which indicates an (ideally greyscale) image file.</li>
</ul>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/heightmap.clj#L90">view source</a></div></div><div class="public anchor" id="var-apply-valuemap"><h3>apply-valuemap</h3><div class="usage"><code>(apply-valuemap world imagepath property)</code></div><div class="doc"><div class="markdown"><p>Generalised from apply-heightmap, set an arbitrary property on each cell of this <code>world</code> from the values in this (ideally greyscale) heightmap.</p>
<ul>
<li><code>world</code> a world, as defined in <code>world.clj</code>, q.v.;</li>
<li><code>imagepath</code> a file path or URL which indicates an (ideally greyscale) image file;</li>
<li><code>property</code> the property of each cell whose value should be added to from the intensity of the corresponding cell of the image.</li>
</ul>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/heightmap.clj#L115">view source</a></div></div><div class="public anchor" id="var-tag-altitude"><h3>tag-altitude</h3><div class="usage"><code>(tag-altitude _ cell heightmap)</code><code>(tag-altitude cell heightmap)</code></div><div class="doc"><div class="markdown"><p>Set the altitude of this cell from the corresponding pixel of this heightmap. If the heightmap you supply is smaller than the world, this will break.</p>
<ul>
<li><code>world</code> not actually used, but present to enable this function to be passed as an argument to <code>mw-engine.utils/map-world</code>, q.v.;</li>
<li><code>cell</code> a cell, as discussed in world.clj, q.v. Alternatively, a map;</li>
<li><code>heightmap</code> an (ideally) greyscale image, whose x and y dimensions should exceed those of the world of which the <code>cell</code> forms part.</li>
</ul>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/heightmap.clj#L76">view source</a></div></div><div class="public anchor" id="var-tag-gradient"><h3>tag-gradient</h3><div class="usage"><code>(tag-gradient world cell)</code></div><div class="doc"><div class="markdown"><p>Set the <code>gradient</code> property of this <code>cell</code> of this <code>world</code> to the difference in altitude between its highest and lowest neghbours.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/heightmap.clj#L58">view source</a></div></div><div class="public anchor" id="var-tag-gradients"><h3>tag-gradients</h3><div class="usage"><code>(tag-gradients world)</code></div><div class="doc"><div class="markdown"><p>Set the <code>gradient</code> property of each cell in this <code>world</code> to the difference in altitude between its highest and lowest neghbours.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/heightmap.clj#L70">view source</a></div></div><div class="public anchor" id="var-tag-property"><h3>tag-property</h3><div class="usage"><code>(tag-property _ cell property heightmap)</code><code>(tag-property cell property heightmap)</code></div><div class="doc"><div class="markdown"><p>Set the value of this <code>property</code> of this cell from the corresponding pixel of this <code>heightmap</code>. If the heightmap you supply is smaller than the world, this will break.</p>
<ul>
<li><code>world</code> not actually used, but present to enable this function to be passed as an argument to <code>mw-engine.utils/map-world</code>, q.v.</li>
<li><code>cell</code> a cell, as discussed in world.clj, q.v. Alternatively, a map;</li>
<li><code>property</code> the property (normally a keyword) whose value will be set on the cell.</li>
<li><code>heightmap</code> an (ideally) greyscale image, whose x and y dimensions should exceed those of the world of which the <code>cell</code> forms part.</li>
</ul>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/heightmap.clj#L35">view source</a></div></div></div></body></html>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>mw-engine.natural-rules documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Mw-engine</span> <span class="project-version">0.2.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to mw-engine</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mw-engine</span></div></div></li><li class="depth-2 branch"><a href="mw-engine.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.display.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>display</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.drainage.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>drainage</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.flow.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>flow</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.heightmap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>heightmap</span></div></a></li><li class="depth-2 branch current"><a href="mw-engine.natural-rules.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>natural-rules</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2"><a href="mw-engine.world.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="mw-engine.natural-rules.html#var-herbivore-rules"><div class="inner"><span>herbivore-rules</span></div></a></li><li class="depth-1"><a href="mw-engine.natural-rules.html#var-init-rules"><div class="inner"><span>init-rules</span></div></a></li><li class="depth-1"><a href="mw-engine.natural-rules.html#var-lightning-probability"><div class="inner"><span>lightning-probability</span></div></a></li><li class="depth-1"><a href="mw-engine.natural-rules.html#var-natural-rules"><div class="inner"><span>natural-rules</span></div></a></li><li class="depth-1"><a href="mw-engine.natural-rules.html#var-predator-rules"><div class="inner"><span>predator-rules</span></div></a></li><li class="depth-1"><a href="mw-engine.natural-rules.html#var-snowline"><div class="inner"><span>snowline</span></div></a></li><li class="depth-1"><a href="mw-engine.natural-rules.html#var-treeline"><div class="inner"><span>treeline</span></div></a></li><li class="depth-1"><a href="mw-engine.natural-rules.html#var-vegetation-rules"><div class="inner"><span>vegetation-rules</span></div></a></li><li class="depth-1"><a href="mw-engine.natural-rules.html#var-waterline"><div class="inner"><span>waterline</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">mw-engine.natural-rules</h1><div class="doc"><div class="markdown"><p>A set of MicroWorld rules describing a simplified natural ecosystem.</p>
<p>Since the completion of the rule language this is more or less obsolete - there are still a few things that you can do with rules written in Clojure that you cant do in the rule language, but not many and I doubt theyre important.</p>
</div></div><div class="public anchor" id="var-herbivore-rules"><h3>herbivore-rules</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/natural_rules.clj#L101">view source</a></div></div><div class="public anchor" id="var-init-rules"><h3>init-rules</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/natural_rules.clj#L168">view source</a></div></div><div class="public anchor" id="var-lightning-probability"><h3>lightning-probability</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/natural_rules.clj#L44">view source</a></div></div><div class="public anchor" id="var-natural-rules"><h3>natural-rules</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/natural_rules.clj#L180">view source</a></div></div><div class="public anchor" id="var-predator-rules"><h3>predator-rules</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/natural_rules.clj#L130">view source</a></div></div><div class="public anchor" id="var-snowline"><h3>snowline</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/natural_rules.clj#L41">view source</a></div></div><div class="public anchor" id="var-treeline"><h3>treeline</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/natural_rules.clj#L35">view source</a></div></div><div class="public anchor" id="var-vegetation-rules"><h3>vegetation-rules</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/natural_rules.clj#L47">view source</a></div></div><div class="public anchor" id="var-waterline"><h3>waterline</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/natural_rules.clj#L38">view source</a></div></div></div></body></html>

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,23 @@
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>mw-engine.world documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Mw-engine</span> <span class="project-version">0.2.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to mw-engine</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mw-engine</span></div></div></li><li class="depth-2 branch"><a href="mw-engine.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.display.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>display</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.drainage.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>drainage</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.flow.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>flow</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.heightmap.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>heightmap</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.natural-rules.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>natural-rules</span></div></a></li><li class="depth-2 branch"><a href="mw-engine.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li><li class="depth-2 current"><a href="mw-engine.world.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>world</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="mw-engine.world.html#var-format-cell"><div class="inner"><span>format-cell</span></div></a></li><li class="depth-1"><a href="mw-engine.world.html#var-make-cell"><div class="inner"><span>make-cell</span></div></a></li><li class="depth-1"><a href="mw-engine.world.html#var-make-world"><div class="inner"><span>make-world</span></div></a></li><li class="depth-1"><a href="mw-engine.world.html#var-print-world"><div class="inner"><span>print-world</span></div></a></li><li class="depth-1"><a href="mw-engine.world.html#var-truncate-state"><div class="inner"><span>truncate-state</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">mw-engine.world</h1><div class="doc"><div class="markdown"><p>Functions to create and to print two dimensional cellular automata.</p>
<p>Nothing in this namespace should determine what states are possible within the automaton, except for the initial state, :new.</p>
<p>A cell is a map containing at least values for the keys <code>:x</code>, <code>:y</code>, and <code>:state</code>.</p>
<p>A world is a two dimensional matrix (sequence of sequences) of cells, such that every cells <code>:x</code> and <code>:y</code> properties reflect its place in the matrix.</p>
</div></div><div class="public anchor" id="var-format-cell"><h3>format-cell</h3><div class="usage"><code>(format-cell cell)</code></div><div class="doc"><div class="markdown"><p>Return a formatted string summarising the current state of this cell.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/world.clj#L65">view source</a></div></div><div class="public anchor" id="var-make-cell"><h3>make-cell</h3><h4 class="type">macro</h4><div class="usage"><code>(make-cell x y)</code></div><div class="doc"><div class="markdown"><p>Create a minimal default cell at x, y</p>
<ul>
<li><code>x</code> the x coordinate at which this cell is created;</li>
<li><code>y</code> the y coordinate at which this cell is created.</li>
</ul>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/world.clj#L38">view source</a></div></div><div class="public anchor" id="var-make-world"><h3>make-world</h3><div class="usage"><code>(make-world width height)</code></div><div class="doc"><div class="markdown"><p>Make a world width cells from east to west, and height cells from north to south.</p>
<ul>
<li><code>width</code> a natural number representing the width of the matrix to be created;</li>
<li><code>height</code> a natural number representing the height of the matrix to be created.</li>
</ul>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/world.clj#L46">view source</a></div></div><div class="public anchor" id="var-print-world"><h3>print-world</h3><div class="usage"><code>(print-world world)</code></div><div class="doc"><div class="markdown"><p>Print the current state of this world, and return nil.</p>
<ul>
<li><code>world</code> a world as defined above.</li>
</ul>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/world.clj#L78">view source</a></div></div><div class="public anchor" id="var-truncate-state"><h3>truncate-state</h3><div class="usage"><code>(truncate-state cell limit)</code></div><div class="doc"><div class="markdown"><p>Truncate the print name of the state of this cell to at most limit characters.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-engine/blob/master/src/cljc/mw_engine/world.clj#L58">view source</a></div></div></div></body></html>

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,9 @@
(defproject mw-engine "0.2.0-SNAPSHOT" (defproject mw-engine "0.2.0-SNAPSHOT"
:cloverage {:output "docs/cloverage"}
:codox {:metadata {:doc "**TODO**: write docs"
:doc/format :markdown}
:output-path "docs/codox"
:source-uri "https://github.com/simon-brooke/mw-engine/blob/master/{filepath}#L{line}"}
:dependencies [[org.clojure/clojure "1.11.1"] :dependencies [[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"]
@ -15,9 +20,10 @@
:min-lein-version "2.0.0" :min-lein-version "2.0.0"
:plugins [[lein-cljsbuild "1.1.7"] :plugins [[lein-cljsbuild "1.1.7"]
[lein-cloverage "1.2.2"]
[lein-codox "0.10.8"]
[lein-kibit "0.1.2"] [lein-kibit "0.1.2"]
[lein-marginalia "0.7.1"]] [lein-marginalia "0.7.1"]]
:resource-paths ["resources" "target/cljsbuild"] :resource-paths ["resources" "target/cljsbuild"]
:source-paths ["src/clj" "src/cljs" "src/cljc"] :source-paths ["src/clj" "src/cljs" "src/cljc"]
:url "http://www.journeyman.cc/microworld/" :url "http://www.journeyman.cc/microworld/")
)

View file

@ -17,7 +17,7 @@
that every cell's `:x` and `:y` properties reflect its place in the matrix. that every cell's `:x` and `:y` properties reflect its place in the matrix.
See `world.clj`. See `world.clj`.
Each time the world is transformed (see `transform-world`, for each cell, 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 rules are applied in turn until one matches. Once one rule has matched no
further rules can be applied to that cell." further rules can be applied to that cell."
:author "Simon Brooke"} :author "Simon Brooke"}

View file

@ -122,7 +122,7 @@
(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]
@ -189,7 +189,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?
@ -207,7 +207,7 @@
(defn find-lakes (defn find-lakes
[world] [_world]
) )
(defn run-drainage (defn run-drainage

View file

@ -2,14 +2,16 @@
"Allow flows of values between cells in the world. "Allow flows of values between cells in the world.
The design here is: a flow object is a map with the following properties: The design here is: a flow object is a map with the following properties:
1. :source, whose value is a location;
2. :destination, whose value is a location; 1. `:source`, whose value is a location;
3. :property, whose value is a keyword; 2. `:destination`, whose value is a location;
4. :quantity, whose value is a positive real number. 3. `:property`, whose value is a keyword;
4. `:quantity`, whose value is a positive real number.
A location object is a map with the following properties: A location object is a map with the following properties:
1. :x, whose value is a natural number not greater than the extent of the world;
2. :y, whose value is a natural number not greater than the extent of the world. 1. `:x`, whose value is a natural number not greater than the extent of the world;
2. `:y`, whose value is a natural number not greater than the extent of the world.
To execute a flow is transfer the quantity specified of the property specified To execute a flow is transfer the quantity specified of the property specified
from the cell at the source specified to the cell at the destination specified; from the cell at the source specified to the cell at the destination specified;
@ -100,8 +102,11 @@
q (min (:quantity flow) (get-num source p)) q (min (:quantity flow) (get-num source p))
s' (assoc source p (- (source p) q)) s' (assoc source p (- (source p) q))
d' (assoc dest p (+ (get-num dest p) q))] d' (assoc dest p (+ (get-num dest p) q))]
(if (= q (:quantity flow))
(info (format "Moving %f units of %s from %d,%d to %d,%d" (info (format "Moving %f units of %s from %d,%d to %d,%d"
(float q) (name p) sx sy dx dy)) (float q) (name p) sx sy dx dy))
(warn (format "Moving %s from %d,%d to %d,%d; %f units ordered but only %f available"
(name p) sx sy dx dy (float (:quantity flow)) (float q))))
(merge-cell (merge-cell world s') d')) (merge-cell (merge-cell world s') d'))
(catch Exception e (catch Exception e
(warn (format "Failed to execute flow %s: %s" flow (.getMessage e))) (warn (format "Failed to execute flow %s: %s" flow (.getMessage e)))
@ -112,3 +117,25 @@
"Return a world like this `world`, but with each of these flows executed." "Return a world like this `world`, but with each of these flows executed."
[world flows] [world flows]
(reduce execute world (filter #(flow? % world) flows))) (reduce execute world (filter #(flow? % world) flows)))
;; building blocks for compiled flow rules
(defmacro create-location
[cell]
`(select-keys ~cell [:x :y]))
(defmacro create-flow-quantity
[source dest prop quantity]
`{:source (create-location ~source)
:destination (create-location ~dest)
:prop ~prop
:quantity ~quantity})
(defmacro create-flow-fraction
[source dest prop fraction]
`(create-flow-quantity ~source ~dest ~prop
(* ~fraction (get-num ~source ~prop))))
(defmacro create-flow-percent
[source dest prop percent]
`(create-flow-fraction ~source ~dest ~prop (/ ~percent 100)))

View file

@ -30,7 +30,8 @@
(defn member? (defn member?
"Return 'true' if elt is a member of col, else 'false'." "Return 'true' if elt is a member of col, else 'false'."
[elt col] (boolean ((set col) elt))) [elt col]
(contains? (set col) elt))
(defn get-int-or-zero (defn get-int-or-zero
"Return the value of this `property` from this `map` if it is a integer; "Return the value of this `property` from this `map` if it is a integer;
@ -51,7 +52,7 @@
"True if x, y are in bounds for this world (i.e., there is a cell at x, y) "True if x, y are in bounds for this world (i.e., there is a cell at x, y)
else false. *DEPRECATED*: it's a predicate, prefer `in-bounds?`. else false. *DEPRECATED*: it's a predicate, prefer `in-bounds?`.
* `world` a world as defined above; * `world` a world as defined in [world.clj](mw-engine.world.html);
* `x` a number which may or may not be a valid x coordinate within that world; * `x` a number which may or may not be a valid x coordinate within that world;
* `y` a number which may or may not be a valid y coordinate within that world." * `y` a number which may or may not be a valid y coordinate within that world."
{:deprecated "1.1.7"} {:deprecated "1.1.7"}
@ -62,7 +63,7 @@
"True if x, y are in bounds for this world (i.e., there is a cell at x, y) "True if x, y are in bounds for this world (i.e., there is a cell at x, y)
else false. else false.
* `world` a world as defined above; * `world` a world as defined in [world.clj](mw-engine.world.html);
* `x` a number which may or may not be a valid x coordinate within that world; * `x` a number which may or may not be a valid x coordinate within that world;
* `y` a number which may or may not be a valid y coordinate within that world." * `y` a number which may or may not be a valid y coordinate within that world."
{:added "1.1.7"} {:added "1.1.7"}
@ -117,7 +118,7 @@
(defn get-cell (defn get-cell
"Return the cell a x, y in this world, if any. "Return the cell a x, y in this world, if any.
* `world` a world as defined above; * `world` a world as defined in [world.clj](mw-engine.world.html);
* `x` a number which may or may not be a valid x coordinate within that world; * `x` a number which may or may not be a valid x coordinate within that world;
* `y` a number which may or may not be a valid y coordinate within that world." * `y` a number which may or may not be a valid y coordinate within that world."
[world x y] [world x y]
@ -178,17 +179,17 @@
"Get the neighbours to distance depth of a cell in this world. "Get the neighbours to distance depth of a cell in this world.
Several overloads: Several overloads:
* `world` a world, as described in world.clj; * `world` a world, as described in [world.clj](mw-engine.world.html);
* `cell` a cell within that world * `cell` a cell within that world
Gets immediate neighbours of the specified cell. Gets immediate neighbours of the specified cell.
* `world` a world, as described in world.clj; * `world` a world, as described in[world.clj](mw-engine.world.html);
* `cell` a cell within that world * `cell` a cell within that world
* `depth` an integer representing the depth to search from the * `depth` an integer representing the depth to search from the
`cell` `cell`
Gets neighbours within the specified distance of the cell. Gets neighbours within the specified distance of the cell.
* `world` a world, as described in world.clj; * `world` a world, as described in[world.clj](mw-engine.world.html);
* `x` an integer representing an x coordinate in that world; * `x` an integer representing an x coordinate in that world;
* `y` an integer representing an y coordinate in that world; * `y` an integer representing an y coordinate in that world;
* `depth` an integer representing the distance from [x,y] that * `depth` an integer representing the distance from [x,y] that
@ -206,7 +207,7 @@
"Get the neighbours to distance depth of the cell at x, y in this world which "Get the neighbours to distance depth of the cell at x, y in this world which
have this value for this property. have this value for this property.
* `world` a world, as described in `world.clj`; * `world` a world, as described in [world.clj](mw-engine.world.html);
* `cell` a cell within that world; * `cell` a cell within that world;
* `depth` an integer representing the distance from [x,y] that * `depth` an integer representing the distance from [x,y] that
should be searched (optional); should be searched (optional);
@ -235,7 +236,7 @@
"Get the neighbours to distance depth of the cell at x, y in this world which "Get the neighbours to distance depth of the cell at x, y in this world which
have this state. have this state.
* `world` a world, as described in `world.clj`; * `world` a world, as described in [world.clj](mw-engine.world.html);
* `cell` a cell within that world; * `cell` a cell within that world;
* `depth` an integer representing the distance from [x,y] that * `depth` an integer representing the distance from [x,y] that
should be searched; should be searched;

View file

@ -1,11 +1,11 @@
(ns mw-engine.core-test (ns mw-engine.core-test
(:require [clojure.test :refer :all] (:require [clojure.test :refer [deftest is testing]]
[mw-engine.core :refer :all])) [mw-engine.core :refer [apply-rule]]))
(deftest apply-rule-test (deftest apply-rule-test
(testing "Application of a single rule" (testing "Application of a single rule"
(let [afn (eval (let [afn (eval
(fn [cell world] (fn [cell _world]
(cond (cond
(= (:state cell) :new) (= (:state cell) :new)
(merge cell {:state :grassland})))) (merge cell {:state :grassland}))))

View file

@ -1,8 +1,8 @@
(ns mw-engine.drainage-test (ns mw-engine.drainage-test
(:require [clojure.test :refer :all] (:require [clojure.test :refer [deftest is testing]]
[mw-engine.world :as world] [mw-engine.drainage :refer [flood-hollow flood-hollows is-hollow]]
[mw-engine.utils :as utils] [mw-engine.utils :as utils]
[mw-engine.drainage :refer :all])) [mw-engine.world :as world]))
(deftest is-hollow-test (deftest is-hollow-test
(testing "detection of hollows" (testing "detection of hollows"

View file

@ -1,6 +1,7 @@
(ns mw-engine.flow-test (ns mw-engine.flow-test
(:require [clojure.test :refer [deftest is testing]] (:require [clojure.test :refer [deftest is testing]]
[mw-engine.flow :refer [coordinate? execute execute-flows flow? [mw-engine.flow :refer [coordinate? create-flow-percent
create-location execute execute-flows flow?
location?]] location?]]
[mw-engine.utils :refer [get-cell merge-cell]] [mw-engine.utils :refer [get-cell merge-cell]]
[mw-engine.world :refer [make-world]])) [mw-engine.world :refer [make-world]]))
@ -52,4 +53,33 @@
dest-q (:q (get-cell transferred 0 1))] dest-q (:q (get-cell transferred 0 1))]
(is (= source-q 2.9)) (is (= source-q 2.9))
(is (= inter-q 1.4)) (is (= inter-q 1.4))
(is (= dest-q 1)))))) (is (= dest-q 1))))
(let [world (make-world 3 3)
world' (merge-cell world {:x 0, :y 0, :state :new :q 5.3})
highdemand {:source {:x 0 :y 0}
:destination {:x 1 :y 1}
:property :q
:quantity 7.4}
transferred (execute world' highdemand)
source-q (:q (get-cell transferred 0 0))
dest-q (:q (get-cell transferred 1 1))
sx 0.0
dx 5.3]
(is (= source-q sx) "The entire stock should have gone;")
(is (= dest-q dx) "Only as much as was available should have arrived."))))
(deftest creator-macro-tests
(testing "Creator macros"
(let [source {:x 1 :y 2 :q 5.7 :state :house}
dest {:x 3 :y 3 :q 1 :state :house}
prop :q]
(let [expected {:x 1, :y 2}
actual (create-location source)]
(is (= actual expected)))
(let [expected {:source {:x 1, :y 2},
:prop :q,
:quantity 1.425,
:destination {:x 3, :y 3}}
actual (create-flow-percent source dest prop 25)]
(is (= actual expected))
(is (= (:quantity actual) (* 0.25 (:q source))))))))

View file

@ -1,9 +1,8 @@
(ns mw-engine.heightmap-test (ns mw-engine.heightmap-test
(:use clojure.java.io) (:require [clojure.java.io :refer [as-file]]
(:require [clojure.test :refer :all] [clojure.test :refer [deftest is testing]]
[mw-engine.heightmap :refer :all] [mw-engine.heightmap :refer [apply-heightmap apply-valuemap]]
[mw-engine.world :as world :only [make-world]] [mw-engine.world :refer [make-world]]))
[clojure.math.combinatorics :as combo]))
(deftest apply-heightmap-test (deftest apply-heightmap-test
(testing "Heightmap functionality" (testing "Heightmap functionality"
@ -22,7 +21,7 @@
(is (> (apply + gradients) 0) (is (> (apply + gradients) 0)
"At least some gradients must be positive, none should be negative")) "At least some gradients must be positive, none should be negative"))
;; alternate means of making the world, same tests. ;; alternate means of making the world, same tests.
(let [world (apply-heightmap (world/make-world 9 9) (as-file "resources/heightmaps/test9x9.png")) (let [world (apply-heightmap (make-world 9 9) (as-file "resources/heightmaps/test9x9.png"))
altitudes (map #(:altitude %) (flatten world)) altitudes (map #(:altitude %) (flatten world))
gradients (map #(:gradient %) (flatten world))] gradients (map #(:gradient %) (flatten world))]
(is (= (count world) 9) "World should be 9x9") (is (= (count world) 9) "World should be 9x9")

View file

@ -1,8 +1,11 @@
(ns mw-engine.utils-test (ns mw-engine.utils-test
(:use [mw-engine.world :as world]) (:require [clojure.math.combinatorics :as combo]
(:require [clojure.test :refer :all] [clojure.test :refer [deftest is testing]]
[clojure.math.combinatorics :as combo] [mw-engine.utils :refer [get-cell get-least-cell get-most-cell
[mw-engine.utils :refer :all])) get-neighbours
get-neighbours-with-property-value
map-world merge-cell set-property]]
[mw-engine.world :refer [make-world]]))
(deftest abs-test (deftest abs-test
(testing "Absolute value function" (testing "Absolute value function"
@ -116,8 +119,8 @@
(let [w1a (make-world 3 3) (let [w1a (make-world 3 3)
w2b (set-property w1a (get-cell w1a 1 1) :location :centre) w2b (set-property w1a (get-cell w1a 1 1) :location :centre)
w3c (set-property w2b 0 0 :location :top-left)] w3c (set-property w2b 0 0 :location :top-left)]
(is (= (:location (get-cell w3c 0 0) :top-left))) (is (= (:location (get-cell w3c 0 0)) :top-left))
(is (= (:location (get-cell w3c 1 1) :centre))) (is (= (:location (get-cell w3c 1 1)) :centre))
(is (nil? (:location (get-cell w3c 2 2))) (is (nil? (:location (get-cell w3c 2 2)))
"Cell at 2,2 should not have location set") "Cell at 2,2 should not have location set")
(is (= (count (remove nil? (map #(:location %) (flatten w3c)))) 2) (is (= (count (remove nil? (map #(:location %) (flatten w3c)))) 2)

View file

@ -1,6 +1,6 @@
(ns mw-engine.world-test (ns mw-engine.world-test
(:require [clojure.test :refer :all] (:require [clojure.test :refer [deftest is testing]]
[mw-engine.world :refer :all] [mw-engine.world :refer [make-world]]
[clojure.math.combinatorics :as combo])) [clojure.math.combinatorics :as combo]))
(deftest genesis-test (deftest genesis-test