1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-03 07:24:58 +03:00
inform7/docs/index-module/4-sm.html

3278 lines
710 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Spatial Map</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul><h2>Compiler Webs</h2><ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul><h2>Inbuild Modules</h2><ul>
<li><a href="../supervisor-module/index.html">supervisor</a></li>
</ul><h2>Inform7 Modules</h2><ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../assertions-module/index.html">assertions</a></li>
<li><a href="../values-module/index.html">values</a></li>
<li><a href="../knowledge-module/index.html">knowledge</a></li>
<li><a href="../imperative-module/index.html">imperative</a></li>
<li><a href="../runtime-module/index.html">runtime</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="index.html"><span class="selectedlink">index</span></a></li>
</ul><h2>Inter Modules</h2><ul>
<li><a href="../bytecode-module/index.html">bytecode</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../pipeline-module/index.html">pipeline</a></li>
<li><a href="../final-module/index.html">final</a></li>
</ul><h2>Services</h2><ul>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../calculus-module/index.html">calculus</a></li>
<li><a href="../html-module/index.html">html</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Spatial Map' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Inter Modules</a></li><li><a href="index.html">index</a></li><li><a href="index.html#4">Chapter 4: Spatial Mapping</a></li><li><b>Spatial Map</b></li></ul></div>
<p class="purpose">To fit the map of the rooms in the game into a cubical grid, preserving distances and angles where possible, and so to give each room approximate coordinate locations.</p>
<ul class="toc"><li><a href="4-sm.html#SP8">&#167;8. Grand strategy</a></li><li><a href="4-sm.html#SP8_3">&#167;8.3. Page directions</a></li><li><a href="4-sm.html#SP8_13">&#167;8.13. Map reading</a></li><li><a href="4-sm.html#SP12">&#167;12. Submap construction</a></li><li><a href="4-sm.html#SP8_21">&#167;8.21. Partitioning to component submaps</a></li><li><a href="4-sm.html#SP8_23">&#167;8.23. Movements of single rooms</a></li><li><a href="4-sm.html#SP8_24">&#167;8.24. Synchronising movements of locked rooms</a></li><li><a href="4-sm.html#SP8_26">&#167;8.26. Positioning within components</a></li><li><a href="4-sm.html#SP19">&#167;19. Heat</a></li><li><a href="4-sm.html#SP24">&#167;24. Subdividing our submap</a></li><li><a href="4-sm.html#SP25">&#167;25. Finding how to divide</a></li><li><a href="4-sm.html#SP27">&#167;27. Zones 1 and 2 for a single cut</a></li><li><a href="4-sm.html#SP29">&#167;29. Zones 1 and 2 for a double cut</a></li><li><a href="4-sm.html#SP31">&#167;31. Tactics</a></li><li><a href="4-sm.html#SP32">&#167;32. The cooling tactic</a></li><li><a href="4-sm.html#SP35">&#167;35. The quenching tactic</a></li><li><a href="4-sm.html#SP36">&#167;36. The diffusion tactic</a></li><li><a href="4-sm.html#SP38">&#167;38. The radiation tactic</a></li><li><a href="4-sm.html#SP8_28">&#167;8.28. The explosion tactic</a></li><li><a href="4-sm.html#SP8_29">&#167;8.29. Stage 3, positioning the components</a></li><li><a href="4-sm.html#SP8_31">&#167;8.31. Stage 5, bounding the universe</a></li><li><a href="4-sm.html#SP8_32">&#167;8.32. Stage 6, removing blank planes</a></li><li><a href="4-sm.html#SP45">&#167;45. Unit testing</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>We assign \((x, y, z)\) coordinates to each room, aiming to make the
descriptive map connections ("The Ballroom is east of the Old Kitchens")
as plausible as possible in coordinate terms. To do this well feels like a
research-level problem in graph theory or aesthetics, but we will just have
to muddle through.
</p>
<p class="commentary">Those experimenting with this code may like to use "Include spatial map
in the debugging layout", and the internal test cases with names in the form
<span class="extract"><span class="extract-syntax">Index-MapLayout-*</span></span>.
</p>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>We will partition the set of rooms into "components", which are disjoint
nonempty collections of rooms joined together by proximity. Proximity comes
about in two ways:
</p>
<ul class="items"><li>(i) Map connections in directions along lattice lines (EAST, UP, and so on
but not INSIDE or OUTSIDE);
</li><li>(ii) Locks placed between rooms by sentences intended to give this algorithm
hints about layout.
</li></ul>
<p class="commentary">As we will see, we will map rooms using a symmetric form of relationships:
if X relates to Y then Y relates to X. This will take some fixing, because
map connections in Inform needn't be symmetrical.
</p>
<p class="commentary">We must then solve two different problems. The first is to place rooms at
grid positions within each individual component. We assign each possible
arrangement a numerical measure of its geometric distortion, and then try
to minimise this, but of course any exhaustive search would be
prohibitively slow. This problem is quite likely NP-complete, and it looks
likely that we can embed notorious problems in complexity theory within it
(say, the bandwidth minimization problem). We do have the advantage of
experience about what IF maps look like, and of not having to deal well
with bizarre maps, but still, we shouldn't expect to achieve a perfect
choice. We must be very careful about running time; it's unacceptable for
the Inform indexer to take longer to run than Inform itself. The code below
is roughly quadratic in the number of rooms, which is a reasonable
compromise given how few works of IF have really enormous room counts.
</p>
<p class="commentary">The second problem is to place the components onto a global grid so that
they make sensible use of space on the index page, but don't get in each
other's way.
</p>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>A "connected submap" is a map formed from some subset of the rooms
in the model world, together with any spatial relationships between them,
such that it's possible to go from any X to any Y in the submap using only
some sequence of these relationships.
</p>
<p class="commentary">Connected submaps will arise initially because we'll take every component
of the map and make it into a connected submap; but then more will exist
temporarily as we cut these up. Each room will, at any given time, belong
to exactly one submap.
</p>
<p class="commentary">At any given point in our calculations each room has a grid location which
is a triple of integers \((x, y, z)\). The position of the origin is
undefined, and not relevant, since only the location of one room relative
to another is important. We will cache the values of the corner points of
the smallest cuboid \((x_0, y_0, z_0)\) to \((x_1, y_1, z_1)\) which contains
all of the rooms in our submap. Similarly, we cache the penalty score for
the current arrangement of rooms relative to each other within the submap
as the "heat", a term to be explained later.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_room_in_submap</span><span class="plain-syntax">; </span><span class="comment-syntax"> double-headed linked list of rooms</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">last_room_in_submap</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">cuboid</span><span class="plain-syntax"> </span><span class="identifier-syntax">bounds</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax">; </span><span class="comment-syntax"> current penalty score for bad placement of rooms</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">positioned</span><span class="plain-syntax">; </span><span class="comment-syntax"> already placed within the global map grid?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">incidence_cache</span><span class="plain-syntax">; </span><span class="comment-syntax"> how many of our rooms occupy each grid position?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">incidence_cache_size</span><span class="plain-syntax">; </span><span class="comment-syntax"> how large that cache is</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">cuboid</span><span class="plain-syntax"> </span><span class="identifier-syntax">incidence_cache_bounds</span><span class="plain-syntax">; </span><span class="comment-syntax"> bounds of the incidence cache array</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">superpositions</span><span class="plain-syntax">; </span><span class="comment-syntax"> number of pairs of rooms which share the same grid location</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">for_session</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">discarded</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure connected_submap is accessed in 2/ii, 2/sas and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>One special room is the "benchmark", from which the map is arranged.
This is usually the room in which the player begins.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::benchmark_level</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::benchmark_level</span></span>:<br/><a href="4-sm.html#SP8_29_1_1">&#167;8.29.1.1</a>, <a href="4-sm.html#SP8_29_1_2">&#167;8.29.1.2</a>, <a href="4-sm.html#SP8_29_1_3">&#167;8.29.1.3</a><br/>Faux Instances - <a href="2-fi.html#SP10_4">&#167;10.4</a><br/>Render HTML Map - <a href="4-rhm.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-fi.html#SP11" class="function-link"><span class="function-syntax">FauxInstances::benchmark</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><a href="2-fi.html#SP11" class="function-link"><span class="function-syntax">FauxInstances::benchmark</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">)).</span><span class="identifier-syntax">z</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>We are going to be iterating through the set of rooms often. Looping over
all rooms can afford to be fairly slow, but it's essential in order to keep
the running time down that we loop through submaps with overhead no worse
than the number of rooms in the submap; this is why we keep the linked list.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_room_in_submap</span><span class="plain-syntax">; </span><span class="identifier-syntax">R</span><span class="plain-syntax">; </span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_room_in_submap</span><span class="plain-syntax">)</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>These algorithms are trying to do something computationally expensive, so
it's useful to keep track of how much time they cost. The unit of currency
here is the "drogna"; 1 drogna is equivalent to a single map or lock lookup,
or a single exit heat calculation.
</p>
<p class="commentary">Just as each submap has a bounding cuboid, so does the whole assemblage:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">map_calculation_data</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">cuboid</span><span class="plain-syntax"> </span><span class="identifier-syntax">Universe</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">spatial_coordinates_established</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">partitioned_into_components</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">drognas_spent</span><span class="plain-syntax">; </span><span class="comment-syntax"> in order to measure roughly how much work we're doing</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cutpoint_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">division_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">slide_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cooling_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">quenching_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">diffusion_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">radiation_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">explosion_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">map_calculation_data</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure map_calculation_data is accessed in 4/rhm, 4/rem and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">map_calculation_data</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::fresh_data</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::fresh_data</span></span>:<br/>Indexing API - <a href="1-ia.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">map_calculation_data</span><span class="plain-syntax"> </span><span class="identifier-syntax">calc</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">Universe</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP10" class="function-link"><span class="function-syntax">Geometry::empty_cuboid</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">spatial_coordinates_established</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">partitioned_into_components</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> in order to measure roughly how much work we're doing</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">cutpoint_spending</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">division_spending</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">slide_spending</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">cooling_spending</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">quenching_spending</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">diffusion_spending</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">radiation_spending</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">explosion_spending</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">calc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Grand strategy. </b>Here is the six-stage strategy. I estimate that the running time is as
follows, where \(R\) is the number of rooms:
</p>
<ul class="items"><li>(1) Linear time, \(O(R)\), so essentially instant.
</li><li>(2) Linear time, \(O(R)\), so essentially instant.
</li><li>(3) About \(O(R^2\log R)\), at worst, but generally better in practical cases.
</li><li>(4) This could be as bad as \(O(R^2)\), but only in bizarre circumstances.
</li><li>(5) Linear time, \(O(R)\), so essentially instant.
</li><li>(6) In theory about \(O(R^{4/3})\), but in practice \(O(R)\).
</li></ul>
<p class="commentary">We allow this function to be called more than once only for the convenience of
the unit test below, which makes spatial positioning happen early in order
to get the results in time to write them in the story file.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::establish_spatial_coordinates</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::establish_spatial_coordinates</span></span>:<br/>Map Element - <a href="3-me.html#SP1">&#167;1</a><br/>Render EPS Map - <a href="4-rem.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">spatial_coordinates_established</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax"> = </span><a href="1-ia.html#SP8" class="function-link"><span class="function-syntax">Indexing::get_set_of_instances</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_14" class="named-paragraph-link"><span class="named-paragraph">(1) Create the spatial relationship arrays</span><span class="named-paragraph-number">8.14</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_21" class="named-paragraph-link"><span class="named-paragraph">(2) Partition the set of rooms into component submaps</span><span class="named-paragraph-number">8.21</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">partitioned_into_components</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_26" class="named-paragraph-link"><span class="named-paragraph">(3) Position the rooms within each component</span><span class="named-paragraph-number">8.26</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_29" class="named-paragraph-link"><span class="named-paragraph">(4) Position the components in space</span><span class="named-paragraph-number">8.29</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_31" class="named-paragraph-link"><span class="named-paragraph">(5) Find the universal bounding cuboid</span><span class="named-paragraph-number">8.31</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_32" class="named-paragraph-link"><span class="named-paragraph">(6) Remove any blank lateral planes</span><span class="named-paragraph-number">8.32</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_31" class="named-paragraph-link"><span class="named-paragraph">(5) Find the universal bounding cuboid</span><span class="named-paragraph-number">8.31</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">spatial_coordinates_established</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_1" class="paragraph-anchor"></a><b>&#167;8.1. </b>To make the code less cumbersome to read, all access to the position
will be using the following:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">) </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">position</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::set_room_position</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::set_room_position</span></span>:<br/><a href="4-sm.html#SP8_23">&#167;8.23</a>, <a href="4-sm.html#SP8_24">&#167;8.24</a>, <a href="4-sm.html#SP31">&#167;31</a>, <a href="4-sm.html#SP38_1">&#167;38.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">O</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">position</span><span class="plain-syntax"> = </span><span class="identifier-syntax">P</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax">) </span><a href="4-sm.html#SP16" class="function-link"><span class="function-syntax">SpatialMap::move_room_within_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax">, </span><span class="identifier-syntax">O</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::set_room_position_breaking_cache</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::set_room_position_breaking_cache</span></span>:<br/><a href="4-sm.html#SP8_18">&#167;8.18</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">position</span><span class="plain-syntax"> = </span><span class="identifier-syntax">P</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_2" class="paragraph-anchor"></a><b>&#167;8.2. </b>Locking is a way to influence the algorithm in this section by forcing a
given exit to be locked in place, forbidding it to be distorted.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::lock_exit_in_place</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::lock_exit_in_place</span></span>:<br/>Faux Instances - <a href="2-fi.html#SP10_2">&#167;10.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I2</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_2" class="function-link"><span class="function-syntax">SpatialMap::lock_one_exit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I2</span><span class="plain-syntax">, </span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_2" class="function-link"><span class="function-syntax">SpatialMap::lock_one_exit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">I2</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::lock_one_exit</span><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Mapping clue: put %S to the %s of %S\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">), </span><a href="4-sm.html#SP8_12" class="function-link"><span class="function-syntax">SpatialMap::usual_Inform_direction_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">lock_exits</span><span class="plain-syntax">[</span><span class="identifier-syntax">exit</span><span class="plain-syntax">] = </span><span class="identifier-syntax">T</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_3" class="paragraph-anchor"></a><b>&#167;8.3. Page directions. </b>These are any of the 12 standard IF directions (N, NE, NW, S, SE, SW, E, W,
U, D, IN, OUT), and are indexed with an number between 0 and 11 inclusive.
These are so called because they refer to directions on the page on which
the map will be plotted &mdash; the page direction 6 really means rightwards, not
east, but it's still convenient to think of them that way.
</p>
<p class="commentary">For most Inform projects, page directions correspond to directions in the
story file. But that needn't be true; some story files create exotic directions
like "port" and "starboard". So the following array gives the correspondence
of story directions to page directions; if the value is 12 or more, the direction
won't be shown on the index at all. The initial setup is for the 12 standard
story directions to correspond exactly to the 12 page directions.
</p>
<p class="commentary">If we want to show one of the exotic directions, we can use a sentence like:
</p>
<blockquote>
<p>Index map with starboard mapped as east.</p>
</blockquote>
<p class="commentary">When we read this, we associate direction object 13, say (the starboard
direction) with page direction 6:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="function-syntax">SpatialMap::mapped_as_if</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::mapped_as_if</span></span>:<br/>Render HTML Map - <a href="4-rhm.html#SP7_1_4">&#167;7.1.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax"> = </span><a href="1-ia.html#SP8" class="function-link"><span class="function-syntax">Indexing::get_set_of_instances</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">direction_index</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">story_dir_to_page_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] == </span><span class="identifier-syntax">i</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_FAUX_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">direction_index</span><span class="plain-syntax"> == </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">story_dir_to_page_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">])</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_4" class="paragraph-anchor"></a><b>&#167;8.4. </b>This is therefore how we know whether a given story direction will actually
be visible on the map we draw:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::direction_is_mappable</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::direction_is_mappable</span></span>:<br/>Render HTML Map - <a href="4-rhm.html#SP1_3">&#167;1.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_DIRECTIONS</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> = </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">story_dir_to_page_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">12</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_5" class="paragraph-anchor"></a><b>&#167;8.5. </b>Each page direction involves a given offset in lattice coordinates: for
example, direction 6 (E) involves an offset of \((1, 0, 0)\), because a move
in this map direction increases the \(x\)-coordinate by 1 and leaves \(y\) and \(z\)
unchanged.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::direction_as_vector</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::direction_as_vector</span></span>:<br/><a href="4-sm.html#SP8_8">&#167;8.8</a>, <a href="4-sm.html#SP8_9">&#167;8.9</a>, <a href="4-sm.html#SP8_24">&#167;8.24</a>, <a href="4-sm.html#SP22">&#167;22</a>, <a href="4-sm.html#SP23">&#167;23</a>, <a href="4-sm.html#SP24_1_4">&#167;24.1.4</a>, <a href="4-sm.html#SP34">&#167;34</a>, <a href="4-sm.html#SP38_1">&#167;38.1</a><br/>Render HTML Map - <a href="4-rhm.html#SP1_3_4">&#167;1.3.4</a><br/>Render EPS Map - <a href="4-rem.html#SP1_2_1_6_1_2">&#167;1.2.1.6.1.2</a>, <a href="4-rem.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_DIRECTIONS</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Zero_vector</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">session</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">story_dir_to_page_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">]):</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">page_direction</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">N_vector</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NE_vector</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NW_vector</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">S_vector</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">SE_vector</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">SW_vector</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">E_vector</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">W_vector</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">U_vector</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">9</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">D_vector</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Zero_vector</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_6" class="paragraph-anchor"></a><b>&#167;8.6. </b>Page directions all have opposites:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::opposite</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::opposite</span></span>:<br/><a href="4-sm.html#SP8_2">&#167;8.2</a>, <a href="4-sm.html#SP8_14_1">&#167;8.14.1</a>, <a href="4-sm.html#SP8_14_1_1">&#167;8.14.1.1</a>, <a href="4-sm.html#SP8_14_1_3">&#167;8.14.1.3</a>, <a href="4-sm.html#SP8_14_1_4">&#167;8.14.1.4</a>, <a href="4-sm.html#SP9">&#167;9</a>, <a href="4-sm.html#SP26_2_3_2">&#167;26.2.3.2</a>, <a href="4-sm.html#SP8_27">&#167;8.27</a><br/>Render EPS Map - <a href="4-rem.html#SP1_2_1_6_1">&#167;1.2.1.6.1</a>, <a href="4-rem.html#SP1_2_1_6_1_1">&#167;1.2.1.6.1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_DIRECTIONS</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">session</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">story_dir_to_page_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">]):</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">page_direction</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">; </span><span class="comment-syntax"> N &mdash; S</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">; </span><span class="comment-syntax"> NE &mdash; SW</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">; </span><span class="comment-syntax"> NW &mdash; SE</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> S &mdash; N</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">; </span><span class="comment-syntax"> SE &mdash; NW</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="comment-syntax"> SW &mdash; NE</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span><span class="plain-syntax">; </span><span class="comment-syntax"> E &mdash; W</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax">; </span><span class="comment-syntax"> W &mdash; E</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">9</span><span class="plain-syntax">; </span><span class="comment-syntax"> UP &mdash; DOWN</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">9</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span><span class="plain-syntax">; </span><span class="comment-syntax"> DOWN &mdash; UP</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">11</span><span class="plain-syntax">; </span><span class="comment-syntax"> IN &mdash; OUT</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">11</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span><span class="plain-syntax">; </span><span class="comment-syntax"> OUT &mdash; IN</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_7" class="paragraph-anchor"></a><b>&#167;8.7. </b>Lateral directions can be rotated clockwise (seen from above), if <span class="extract"><span class="extract-syntax">way</span></span>
is positive; or anticlockwise if it's negative.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::rotate_direction</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::rotate_direction</span></span>:<br/><a href="4-sm.html#SP8_14_1">&#167;8.14.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">way</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_DIRECTIONS</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">session</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">story_dir_to_page_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">]):</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">way</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">N</span><span class="plain-syntax"> = </span><span class="constant-syntax">7</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=1; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">N</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">page_direction</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> N &mdash; NE</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> = </span><span class="constant-syntax">6</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> NE &mdash; E</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> NW &mdash; N</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">: </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> = </span><span class="constant-syntax">5</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> S &mdash; SW</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">: </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> SE &mdash; S</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">: </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> = </span><span class="constant-syntax">7</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> SW &mdash; W</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax">: </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> E &mdash; SE</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span><span class="plain-syntax">: </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> W &mdash; NW</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> = -1; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_8" class="paragraph-anchor"></a><b>&#167;8.8. </b>Lateral directions are the ones which (a) are mappable, and (b) involve
movement along the \(x-y\) grid lines.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::direction_is_lateral</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::direction_is_lateral</span></span>:<br/>Render HTML Map - <a href="4-rhm.html#SP1_3_4">&#167;1.3.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-sg.html#SP6" class="function-link"><span class="function-syntax">Geometry::vec_lateral</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_5" class="function-link"><span class="function-syntax">SpatialMap::direction_as_vector</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_9" class="paragraph-anchor"></a><b>&#167;8.9. </b>Along-lattice directions are those which (a) are mappable, and (b) involve
movement along grid lines. Clearly lateral directions are along-lattice, but
not necessarily vice versa.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::direction_is_along_lattice</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::direction_is_along_lattice</span></span>:<br/><a href="4-sm.html#SP22">&#167;22</a>, <a href="4-sm.html#SP23">&#167;23</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_5" class="function-link"><span class="function-syntax">SpatialMap::direction_as_vector</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sg.html#SP6" class="function-link"><span class="function-syntax">Geometry::vec_eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="identifier-syntax">Zero_vector</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_10" class="paragraph-anchor"></a><b>&#167;8.10. </b>For speed, we don't call these functions when looping through directions;
we use these hard-wired macros instead.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_DIRECTION_NUMBERS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;12; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_STORY_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; ((</span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><a href="2-fi.html#SP12" class="function-link"><span class="function-syntax">FauxInstances::no_directions</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">MAX_DIRECTIONS</span><span class="plain-syntax">)); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;10; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_NONLATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=10; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;12; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_11" class="paragraph-anchor"></a><b>&#167;8.11. </b>Strictly speaking the following is more to do with rendering than
calculating, but it seems to belong here. In the HTML map, rooms have a
five-by-five cell grid, and exits are plotted at positions on the
boundary of that grid; for example, a line running in page direction 6
will be plotted with an icon at cell \((4, 2)\).
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::cell_position_for_direction</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::cell_position_for_direction</span></span>:<br/>Render HTML Map - <a href="4-rhm.html#SP1_3_4">&#167;1.3.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mx</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">my</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">mx</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; *</span><span class="identifier-syntax">my</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_DIRECTIONS</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">session</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">story_dir_to_page_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">]):</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">page_direction</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: *</span><span class="identifier-syntax">mx</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">; *</span><span class="identifier-syntax">my</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: *</span><span class="identifier-syntax">mx</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">; *</span><span class="identifier-syntax">my</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: *</span><span class="identifier-syntax">mx</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; *</span><span class="identifier-syntax">my</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">: *</span><span class="identifier-syntax">mx</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">; *</span><span class="identifier-syntax">my</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">: *</span><span class="identifier-syntax">mx</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">; *</span><span class="identifier-syntax">my</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">: *</span><span class="identifier-syntax">mx</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; *</span><span class="identifier-syntax">my</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax">: *</span><span class="identifier-syntax">mx</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">; *</span><span class="identifier-syntax">my</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span><span class="plain-syntax">: *</span><span class="identifier-syntax">mx</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; *</span><span class="identifier-syntax">my</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span><span class="plain-syntax">: *</span><span class="identifier-syntax">mx</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; *</span><span class="identifier-syntax">my</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">9</span><span class="plain-syntax">: *</span><span class="identifier-syntax">mx</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">; *</span><span class="identifier-syntax">my</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span><span class="plain-syntax">: *</span><span class="identifier-syntax">mx</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">; *</span><span class="identifier-syntax">my</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">11</span><span class="plain-syntax">: *</span><span class="identifier-syntax">mx</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; *</span><span class="identifier-syntax">my</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_12" class="paragraph-anchor"></a><b>&#167;8.12. </b>And similarly:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="function-syntax">SpatialMap::find_icon_label</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::find_icon_label</span></span>:<br/><a href="4-sm.html#SP34">&#167;34</a>, <a href="4-sm.html#SP35_1">&#167;35.1</a>, <a href="4-sm.html#SP36_1">&#167;36.1</a>, <a href="4-sm.html#SP38_1">&#167;38.1</a><br/>Render HTML Map - <a href="4-rhm.html#SP11_2_1">&#167;11.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_DIRECTIONS</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">session</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">story_dir_to_page_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">]):</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">page_direction</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"n"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"ne"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"nw"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"s"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"se"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"sw"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"e"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"w"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"u"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">9</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"d"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"in"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">11</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"out"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="function-syntax">SpatialMap::usual_Inform_direction_name</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::usual_Inform_direction_name</span></span>:<br/><a href="4-sm.html#SP8_2">&#167;8.2</a>, <a href="4-sm.html#SP24_1_2">&#167;24.1.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_DIRECTIONS</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"&lt;none&gt;"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">page_direction</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">session</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">story_dir_to_page_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">]):</span><span class="identifier-syntax">story_direction</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">page_direction</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"north"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"northeast"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"northwest"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"south"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"southeast"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"southwest"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"east"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"west"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"up"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">9</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"down"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"inside"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">11</span><span class="plain-syntax">: </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"outside"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="string-syntax">"&lt;none&gt;"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_13" class="paragraph-anchor"></a><b>&#167;8.13. Map reading. </b>The map is read in the first faux_instance by the <span class="extract"><span class="extract-syntax">SpatialMap::room_exit</span></span>
function below, which works out what room the exit leads to, perhaps via a
door, which we take a note of if asked to do so.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="function-syntax">SpatialMap::room_exit</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::room_exit</span></span>:<br/><a href="4-sm.html#SP10">&#167;10</a>, <a href="4-sm.html#SP44">&#167;44</a><br/>Render HTML Map - <a href="4-rhm.html#SP1_3">&#167;1.3</a>, <a href="4-rhm.html#SP11_2_2">&#167;11.2.2</a><br/>Render EPS Map - <a href="4-rem.html#SP1_2_1_6">&#167;1.2.1.6</a>, <a href="4-rem.html#SP1_2_1_6_1">&#167;1.2.1.6.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">origin</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">dir_num</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">via</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">via</span><span class="plain-syntax">) *</span><span class="identifier-syntax">via</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">origin</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::is_a_room</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">origin</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">dir_num</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">dir_num</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_DIRECTIONS</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ultimate_destination</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">immediate_destination</span><span class="plain-syntax"> = </span><span class="identifier-syntax">origin</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">exits</span><span class="plain-syntax">[</span><span class="identifier-syntax">dir_num</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">immediate_destination</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::is_a_room</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">immediate_destination</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ultimate_destination</span><span class="plain-syntax"> = </span><span class="identifier-syntax">immediate_destination</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::is_a_door</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">immediate_destination</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">via</span><span class="plain-syntax">) *</span><span class="identifier-syntax">via</span><span class="plain-syntax"> = </span><span class="identifier-syntax">immediate_destination</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">A</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">B</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_door_data</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">immediate_destination</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">A</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">B</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">A</span><span class="plain-syntax"> == </span><span class="identifier-syntax">origin</span><span class="plain-syntax">) </span><span class="identifier-syntax">ultimate_destination</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">B</span><span class="plain-syntax"> == </span><span class="identifier-syntax">origin</span><span class="plain-syntax">) </span><span class="identifier-syntax">ultimate_destination</span><span class="plain-syntax"> = </span><span class="identifier-syntax">A</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">ultimate_destination</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="function-syntax">SpatialMap::room_exit_as_indexed</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></span>:<br/><a href="4-sm.html#SP8_14">&#167;8.14</a>, <a href="4-sm.html#SP8_14_1">&#167;8.14.1</a>, <a href="4-sm.html#SP8_14_1_1">&#167;8.14.1.1</a>, <a href="4-sm.html#SP8_14_1_3">&#167;8.14.1.3</a>, <a href="4-sm.html#SP8_14_1_4">&#167;8.14.1.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">origin</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">dir_num</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">via</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">j</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">MAX_DIRECTIONS</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">story_dir_to_page_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] == </span><span class="identifier-syntax">dir_num</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">origin</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="identifier-syntax">via</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">I</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">I</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_14" class="paragraph-anchor"></a><b>&#167;8.14. </b>In practice, the map itself isn't the ideal source of data. It's slow to
keep checking all of that business with doors, and in any case the map is
asymmetrical. Instead, we use the following. The tricky point here is that
we want to record a sort of symmetric version of the map, which takes some
adjudication.
</p>
<p class="commentary">As can be seen, step (1) runs in \(O(R)\) time, where \(R\) is the number of rooms.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(1) Create the spatial relationship arrays</span><span class="named-paragraph-number">8.14</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_FAUX_ROOMS</span><span class="plain-syntax">(</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_14_1" class="named-paragraph-link"><span class="named-paragraph">Consider this Inform map connection for a spatial relationship</span><span class="named-paragraph-number">8.14.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_14_1" class="paragraph-anchor"></a><b>&#167;8.14.1. </b>We first find a spread of nearly opposite directions: for instance, if <span class="extract"><span class="extract-syntax">i</span></span>
is northeast, then <span class="extract"><span class="extract-syntax">back</span></span> is SW, <span class="extract"><span class="extract-syntax">cw</span></span> is W, <span class="extract"><span class="extract-syntax">cwcw</span></span> is NW, <span class="extract"><span class="extract-syntax">ccw</span></span> is S, <span class="extract"><span class="extract-syntax">ccwccw</span></span>
is SE. We also find the <span class="extract"><span class="extract-syntax">backstep</span></span>, the room you get to if trying to go back
from the destination in the <span class="extract"><span class="extract-syntax">back</span></span> direction; which in a nicely arranged
map will be the room you start from, but that can't be assumed.
</p>
<p class="commentary">The cases below don't exhaust the possibilities. We could be left with a
1-way connection blocked at the other end, in cases where no 2-way
connection exists between rooms <span class="extract"><span class="extract-syntax">R</span></span> and <span class="extract"><span class="extract-syntax">T</span></span>. If so, we shrug and ignore it;
this will be a situation where the connection doesn't help us. (It will still
be plotted on the index page; we just won't use it in our choice of how to
position the rooms.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Consider this Inform map connection for a spatial relationship</span><span class="named-paragraph-number">8.14.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">back</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cw</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_7" class="function-link"><span class="function-syntax">SpatialMap::rotate_direction</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">back</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">); </span><span class="comment-syntax"> clockwise one place</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">cwcw</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_7" class="function-link"><span class="function-syntax">SpatialMap::rotate_direction</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cw</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">); </span><span class="comment-syntax"> clockwise twice</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ccw</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_7" class="function-link"><span class="function-syntax">SpatialMap::rotate_direction</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">back</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">session</span><span class="plain-syntax">); </span><span class="comment-syntax"> counterclockwise once</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ccwccw</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_7" class="function-link"><span class="function-syntax">SpatialMap::rotate_direction</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ccw</span><span class="plain-syntax">, -1, </span><span class="identifier-syntax">session</span><span class="plain-syntax">); </span><span class="comment-syntax"> counterclockwise twice</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">backstep</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">back</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_14_1_1" class="named-paragraph-link"><span class="named-paragraph">Average out a pair of 2-way connections which each bend</span><span class="named-paragraph-number">8.14.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_14_1_2" class="named-paragraph-link"><span class="named-paragraph">Turn a straightforward 2-way connection into a spatial relationship</span><span class="named-paragraph-number">8.14.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_14_1_3" class="named-paragraph-link"><span class="named-paragraph">Average out a pair of 1-way connections which suggest a deformed 2-way connection</span><span class="named-paragraph-number">8.14.1.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_14_1_4" class="named-paragraph-link"><span class="named-paragraph">Treat a 1-way connection as 2-way if there are no 2-way connections already</span><span class="named-paragraph-number">8.14.1.4</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8_14">&#167;8.14</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_14_1_1" class="paragraph-anchor"></a><b>&#167;8.14.1.1. </b>What we're looking for here is a configuration like:
</p>
<blockquote>
<p>Alpha is east of Beta. Beta is south of Alpha.</p>
</blockquote>
<p class="commentary">This in fact sets up four connections: A is both S and W of B, and B is both
N and E of A. A reasonable interpretation is that A lies SW of B, and so we
form a single (symmetric) spatial relationship between them, in this direction.
We check first clockwise, then counterclockwise.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Average out a pair of 2-way connections which each bend</span><span class="named-paragraph-number">8.14.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">backstep</span><span class="plain-syntax"> == </span><span class="identifier-syntax">R</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">cwcw</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">cwcw</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">R</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">cw</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cwcw</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">T</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cw</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP9" class="function-link"><span class="function-syntax">SpatialMap::form_spatial_relationship</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cw</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">backstep</span><span class="plain-syntax"> == </span><span class="identifier-syntax">R</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">ccwccw</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">ccwccw</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">R</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">ccw</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ccwccw</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">T</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ccw</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP9" class="function-link"><span class="function-syntax">SpatialMap::form_spatial_relationship</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ccw</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8_14_1">&#167;8.14.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_14_1_2" class="paragraph-anchor"></a><b>&#167;8.14.1.2. </b>The easiest case:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Turn a straightforward 2-way connection into a spatial relationship</span><span class="named-paragraph-number">8.14.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">backstep</span><span class="plain-syntax"> == </span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP9" class="function-link"><span class="function-syntax">SpatialMap::form_spatial_relationship</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8_14_1">&#167;8.14.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_14_1_3" class="paragraph-anchor"></a><b>&#167;8.14.1.3. </b>Now perhaps A runs east to B, B runs south to A, but these are both 1-way
connections. We'll regard this as being a single passageway running on average
northeast from A to B:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Average out a pair of 1-way connections which suggest a deformed 2-way connection</span><span class="named-paragraph-number">8.14.1.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="comment-syntax"> a deformed 2-way connection made up of 1-way connections</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cwcw</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">cwcw</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">R</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">cw</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cwcw</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">T</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cw</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP9" class="function-link"><span class="function-syntax">SpatialMap::form_spatial_relationship</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cw</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ccwccw</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">ccwccw</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">R</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">ccw</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ccwccw</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">T</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ccw</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP9" class="function-link"><span class="function-syntax">SpatialMap::form_spatial_relationship</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ccw</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8_14_1">&#167;8.14.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_14_1_4" class="paragraph-anchor"></a><b>&#167;8.14.1.4. </b>Most of the time, a 1-way connection is fine for mapping purposes; it
establishes as good a spatial relationship as a 2-way one. But we suppress
this if either (a) there are already 2-way connections between the rooms
in general, or (b) the opposite connection exists but is to a different
room (the case where <span class="extract"><span class="extract-syntax">backstep</span></span> is not null here).
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Treat a 1-way connection as 2-way if there are no 2-way connections already</span><span class="named-paragraph-number">8.14.1.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="identifier-syntax">two_ways</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">j</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">R</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit_as_indexed</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">T</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">two_ways</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">two_ways</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">backstep</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP9" class="function-link"><span class="function-syntax">SpatialMap::form_spatial_relationship</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8_14_1">&#167;8.14.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>The following ensures that SR links are always symmetric, in opposed
pairs of directions:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::form_spatial_relationship</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::form_spatial_relationship</span></span>:<br/><a href="4-sm.html#SP8_14_1_1">&#167;8.14.1.1</a>, <a href="4-sm.html#SP8_14_1_2">&#167;8.14.1.2</a>, <a href="4-sm.html#SP8_14_1_3">&#167;8.14.1.3</a>, <a href="4-sm.html#SP8_14_1_4">&#167;8.14.1.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">dir</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">spatial_relationship</span><span class="plain-syntax">[</span><span class="identifier-syntax">dir</span><span class="plain-syntax">] = </span><span class="identifier-syntax">T</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">spatial_relationship</span><span class="plain-syntax">[</span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">dir</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">)] = </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>The spatial relationships arrays are read only by the following. Note
that <span class="extract"><span class="extract-syntax">SpatialMap::read_smap</span></span> suppresses relationships between different submaps (at
least once the initial map components have been set up). This is done to
make it easy and quick to cut up a submap into two sub-submaps; effectively
severing any links between them. All we need do is move the rooms around
from one submap to another.
</p>
<p class="commentary"><span class="extract"><span class="extract-syntax">SpatialMap::read_smap_cross</span></span> has the ability to read relationships which cross submap
boundaries, and will be needed when we place submaps on the global grid.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="function-syntax">SpatialMap::read_smap</span><button class="popup" onclick="togglePopup('usagePopup20')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup20">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::read_smap</span></span>:<br/><a href="4-sm.html#SP8_22">&#167;8.22</a>, <a href="4-sm.html#SP18">&#167;18</a>, <a href="4-sm.html#SP22">&#167;22</a>, <a href="4-sm.html#SP23">&#167;23</a>, <a href="4-sm.html#SP26">&#167;26</a>, <a href="4-sm.html#SP28">&#167;28</a>, <a href="4-sm.html#SP30">&#167;30</a>, <a href="4-sm.html#SP33_1">&#167;33.1</a>, <a href="4-sm.html#SP34">&#167;34</a>, <a href="4-sm.html#SP35_1">&#167;35.1</a>, <a href="4-sm.html#SP36">&#167;36</a>, <a href="4-sm.html#SP37">&#167;37</a>, <a href="4-sm.html#SP38">&#167;38</a>, <a href="4-sm.html#SP8_27">&#167;8.27</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">dir</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">from</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to read smap at null room"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">from</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">spatial_relationship</span><span class="plain-syntax">[</span><span class="identifier-syntax">dir</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">partitioned_into_components</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">to</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">from</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax"> != </span><span class="identifier-syntax">to</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="function-syntax">SpatialMap::read_smap_cross</span><button class="popup" onclick="togglePopup('usagePopup21')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup21">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::read_smap_cross</span></span>:<br/><a href="4-sm.html#SP43">&#167;43</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">dir</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">from</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to read smap at null room"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">dir</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">to</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>While we're at it:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="function-syntax">SpatialMap::read_slock</span><button class="popup" onclick="togglePopup('usagePopup22')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup22">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::read_slock</span></span>:<br/><a href="4-sm.html#SP8_22">&#167;8.22</a>, <a href="4-sm.html#SP8_24">&#167;8.24</a>, <a href="4-sm.html#SP26">&#167;26</a>, <a href="4-sm.html#SP26_2_3_2">&#167;26.2.3.2</a>, <a href="4-sm.html#SP28">&#167;28</a>, <a href="4-sm.html#SP30">&#167;30</a>, <a href="4-sm.html#SP37">&#167;37</a>, <a href="4-sm.html#SP8_27">&#167;8.27</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">dir</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">from</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"tried to read slock at null room"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">lock_exits</span><span class="plain-syntax">[</span><span class="identifier-syntax">dir</span><span class="plain-syntax">];</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Submap construction. </b>Here's an empty submap, with no rooms.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="function-syntax">SpatialMap::new_submap</span><button class="popup" onclick="togglePopup('usagePopup23')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup23">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::new_submap</span></span>:<br/><a href="4-sm.html#SP8_22">&#167;8.22</a>, <a href="4-sm.html#SP24_1_3">&#167;24.1.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-ia.html#SP7" class="function-link"><span class="function-syntax">Indexing::add_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP10" class="function-link"><span class="function-syntax">Geometry::empty_cuboid</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_room_in_submap</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_room_in_submap</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache_bounds</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP10" class="function-link"><span class="function-syntax">Geometry::empty_cuboid</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">superpositions</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax"> = </span><span class="identifier-syntax">session</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">discarded</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b>This will loop through all of the submaps attached to a session, assuming
that <span class="extract"><span class="extract-syntax">LS</span></span> already holds the session's list:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_SUBMAPS</span><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax">, </span><span class="identifier-syntax">LS</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">discarded</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. </b>Doctrinally, a room is always in just one submap, except at the very beginning
when we are forming the original components into submaps, when most of the
rooms aren't yet in any submap. Doctrinally, too, if a room is in a submap,
any room locked to it must always be in the same submap.
</p>
<p class="commentary">That makes the following function dangerous to use, since it doesn't guarantee
either of those things. Use with care.
</p>
<p class="commentary">Because we keep a double-ended linked list to hold membership, adding a
room to a submap takes constant time with respect to the number of rooms \(R\).
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::add_room_to_submap</span><button class="popup" onclick="togglePopup('usagePopup24')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup24">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::add_room_to_submap</span></span>:<br/><a href="4-sm.html#SP8_19">&#167;8.19</a>, <a href="4-sm.html#SP8_20">&#167;8.20</a>, <a href="4-sm.html#SP8_22">&#167;8.22</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_room_in_submap</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_room_in_submap</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_room_in_submap</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_room_in_submap</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_room_in_submap</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_room_in_submap</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_room_in_submap</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP17" class="function-link"><span class="function-syntax">SpatialMap::add_room_to_cache</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. </b>Here is how we read from the incidence cache. Its purpose is to provide
a constant running-time way to find out if a given position would collide
with that of an existing room in the submap &mdash; something we could otherwise
find out only by an \(O(R)\) search. If we had to maintain enormous submaps
of rooms, we'd probably want a balanced geographical tree structure, of the
sort used for collision detection in first-person shooters; but as it is,
we have plenty of memory and relatively few possible location coordinate
positions. So we simply keep a cubical array; though it may need to be
resized as the rooms in the submap move around, which complicates things.
</p>
<p class="commentary">Anyway, this returns the number of rooms at position P within the submap.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::occupied_in_submap</span><button class="popup" onclick="togglePopup('usagePopup25')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup25">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::occupied_in_submap</span></span>:<br/><a href="4-sm.html#SP22">&#167;22</a>, <a href="4-sm.html#SP8_28">&#167;8.28</a>, <a href="4-sm.html#SP41">&#167;41</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP14" class="function-link"><span class="function-syntax">Geometry::cuboid_index</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache_bounds</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. </b>The cache will be invalidated by any movement of a room, so the following
function must be notified of any such:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::move_room_within_submap</span><button class="popup" onclick="togglePopup('usagePopup26')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup26">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::move_room_within_submap</span></span>:<br/><a href="4-sm.html#SP8_1">&#167;8.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">O</span><span class="plain-syntax">, </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP17" class="function-link"><span class="function-syntax">SpatialMap::add_room_to_cache</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">O</span><span class="plain-syntax">, -1);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP17" class="function-link"><span class="function-syntax">SpatialMap::add_room_to_cache</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. </b>Here goes, then: the following increments the cached population value at <span class="extract"><span class="extract-syntax">P</span></span>
if <span class="extract"><span class="extract-syntax">m</span></span> is 1, decrements it if \(-1\).
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::add_room_to_cache</span><button class="popup" onclick="togglePopup('usagePopup27')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup27">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::add_room_to_cache</span></span>:<br/><a href="4-sm.html#SP14">&#167;14</a>, <a href="4-sm.html#SP16">&#167;16</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sg.html#SP13" class="function-link"><span class="function-syntax">Geometry::within_cuboid</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache_bounds</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP17_1" class="named-paragraph-link"><span class="named-paragraph">Location P lies outside the current incidence cache</span><span class="named-paragraph-number">17.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP14" class="function-link"><span class="function-syntax">Geometry::cuboid_index</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache_bounds</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">t</span><span class="plain-syntax">+</span><span class="identifier-syntax">m</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">t</span><span class="plain-syntax"> = -</span><span class="identifier-syntax">m</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">t</span><span class="plain-syntax">+</span><span class="identifier-syntax">m</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">m</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">superpositions</span><span class="plain-syntax"> += </span><span class="constant-syntax">2</span><span class="plain-syntax">*</span><span class="identifier-syntax">t</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">m</span><span class="plain-syntax"> == -1) </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">superpositions</span><span class="plain-syntax"> -= </span><span class="constant-syntax">2</span><span class="plain-syntax">*(</span><span class="identifier-syntax">t</span><span class="plain-syntax">-1);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17_1" class="paragraph-anchor"></a><b>&#167;17.1. </b>We make a new incidence cache which is more than large enough to contain
both P and the existing one, and then copy the old one's contents into the
new one before deallocating the old.
</p>
<p class="commentary">This looks as if it has cubic running time, but isn't really that bad,
since the volume of the cuboid is probably about proportional to \(R\) rather
than \(R^3\) (assuming rooms are fairly evenly distributed through space).
Still, we ought to make sure it happens fairly seldom. We therefore expand
the cuboid by a margin giving us always at least 20 more cells than we need
horizontally, and 3 vertically. Since movements within submaps are modest
and local, this means very few submaps need to expand more than twice at
the most.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Location P lies outside the current incidence cache</span><span class="named-paragraph-number">17.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">cuboid</span><span class="plain-syntax"> </span><span class="identifier-syntax">old_cuboid</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache_bounds</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">cuboid</span><span class="plain-syntax"> </span><span class="identifier-syntax">new_cuboid</span><span class="plain-syntax"> = </span><span class="identifier-syntax">old_cuboid</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP15" class="function-link"><span class="function-syntax">Geometry::thicken_cuboid</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">new_cuboid</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><a href="4-sg.html#SP5" class="function-link"><span class="function-syntax">Geometry::vec</span></a><span class="plain-syntax">(20, </span><span class="constant-syntax">20</span><span class="plain-syntax">, </span><span class="constant-syntax">3</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">extent</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP14" class="function-link"><span class="function-syntax">Geometry::cuboid_volume</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_cuboid</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_cache</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Memory::calloc</span><span class="plain-syntax">(</span><span class="identifier-syntax">extent</span><span class="plain-syntax">, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax">), </span><span class="constant-syntax">MAP_INDEX_MREASON</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">x</span><span class="plain-syntax">, </span><span class="identifier-syntax">y</span><span class="plain-syntax">, </span><span class="identifier-syntax">z</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">x</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_cuboid</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax">; </span><span class="identifier-syntax">x</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">new_cuboid</span><span class="plain-syntax">.</span><span class="element-syntax">corner1</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax">; </span><span class="identifier-syntax">x</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">y</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_cuboid</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax">; </span><span class="identifier-syntax">y</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">new_cuboid</span><span class="plain-syntax">.</span><span class="element-syntax">corner1</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax">; </span><span class="identifier-syntax">y</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">z</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_cuboid</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax">; </span><span class="identifier-syntax">z</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">new_cuboid</span><span class="plain-syntax">.</span><span class="element-syntax">corner1</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax">; </span><span class="identifier-syntax">z</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP14" class="function-link"><span class="function-syntax">Geometry::cuboid_index</span></a><span class="plain-syntax">(</span><a href="4-sg.html#SP5" class="function-link"><span class="function-syntax">Geometry::vec</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">x</span><span class="plain-syntax">,</span><span class="identifier-syntax">y</span><span class="plain-syntax">,</span><span class="identifier-syntax">z</span><span class="plain-syntax">), </span><span class="identifier-syntax">new_cuboid</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_cache</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">old_cache</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">old_cache</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">x</span><span class="plain-syntax"> = </span><span class="identifier-syntax">old_cuboid</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax">; </span><span class="identifier-syntax">x</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">old_cuboid</span><span class="plain-syntax">.</span><span class="element-syntax">corner1</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax">; </span><span class="identifier-syntax">x</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">y</span><span class="plain-syntax"> = </span><span class="identifier-syntax">old_cuboid</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax">; </span><span class="identifier-syntax">y</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">old_cuboid</span><span class="plain-syntax">.</span><span class="element-syntax">corner1</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax">; </span><span class="identifier-syntax">y</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">z</span><span class="plain-syntax"> = </span><span class="identifier-syntax">old_cuboid</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax">; </span><span class="identifier-syntax">z</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">old_cuboid</span><span class="plain-syntax">.</span><span class="element-syntax">corner1</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax">; </span><span class="identifier-syntax">z</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP14" class="function-link"><span class="function-syntax">Geometry::cuboid_index</span></a><span class="plain-syntax">(</span><a href="4-sg.html#SP5" class="function-link"><span class="function-syntax">Geometry::vec</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">x</span><span class="plain-syntax">,</span><span class="identifier-syntax">y</span><span class="plain-syntax">,</span><span class="identifier-syntax">z</span><span class="plain-syntax">), </span><span class="identifier-syntax">old_cuboid</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax"> = </span><span class="identifier-syntax">old_cache</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">t</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP14" class="function-link"><span class="function-syntax">Geometry::cuboid_index</span></a><span class="plain-syntax">(</span><a href="4-sg.html#SP5" class="function-link"><span class="function-syntax">Geometry::vec</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">x</span><span class="plain-syntax">,</span><span class="identifier-syntax">y</span><span class="plain-syntax">,</span><span class="identifier-syntax">z</span><span class="plain-syntax">), </span><span class="identifier-syntax">new_cuboid</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_cache</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="identifier-syntax">t</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_15" class="function-link"><span class="function-syntax">SpatialMap::free_incidence_cache</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_cache</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache_size</span><span class="plain-syntax"> = </span><span class="identifier-syntax">extent</span><span class="plain-syntax">*((</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache_bounds</span><span class="plain-syntax"> = </span><span class="identifier-syntax">new_cuboid</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP17">&#167;17</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_15" class="paragraph-anchor"></a><b>&#167;8.15. </b>Here we throw away the cache, something which must otherwise only be done
when the submap has no rooms...
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::free_incidence_cache</span><button class="popup" onclick="togglePopup('usagePopup28')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup28">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::free_incidence_cache</span></span>:<br/><a href="4-sm.html#SP17_1">&#167;17.1</a>, <a href="4-sm.html#SP8_16">&#167;8.16</a>, <a href="4-sm.html#SP8_17">&#167;8.17</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Memory::I7_free</span><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache</span><span class="plain-syntax">, </span><span class="constant-syntax">MAP_INDEX_MREASON</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache_size</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache_bounds</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP10" class="function-link"><span class="function-syntax">Geometry::empty_cuboid</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_16" class="paragraph-anchor"></a><b>&#167;8.16. </b>...such as now:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::empty_submap</span><button class="popup" onclick="togglePopup('usagePopup29')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup29">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::empty_submap</span></span>:<br/><a href="4-sm.html#SP8_19">&#167;8.19</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_room_in_submap</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_room_in_submap</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_15" class="function-link"><span class="function-syntax">SpatialMap::free_incidence_cache</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">superpositions</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_17" class="paragraph-anchor"></a><b>&#167;8.17. </b>And finally:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::destroy_submap</span><button class="popup" onclick="togglePopup('usagePopup30')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup30">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::destroy_submap</span></span>:<br/><a href="4-sm.html#SP24_1_3">&#167;24.1.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_15" class="function-link"><span class="function-syntax">SpatialMap::free_incidence_cache</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">discarded</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_18" class="paragraph-anchor"></a><b>&#167;8.18. </b>Suppose we want to move all the rooms in a submap at once, and all by the
same vector <span class="extract"><span class="extract-syntax">D</span></span>. Then we can simply move the cache boundaries, too, and not
have to change the contents of the cache at all.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::move_component</span><button class="popup" onclick="togglePopup('usagePopup31')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup31">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::move_component</span></span>:<br/><a href="4-sm.html#SP8_29_1_1">&#167;8.29.1.1</a>, <a href="4-sm.html#SP8_29_1_2">&#167;8.29.1.2</a>, <a href="4-sm.html#SP8_29_1_3">&#167;8.29.1.3</a>, <a href="4-sm.html#SP8_29_1_3_1">&#167;8.29.1.3.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_1" class="function-link"><span class="function-syntax">SpatialMap::set_room_position_breaking_cache</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_plus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="identifier-syntax">D</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP12" class="function-link"><span class="function-syntax">Geometry::cuboid_translate</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">), </span><span class="identifier-syntax">D</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP12" class="function-link"><span class="function-syntax">Geometry::cuboid_translate</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">incidence_cache_bounds</span><span class="plain-syntax">), </span><span class="identifier-syntax">D</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_19" class="paragraph-anchor"></a><b>&#167;8.19. </b>The following functions will be used in order to divide an existing submap
into two new ones, which we'll call Zone 1 and Zone 2, and then to merge
them back again.
</p>
<p class="commentary">We start with each room in <span class="extract"><span class="extract-syntax">sub</span></span> having a value of <span class="extract"><span class="extract-syntax">zone</span></span> set to either
<span class="extract"><span class="extract-syntax">Z1_number</span></span> or <span class="extract"><span class="extract-syntax">Z2_number</span></span>, the former meaning it is destined for Zone 1,
the latter for Zone 2. It's assumed here that if two rooms are locked together
then they have the same value of <span class="extract"><span class="extract-syntax">zone</span></span>. With that done, we empty <span class="extract"><span class="extract-syntax">sub</span></span>,
since its rooms have all moved out.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::create_submaps_from_zones</span><button class="popup" onclick="togglePopup('usagePopup32')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup32">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::create_submaps_from_zones</span></span>:<br/><a href="4-sm.html#SP24_1_3">&#167;24.1.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Z1_number</span><span class="plain-syntax">, </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Zone1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Z2_number</span><span class="plain-syntax">, </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Zone2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax"> = </span><a href="1-ia.html#SP8" class="function-link"><span class="function-syntax">Indexing::get_set_of_instances</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_FAUX_ROOMS</span><span class="plain-syntax">(</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="identifier-syntax">Z1_number</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP14" class="function-link"><span class="function-syntax">SpatialMap::add_room_to_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">Zone1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="identifier-syntax">Z2_number</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP14" class="function-link"><span class="function-syntax">SpatialMap::add_room_to_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">Zone2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_16" class="function-link"><span class="function-syntax">SpatialMap::empty_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_20" class="paragraph-anchor"></a><b>&#167;8.20. </b>Convert membership of Zone 1 or 2 back into value of the zone number: the
reverse process exactly.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::create_zones_from_submaps</span><button class="popup" onclick="togglePopup('usagePopup33')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup33">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::create_zones_from_submaps</span></span>:<br/><a href="4-sm.html#SP24_1_3">&#167;24.1.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Z1_number</span><span class="plain-syntax">, </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Zone1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Z2_number</span><span class="plain-syntax">, </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Zone2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax"> = </span><a href="1-ia.html#SP8" class="function-link"><span class="function-syntax">Indexing::get_set_of_instances</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_FAUX_ROOMS</span><span class="plain-syntax">(</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax"> == </span><span class="identifier-syntax">Zone1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP14" class="function-link"><span class="function-syntax">SpatialMap::add_room_to_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Z1_number</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax"> == </span><span class="identifier-syntax">Zone2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP14" class="function-link"><span class="function-syntax">SpatialMap::add_room_to_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Z2_number</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_21" class="paragraph-anchor"></a><b>&#167;8.21. Partitioning to component submaps. </b>We can now go back to our strategy. The next task is to partition the map into
components, that is, equivalence classes under the closure of the relation
\(R\sim S\) if either \(R\) is locked to \(S\) or if there is a spatial relationship
between \(R\) and \(S\).
</p>
<p class="commentary">We ensure that the first-created component is the one containing the
benchmark room.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(2) Partition the set of rooms into component submaps</span><span class="named-paragraph-number">8.21</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_22" class="function-link"><span class="function-syntax">SpatialMap::create_map_component_around</span></a><span class="plain-syntax">(</span><a href="2-fi.html#SP11" class="function-link"><span class="function-syntax">FauxInstances::benchmark</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">), </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_FAUX_ROOMS</span><span class="plain-syntax">(</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_22" class="function-link"><span class="function-syntax">SpatialMap::create_map_component_around</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_22" class="paragraph-anchor"></a><b>&#167;8.22. </b>The following grows a component outwards from <span class="extract"><span class="extract-syntax">at</span></span>, so that it also includes
all rooms locked to <span class="extract"><span class="extract-syntax">at</span></span> or with a SR to it. If <span class="extract"><span class="extract-syntax">at</span></span> is currently not in a
component, we start a new submap to hold it.
</p>
<p class="commentary">Note that <span class="extract"><span class="extract-syntax">SpatialMap::create_map_component_around</span></span> has constant running time, i.e., it
doesn't depend on \(R\), the number of rooms. It is called exactly once for
each room, so phase (2) has running time \(O(R)\).
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::create_map_component_around</span><button class="popup" onclick="togglePopup('usagePopup34')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup34">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::create_map_component_around</span></span>:<br/><a href="4-sm.html#SP8_21">&#167;8.21</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">at</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP14" class="function-link"><span class="function-syntax">SpatialMap::add_room_to_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><a href="4-sm.html#SP12" class="function-link"><span class="function-syntax">SpatialMap::new_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">locked_to</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP11" class="function-link"><span class="function-syntax">SpatialMap::read_slock</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">locked_to</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">locked_to</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax"> != </span><span class="identifier-syntax">at</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP14" class="function-link"><span class="function-syntax">SpatialMap::add_room_to_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">locked_to</span><span class="plain-syntax">, </span><span class="identifier-syntax">at</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_22" class="function-link"><span class="function-syntax">SpatialMap::create_map_component_around</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">locked_to</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dest</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">dest</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">dest</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax"> != </span><span class="identifier-syntax">at</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP14" class="function-link"><span class="function-syntax">SpatialMap::add_room_to_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="identifier-syntax">at</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_22" class="function-link"><span class="function-syntax">SpatialMap::create_map_component_around</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">dest</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_23" class="paragraph-anchor"></a><b>&#167;8.23. Movements of single rooms. </b>Positions are just 3-vectors, so:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::translate_room</span><button class="popup" onclick="togglePopup('usagePopup35')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup35">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::translate_room</span></span>:<br/><a href="4-sm.html#SP24_1_4_1">&#167;24.1.4.1</a>, <a href="4-sm.html#SP36_1">&#167;36.1</a>, <a href="4-sm.html#SP38_1_1">&#167;38.1.1</a>, <a href="4-sm.html#SP8_32">&#167;8.32</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_1" class="function-link"><span class="function-syntax">SpatialMap::set_room_position</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_plus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="identifier-syntax">D</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::move_room_to</span><button class="popup" onclick="togglePopup('usagePopup36')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup36">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::move_room_to</span></span>:<br/><a href="4-sm.html#SP34">&#167;34</a>, <a href="4-sm.html#SP8_28">&#167;8.28</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_1" class="function-link"><span class="function-syntax">SpatialMap::set_room_position</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_24" class="function-link"><span class="function-syntax">SpatialMap::move_anything_locked_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_24" class="paragraph-anchor"></a><b>&#167;8.24. Synchronising movements of locked rooms. </b>The next preliminary we need is the implementation of locking. As we've seen,
the source text can instruct us to lock one room so that it lies perfectly
placed with respect to another (in the sense that if there were an exit
between them in that direction then it would have heat 0).
</p>
<p class="commentary">The following is for use after room R has been moved to a new grid position;
it moves anything locked to R (and anything locked to that, and so on) to
corresponding positions.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::move_anything_locked_to</span><button class="popup" onclick="togglePopup('usagePopup37')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup37">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::move_anything_locked_to</span></span>:<br/><a href="4-sm.html#SP8_23">&#167;8.23</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R2</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">shifted</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_24" class="function-link"><span class="function-syntax">SpatialMap::move_anything_locked_to_r</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::move_anything_locked_to_r</span><button class="popup" onclick="togglePopup('usagePopup38')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup38">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::move_anything_locked_to_r</span></span>:<br/><a href="4-sm.html#SP8_25">&#167;8.25</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">shifted</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">shifted</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP11" class="function-link"><span class="function-syntax">SpatialMap::read_slock</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_5" class="function-link"><span class="function-syntax">SpatialMap::direction_as_vector</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_1" class="function-link"><span class="function-syntax">SpatialMap::set_room_position</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_plus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="identifier-syntax">D</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_24" class="function-link"><span class="function-syntax">SpatialMap::move_anything_locked_to_r</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_25" class="paragraph-anchor"></a><b>&#167;8.25. </b>That allows us to define the initial state of placements in a submap.
All rooms begin at (0,0,0), except that locking may offset a few of them
slightly. This runs in \(O(R)\) time.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::lock_positions_in_submap</span><button class="popup" onclick="togglePopup('usagePopup39')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup39">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::lock_positions_in_submap</span></span>:<br/><a href="4-sm.html#SP8_26">&#167;8.26</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">shifted</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_24" class="function-link"><span class="function-syntax">SpatialMap::move_anything_locked_to_r</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_26" class="paragraph-anchor"></a><b>&#167;8.26. Positioning within components. </b>This is much more difficult. It's going to be a matter of minimising the
badness of the configuration, but to talk about it it's convenient to have
a better word than "badness". So the "heat" is a penalty score
calculated at each map connection which keeps track of the badness of local
geometric distortion; thus, lowering the temperature improves the geometry.
We want to reduce the total amount of heat, ideally to absolute zero, but
we also to want to avoid hot-spots.
</p>
<p class="commentary">The worst case for running time here is when the entire map is a single component;
the loop over submaps doesn't therefore add to the running time.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(3) Position the rooms within each component</span><span class="named-paragraph-number">8.26</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">total_accuracy</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">LS</span><span class="plain-syntax"> = </span><a href="1-ia.html#SP7" class="function-link"><span class="function-syntax">Indexing::get_list_of_submaps</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAPS</span><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Laying out component %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_25" class="function-link"><span class="function-syntax">SpatialMap::lock_positions_in_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">); </span><span class="comment-syntax"> </span>\(O(R)\)<span class="comment-syntax"> running time</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP18" class="function-link"><span class="function-syntax">SpatialMap::establish_natural_lengths</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">); </span><span class="comment-syntax"> </span>\(O(R)\)<span class="comment-syntax"> running time</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP24" class="function-link"><span class="function-syntax">SpatialMap::position_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">total_accuracy</span><span class="plain-syntax"> += </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Component %d has final heat %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"\nAll components laid out: total heat %d\n\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">total_accuracy</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Cost: cutpoint choosing %d drognas\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">cutpoint_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Cost: dividing %d drognas\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">division_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Cost: sliding %d drognas\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">slide_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Cost: cooling %d drognas\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">cooling_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Cost: quenching %d drognas\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">quenching_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Cost: diffusion %d drognas\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">diffusion_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Cost: radiation %d drognas\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">radiation_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Cost: explosion %d drognas\n\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">explosion_spending</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. </b>Every spatial relationship has a "length", which is a positive integer.
This is our preferred amount of stretch when laying out the rooms; a
length of 1 means one grid increment, and that's our preference if we
can have it. Initially, all SRs have length 1.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::establish_natural_lengths</span><button class="popup" onclick="togglePopup('usagePopup40')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup40">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::establish_natural_lengths</span></span>:<br/><a href="4-sm.html#SP8_26">&#167;8.26</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">exit_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">exit_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = -1;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. Heat. </b>Before we can get any further with (3), we need to be able to measure heat. For
a submap, it's the sum of its room heats, plus additional heat (and a
lot of it) for each pair of rooms occupying the same grid location. We also
refresh the cached value of the smallest squarely oriented cuboid which
contains the component.
</p>
<p class="commentary">The mapmaker behaves slowly if the collision heat penalty is low enough
that large amounts of heat soaked up from ordinary exits can ever exceed it.
On the other hand, for very large maps with horrible tangles the total number
of collisions can be enormous, and quite high heats are observed; I've seen
temperatures over 165,000,000, so temperatures of 1,000,000,000 are not at
all out of the question. So we will be careful, just on the safe side,
not to overflow a single <span class="extract"><span class="extract-syntax">int</span></span>; we'll cap temperatures except to add a tiny
extra heat so that there is still a slight incentive to remove collisions
even in submaps at this unthinkably hot level.
</p>
<p class="commentary">The FHM magazine website informs me that the current (2010) maximal value of
temperature is <span class="extract"><span class="extract-syntax">CHERYL_COLE</span></span>, but I think I'll call it <span class="extract"><span class="extract-syntax">FUSION_POINT</span></span>.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">OVERLYING_HEAT</span><span class="plain-syntax"> </span><span class="constant-syntax">20</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">COLLISION_HEAT</span><span class="plain-syntax"> </span><span class="constant-syntax">50000</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">FUSION_POINT</span><span class="plain-syntax"> </span><span class="constant-syntax">1000000000</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::heat_sum</span><button class="popup" onclick="togglePopup('usagePopup41')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup41">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::heat_sum</span></span>:<br/><a href="4-sm.html#SP20">&#167;20</a>, <a href="4-sm.html#SP43">&#167;43</a>, <a href="4-sm.html#SP43_1">&#167;43.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">h1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">h2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><span class="identifier-syntax">h1</span><span class="plain-syntax">+</span><span class="identifier-syntax">h2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">FUSION_POINT</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FUSION_POINT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. </b>Finding the heat of a submap runs in \(O(S)\) time, where \(S\) is the number
of rooms in the submap; this is the point of having the incidence cache,
without which it would be \(O(S^2)\). (Even so, we will try to make \(S\) a lot
smaller than \(R\).)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::find_submap_heat</span><button class="popup" onclick="togglePopup('usagePopup42')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup42">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::find_submap_heat</span></span>:<br/><a href="4-sm.html#SP24">&#167;24</a>, <a href="4-sm.html#SP24_1">&#167;24.1</a>, <a href="4-sm.html#SP24_1_1">&#167;24.1.1</a>, <a href="4-sm.html#SP24_1_4">&#167;24.1.4</a>, <a href="4-sm.html#SP32">&#167;32</a>, <a href="4-sm.html#SP35">&#167;35</a>, <a href="4-sm.html#SP35_1">&#167;35.1</a>, <a href="4-sm.html#SP36">&#167;36</a>, <a href="4-sm.html#SP36_1">&#167;36.1</a>, <a href="4-sm.html#SP38">&#167;38</a>, <a href="4-sm.html#SP38_1_1">&#167;38.1.1</a>, <a href="4-sm.html#SP8_28">&#167;8.28</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP10" class="function-link"><span class="function-syntax">Geometry::empty_cuboid</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">SpatialMap::heat_sum</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">heat</span><span class="plain-syntax">, </span><a href="4-sm.html#SP21" class="function-link"><span class="function-syntax">SpatialMap::find_room_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP10" class="function-link"><span class="function-syntax">Geometry::adjust_cuboid</span></a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">), </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">collisions</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">superpositions</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">collisions</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">1000</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">SpatialMap::heat_sum</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">heat</span><span class="plain-syntax">, </span><span class="constant-syntax">1000</span><span class="plain-syntax">*</span><span class="constant-syntax">COLLISION_HEAT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">collisions</span><span class="plain-syntax"> -= </span><span class="constant-syntax">1000</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">SpatialMap::heat_sum</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">heat</span><span class="plain-syntax">, </span><span class="identifier-syntax">collisions</span><span class="plain-syntax">*</span><span class="constant-syntax">COLLISION_HEAT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">heat</span><span class="plain-syntax"> == </span><span class="constant-syntax">FUSION_POINT</span><span class="plain-syntax">) </span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><span class="constant-syntax">FUSION_POINT</span><span class="plain-syntax"> + </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">superpositions</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax"> = </span><span class="identifier-syntax">heat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. </b>The total heat for a room is in turn the sum of its exit heats. This runs
in constant time.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::find_room_heat</span><button class="popup" onclick="togglePopup('usagePopup43')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup43">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::find_room_heat</span></span>:<br/><a href="4-sm.html#SP20">&#167;20</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) </span><span class="identifier-syntax">h</span><span class="plain-syntax"> += </span><a href="4-sm.html#SP22" class="function-link"><span class="function-syntax">SpatialMap::find_exit_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b>So now we come to it: measuring the heat of an exit, which is a matter of
how much geometric distortion it has in the current layout. This is based
primarily on the angular divergence in direction between the known exit
direction and the grid direction, and only secondarily on distance
anomalies, because when the user typed "the Field is east of the River"
no particular distance was implied. As with Harry Beck's London Underground
map (1931), we may be constrained to use only about eight possible angles but
nevertheless care more about angle than length.
</p>
<p class="commentary">Note that an exit in the lattice (i.e., not IN or OUT) which joins two
different rooms can only have heat 0 if the destination room lies exactly
at the optimal grid offset from the origin room. (In the sense that you'd
expect the room north from \((0,0,0)\) to be at \((0,1,0)\), and so on.) A
component therefore has a total heat of 0 if and only if it has been
aligned perfectly on a grid such that all exits are optimal.
</p>
<p class="commentary">This too runs in constant time.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">ANGULAR_MULTIPLIER</span><span class="plain-syntax"> </span><span class="constant-syntax">50</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::find_exit_heat</span><button class="popup" onclick="togglePopup('usagePopup44')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup44">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::find_exit_heat</span></span>:<br/><a href="4-sm.html#SP21">&#167;21</a>, <a href="4-sm.html#SP33_1">&#167;33.1</a>, <a href="4-sm.html#SP35">&#167;35</a>, <a href="4-sm.html#SP37">&#167;37</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">to</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> if there's no exit this way, there's no heat</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">from</span><span class="plain-syntax"> == </span><span class="identifier-syntax">to</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> an exit from a room to itself doesn't show on the map</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP8_9" class="function-link"><span class="function-syntax">SpatialMap::direction_is_along_lattice</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> IN, OUT generate no heat</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_minus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">to</span><span class="plain-syntax">), </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sg.html#SP6" class="function-link"><span class="function-syntax">Geometry::vec_eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="identifier-syntax">Zero_vector</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">COLLISION_HEAT</span><span class="plain-syntax">; </span><span class="comment-syntax"> the two rooms have collided!</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_5" class="function-link"><span class="function-syntax">SpatialMap::direction_as_vector</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">distance_distortion</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP8" class="function-link"><span class="function-syntax">Geometry::vec_length_squared</span></a><span class="plain-syntax">(</span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_minus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">distance_distortion</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> perfect placement</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">angular_distortion</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) (</span><span class="constant-syntax">ANGULAR_MULTIPLIER</span><span class="plain-syntax">*</span><a href="4-sg.html#SP9" class="function-link"><span class="function-syntax">Geometry::vec_angular_separation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">overlying_penalty</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">angular_distortion</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><a href="4-sg.html#SP6" class="function-link"><span class="function-syntax">Geometry::vec_eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">Zero_vector</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_plus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">n</span><span class="plain-syntax">++ &lt; </span><span class="constant-syntax">20</span><span class="plain-syntax">) &amp;&amp; (</span><a href="4-sg.html#SP6" class="function-link"><span class="function-syntax">Geometry::vec_eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">to</span><span class="plain-syntax">)) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">SpatialMap::occupied_in_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">overlying_penalty</span><span class="plain-syntax"> += </span><span class="constant-syntax">OVERLYING_HEAT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_plus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">angular_distortion</span><span class="plain-syntax"> + </span><span class="identifier-syntax">distance_distortion</span><span class="plain-syntax"> + </span><span class="identifier-syntax">overlying_penalty</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. </b>The following simply tests whether a link is correctly aligned, in that
the destination room lies along a multiple of the exit vector from the
origin. In effect, it tests whether <span class="extract"><span class="extract-syntax">angular_distortion</span></span> is zero.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::exit_aligned</span><button class="popup" onclick="togglePopup('usagePopup45')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup45">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::exit_aligned</span></span>:<br/><a href="4-sm.html#SP38">&#167;38</a>, <a href="4-sm.html#SP38_1">&#167;38.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">to</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> at any rate, not misaligned</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">from</span><span class="plain-syntax"> == </span><span class="identifier-syntax">to</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> ditto</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP8_9" class="function-link"><span class="function-syntax">SpatialMap::direction_is_along_lattice</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> IN, OUT are always aligned</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_minus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">to</span><span class="plain-syntax">), </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sg.html#SP6" class="function-link"><span class="function-syntax">Geometry::vec_eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="identifier-syntax">Zero_vector</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">; </span><span class="comment-syntax"> bad, but not for alignment reasons</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_5" class="function-link"><span class="function-syntax">SpatialMap::direction_as_vector</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">angular_distortion</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) (</span><span class="constant-syntax">ANGULAR_MULTIPLIER</span><span class="plain-syntax">*</span><a href="4-sg.html#SP9" class="function-link"><span class="function-syntax">Geometry::vec_angular_separation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">angular_distortion</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. Subdividing our submap. </b>Any remotely good algorithm for this task will have a dangerous running time
if let loose on the entire map, and in any case, the entirety may have such
a complex layout that it defeats our tactics. So we need a divide-and-rule
method; one which cuts the map into two pieces, positions each piece, and
then glues them back together again.
</p>
<p class="commentary">We will eventually use five tactics: cooling, quenching, diffusion,
radiation and explosion. Cooling is quick and useful, so we'll try that
first even before looking for subdivisions.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unique_Z_number</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::position_submap</span><button class="popup" onclick="togglePopup('usagePopup46')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup46">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::position_submap</span></span>:<br/><a href="4-sm.html#SP8_26">&#167;8.26</a>, <a href="4-sm.html#SP24_1_3">&#167;24.1.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">initial_heat</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax"> = </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"\nPOSITIONING submap %d: initial heat %d"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">": nothing to do"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Log::aspect_switched_on</span><span class="plain-syntax">(</span><span class="constant-syntax">SPATIAL_MAP_DA</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">n</span><span class="plain-syntax">++) % </span><span class="constant-syntax">8</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">" %S"</span><span class="plain-syntax">, </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP32" class="function-link"><span class="function-syntax">SpatialMap::cool_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP24_1" class="named-paragraph-link"><span class="named-paragraph">Attempt to divide the current submap in two</span><span class="named-paragraph-number">24.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"\nPOSITIONING submap %d done: cooled by %d to %d "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"at cost of %d drognas\n\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">initial_heat</span><span class="plain-syntax"> - </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP24_1" class="paragraph-anchor"></a><b>&#167;24.1. </b>We will look for a way to divide the rooms up into two subsets, allocating
each subset a unique zone number. (We must remember that all of this code is
running recursively.)
</p>
<p class="commentary">There are three cases: sometimes the <span class="extract"><span class="extract-syntax">SpatialMap::work_out_optimal_cutpoint</span></span> function
recommends cutting a single spatial relationship, from <span class="extract"><span class="extract-syntax">div_F1</span></span> to <span class="extract"><span class="extract-syntax">div_T1</span></span>,
and sometimes it recommends cutting a pair. Then again, sometimes it finds
no good cutpoint.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Attempt to divide the current submap in two</span><span class="named-paragraph-number">24.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Z1_number</span><span class="plain-syntax"> = </span><span class="identifier-syntax">unique_Z_number</span><span class="plain-syntax">++, </span><span class="identifier-syntax">Z2_number</span><span class="plain-syntax"> = </span><span class="identifier-syntax">unique_Z_number</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">div_F1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">div_T1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">div_dir1</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">div_F2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">div_T2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">div_dir2</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax"> = </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">found</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP25" class="function-link"><span class="function-syntax">SpatialMap::work_out_optimal_cutpoint</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">div_F1</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">div_T1</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">div_dir1</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> &amp;</span><span class="identifier-syntax">div_F2</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">div_T2</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">div_dir2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">cutpoint_spending</span><span class="plain-syntax"> += </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">found</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP24_1_2" class="named-paragraph-link"><span class="named-paragraph">Set the zone numbers throughout the two soon-to-be zones</span><span class="named-paragraph-number">24.1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP24_1_3" class="named-paragraph-link"><span class="named-paragraph">Divide the submap into zones, recurse to position those, then merge back</span><span class="named-paragraph-number">24.1.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP24_1_4" class="named-paragraph-link"><span class="named-paragraph">Slide the two former zones together along the F1-to-T1 line, minimising heat</span><span class="named-paragraph-number">24.1.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><a href="4-sm.html#SP38" class="function-link"><span class="function-syntax">SpatialMap::radiate_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP24_1_1" class="named-paragraph-link"><span class="named-paragraph">Position this indivisible component</span><span class="named-paragraph-number">24.1.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP24">&#167;24</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_1_1" class="paragraph-anchor"></a><b>&#167;24.1.1. </b>When we can't divide, we use our remaining three tactics, stopping if the
submap should reach absolute zero:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Position this indivisible component</span><span class="named-paragraph-number">24.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP35" class="function-link"><span class="function-syntax">SpatialMap::quench_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP36" class="function-link"><span class="function-syntax">SpatialMap::diffuse_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP35" class="function-link"><span class="function-syntax">SpatialMap::quench_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP38" class="function-link"><span class="function-syntax">SpatialMap::radiate_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) &gt;= </span><span class="constant-syntax">COLLISION_HEAT</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_28" class="function-link"><span class="function-syntax">SpatialMap::explode_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP24_1">&#167;24.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_1_2" class="paragraph-anchor"></a><b>&#167;24.1.2. </b>Supposing we can divide, though, we need to set zone numbers throughout
the submap, and the procedure is different depending on whether we're
dividing at one relationship F1-to-T1 or at two, F1-to-T1 and F2-to-T2.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Set the zone numbers throughout the two soon-to-be zones</span><span class="named-paragraph-number">24.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Z1_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">Z2_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">div_F2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">predivision_spending</span><span class="plain-syntax"> = </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP29" class="function-link"><span class="function-syntax">SpatialMap::divide_into_zones_twocut</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">div_F1</span><span class="plain-syntax">, </span><span class="identifier-syntax">div_T1</span><span class="plain-syntax">, </span><span class="identifier-syntax">div_F2</span><span class="plain-syntax">, </span><span class="identifier-syntax">div_T2</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Z1_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">Z2_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="identifier-syntax">Z1_number</span><span class="plain-syntax">) </span><span class="identifier-syntax">Z1_count</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="identifier-syntax">Z2_number</span><span class="plain-syntax">) </span><span class="identifier-syntax">Z2_count</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Making a double cut: %S %s to %S and %S %s to %S at cost %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">div_F1</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_12" class="function-link"><span class="function-syntax">SpatialMap::usual_Inform_direction_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">div_dir1</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">div_T1</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">div_F2</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_12" class="function-link"><span class="function-syntax">SpatialMap::usual_Inform_direction_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">div_dir2</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">div_T2</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">predivision_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">division_spending</span><span class="plain-syntax"> += </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">predivision_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">predivision_spending</span><span class="plain-syntax"> = </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP27" class="function-link"><span class="function-syntax">SpatialMap::divide_into_zones_onecut</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">div_F1</span><span class="plain-syntax">, </span><span class="identifier-syntax">div_T1</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> &amp;</span><span class="identifier-syntax">Z1_count</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">Z2_count</span><span class="plain-syntax">, </span><span class="identifier-syntax">Z1_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">Z2_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Making a single cut: %S %s to %S at cost %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">div_F1</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_12" class="function-link"><span class="function-syntax">SpatialMap::usual_Inform_direction_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">div_dir1</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">div_T1</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">predivision_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">division_spending</span><span class="plain-syntax"> += </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">predivision_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"This produces two zones of sizes %d and %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Z1_count</span><span class="plain-syntax">, </span><span class="identifier-syntax">Z2_count</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP24_1">&#167;24.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_1_3" class="paragraph-anchor"></a><b>&#167;24.1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Divide the submap into zones, recurse to position those, then merge back</span><span class="named-paragraph-number">24.1.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Zone1</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP12" class="function-link"><span class="function-syntax">SpatialMap::new_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Zone2</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP12" class="function-link"><span class="function-syntax">SpatialMap::new_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_19" class="function-link"><span class="function-syntax">SpatialMap::create_submaps_from_zones</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">Z1_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">Zone1</span><span class="plain-syntax">, </span><span class="identifier-syntax">Z2_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">Zone2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Zone 1 becomes submap %d; zone 2 becomes submap %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Zone1</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">Zone2</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP24" class="function-link"><span class="function-syntax">SpatialMap::position_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Zone1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP24" class="function-link"><span class="function-syntax">SpatialMap::position_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Zone2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_20" class="function-link"><span class="function-syntax">SpatialMap::create_zones_from_submaps</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">Z1_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">Zone1</span><span class="plain-syntax">, </span><span class="identifier-syntax">Z2_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">Zone2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Destroying submaps %d and %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Zone1</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">Zone2</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_17" class="function-link"><span class="function-syntax">SpatialMap::destroy_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Zone1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_17" class="function-link"><span class="function-syntax">SpatialMap::destroy_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Zone2</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP24_1">&#167;24.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_1_4" class="paragraph-anchor"></a><b>&#167;24.1.4. </b>The zone-1 rooms are now correctly placed with respect to each other, and
vice versa, but we might have a horrendous breakage where the two sets of
rooms meet. We need to rejoin them, and we do this by stretching the
F1-to-T1 line segment to that length which minimises the total heat of
the submap. For a single cut, this is clearly the smallest length such
that there's no collision between old zone-1 and old zone-2 rooms.
</p>
<p class="commentary">The worst case is a configuration like so:
</p>
<blockquote>
<p>X is west of Y. X1 is northeast of X. X2 is northeast of X. Y1 is northwest of Y. Y2 is northwest of Y1.</p>
</blockquote>
<p class="commentary">We've cut between X and Y. To give clearance so that X2 and Y2 do not collide,
the new length X to Y needs to be 5.
</p>
<p class="commentary">However, it's computationally too expensive to check every possible length
as high as that: it would run in \(O(S^2)\) time, and we must remember that
this is the divide-and-rule code running on even the largest submaps, so
that this is effectively an \(O(R^2)\) algorithm. On a 300-room example source
text (the entire London Underground map, zones 1 to 7) this results in
sliding taking up about 80 percent of our time, which is unacceptable.
</p>
<p class="commentary">We therefore cap the length once we have reduced below the collision penalty.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">CAP_ON_SLIDE_LENGTHS</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Slide the two former zones together along the F1-to-T1 line, minimising heat</span><span class="named-paragraph-number">24.1.4</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">preslide_spending</span><span class="plain-syntax"> = </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">Axis</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_5" class="function-link"><span class="function-syntax">SpatialMap::direction_as_vector</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">div_dir1</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">worst_case_length</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) </span><span class="identifier-syntax">worst_case_length</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">worst_case_length</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">coolest_L</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">coolest_temperature</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">L</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">worst_case_length</span><span class="plain-syntax">; </span><span class="identifier-syntax">L</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP31" class="function-link"><span class="function-syntax">SpatialMap::save_component_positions</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP24_1_4_1" class="named-paragraph-link"><span class="named-paragraph">Displace zone 2 relative to zone 1</span><span class="named-paragraph-number">24.1.4.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">h</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">coolest_temperature</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">coolest_temperature</span><span class="plain-syntax"> == -1)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">coolest_temperature</span><span class="plain-syntax"> = </span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">coolest_L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP31" class="function-link"><span class="function-syntax">SpatialMap::restore_component_positions</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">coolest_temperature</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">coolest_temperature</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">COLLISION_HEAT</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> == </span><span class="constant-syntax">CAP_ON_SLIDE_LENGTHS</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Optimal axis length for cut-exit is %d (heat %d), at cost %d.\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">coolest_L</span><span class="plain-syntax">, </span><span class="identifier-syntax">coolest_temperature</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">preslide_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">slide_spending</span><span class="plain-syntax"> += </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">preslide_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">coolest_L</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP24_1_4_1" class="named-paragraph-link"><span class="named-paragraph">Displace zone 2 relative to zone 1</span><span class="named-paragraph-number">24.1.4.1</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP24_1">&#167;24.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP24_1_4_1" class="paragraph-anchor"></a><b>&#167;24.1.4.1. </b>Here we slide rooms which came from Zone 2 so that they retain their
positions with respect to each other, and therefore to T1, and so that T1
is placed correctly aligned along the axis from F1 with length L.
</p>
<p class="commentary">Because there can never be locks across zone boundaries, this process
can't break a lock between two rooms.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Displace zone 2 relative to zone 1</span><span class="named-paragraph-number">24.1.4.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">div_F1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">exit_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">div_dir1</span><span class="plain-syntax">] = </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_plus</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_scale</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">Axis</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_minus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">div_F1</span><span class="plain-syntax">), </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">div_T1</span><span class="plain-syntax">)));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Z2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">Z2</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Z2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="identifier-syntax">Z2_number</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_23" class="function-link"><span class="function-syntax">SpatialMap::translate_room</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Z2</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP24_1_4">&#167;24.1.4</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>&#167;25. Finding how to divide. </b>That completes the logic for how we divide and conquer the submaps, except,
of course, that some of the critical steps weren't spelled out. We do that
now. First, the code to find good cutpoint(s): map connection(s) which, if
removed, would divide the submap efficiently. We prefer single cuts if
possible, but can live with double cuts; we want as evenly spread a
division as possible. (The "spread" is the difference in room count
of the larger zone compared to the smaller zone; we want to minimise this.)
</p>
<p class="commentary">Here is the basic idea. We will recursively spread a generation count out
into the submap, with the first room (<span class="extract"><span class="extract-syntax">first</span></span> below) belonging to generation 1.
We'll use the <span class="extract"><span class="extract-syntax">zone</span></span> field to store this, since it's an integer attached to
each room which isn't yet in use. <span class="extract"><span class="extract-syntax">SpatialMap::assign_generation_count</span></span> is recursively
called so that it visits each room exactly once, and increases the generation
on each call. Thus a line of rooms from <span class="extract"><span class="extract-syntax">first</span></span> would have generations 1, 2,
3, ... When <span class="extract"><span class="extract-syntax">SpatialMap::assign_generation_count</span></span> finds a connection from its current
position to a room with a lower generation, we say that there's a "contact".
</p>
<p class="commentary">What makes the function so effective is that it returns a great deal of data
about the high-spots of the history after it was called. The mechanism for
this, though, is that the caller has to set up a pile of arrays, and then
pass pointers to <span class="extract"><span class="extract-syntax">SpatialMap::assign_generation_count</span></span>; on its exit, the arrays are
then populated with answers.
</p>
<p class="commentary">This calculation runs in \(O(S)\) time, where \(S\) is the number of rooms in
the submap. It's guaranteed to find the optimal single cut, if one exists;
it's not guaranteed to find the optimal double cut &mdash; I suspect this is
not possible in \(O(S)\) running time, though possibly in \(O(S\log S)\) &mdash; but
in any case we have heuristic reasons why we don't always want the optimal
double cut. What can be said is that we at least try to find good spreads,
usually succeed in practice, and are guaranteed to find at least one double
cut if any exists.
</p>
<p class="commentary">The guarantees are void in a small number of cases where locks have been
applied: for instance, if the entire submap is locked together, nothing can
ever be cut. Should that happen, the user will find that the map-maker may
run slowly; it's his own fault.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">EXPLORATION_RECORDS</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax"> </span><span class="comment-syntax"> how much we keep track of</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">BEST_ONECUT_ER</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax"> </span><span class="comment-syntax"> what's the best-known single link to cut?</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">BEST_PARALLEL_TWOCUT_ER</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> </span><span class="comment-syntax"> what's the best-known pair of links equal in direction?</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">BEST_TWOCUT_ER</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax"> </span><span class="comment-syntax"> and in general?</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax"> </span><span class="comment-syntax"> a term to be explained below</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::work_out_optimal_cutpoint</span><button class="popup" onclick="togglePopup('usagePopup47')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup47">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::work_out_optimal_cutpoint</span></span>:<br/><a href="4-sm.html#SP24_1">&#167;24.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">to</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">way</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">from2</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">to2</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">way2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">size</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP25_1" class="named-paragraph-link"><span class="named-paragraph">Find the size of and first room in the submap, and give all rooms generation 0</span><span class="named-paragraph-number">25.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">first</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">best_spread</span><span class="plain-syntax">[</span><span class="constant-syntax">EXPLORATION_RECORDS</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">best_from1</span><span class="plain-syntax">[</span><span class="constant-syntax">EXPLORATION_RECORDS</span><span class="plain-syntax">], *</span><span class="identifier-syntax">best_to1</span><span class="plain-syntax">[</span><span class="constant-syntax">EXPLORATION_RECORDS</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">best_dir1</span><span class="plain-syntax">[</span><span class="constant-syntax">EXPLORATION_RECORDS</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">best_from2</span><span class="plain-syntax">[</span><span class="constant-syntax">EXPLORATION_RECORDS</span><span class="plain-syntax">], *</span><span class="identifier-syntax">best_to2</span><span class="plain-syntax">[</span><span class="constant-syntax">EXPLORATION_RECORDS</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">best_dir2</span><span class="plain-syntax">[</span><span class="constant-syntax">EXPLORATION_RECORDS</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">outer_contact_generation</span><span class="plain-syntax">[</span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">], </span><span class="identifier-syntax">outer_contact_dir</span><span class="plain-syntax">[</span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outer_contact_from</span><span class="plain-syntax">[</span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">], *</span><span class="identifier-syntax">outer_contact_to</span><span class="plain-syntax">[</span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP25_2" class="named-paragraph-link"><span class="named-paragraph">Initialise all this cutpoint search workspace</span><span class="named-paragraph-number">25.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP26" class="function-link"><span class="function-syntax">SpatialMap::assign_generation_count</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">first</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">size</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_spread</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_from1</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_to1</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_dir1</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_from2</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_to2</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_dir2</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outer_contact_generation</span><span class="plain-syntax">, </span><span class="identifier-syntax">outer_contact_from</span><span class="plain-syntax">, </span><span class="identifier-syntax">outer_contact_to</span><span class="plain-syntax">, </span><span class="identifier-syntax">outer_contact_dir</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP25_3" class="named-paragraph-link"><span class="named-paragraph">Look at the results and return connections to cut, if any look good enough</span><span class="named-paragraph-number">25.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP25_1" class="paragraph-anchor"></a><b>&#167;25.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Find the size of and first room in the submap, and give all rooms generation 0</span><span class="named-paragraph-number">25.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> i.e., not yet given a generation</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">size</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">first</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">size</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP25">&#167;25</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP25_2" class="paragraph-anchor"></a><b>&#167;25.2. </b>See below.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialise all this cutpoint search workspace</span><span class="named-paragraph-number">25.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outer_contact_generation</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = -1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outer_contact_from</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">outer_contact_to</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">outer_contact_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = -1;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">EXPLORATION_RECORDS</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_spread</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">size</span><span class="plain-syntax">+1; </span><span class="comment-syntax"> an impossibly high value</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_from1</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">best_to1</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">best_dir1</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = -1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_from2</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">best_to2</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">best_dir2</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = -1;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP25">&#167;25</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP25_3" class="paragraph-anchor"></a><b>&#167;25.3. </b>Suppose the larger and smaller zones have sizes \(X\) and \(Y\). Then clearly
\(X+Y = T\), where \(T\) is the total number of rooms (called <span class="extract"><span class="extract-syntax">size</span></span> below). The
spread is by definition \(S = X-Y\). Therefore the size of the smaller zone
is given by \(Y = (T-S)/2\). We use this to ensure that the division is worth
the time it takes.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MIN_ONECUT_ZONE_SIZE</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">MIN_TWOCUT_ZONE_SIZE</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Look at the results and return connections to cut, if any look good enough</span><span class="named-paragraph-number">25.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">size</span><span class="plain-syntax"> - </span><span class="identifier-syntax">best_spread</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_ONECUT_ER</span><span class="plain-syntax">])/2 &gt;= </span><span class="constant-syntax">MIN_ONECUT_ZONE_SIZE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_from1</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_ONECUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_to1</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_ONECUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">way</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_dir1</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_ONECUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">size</span><span class="plain-syntax"> - </span><span class="identifier-syntax">best_spread</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_PARALLEL_TWOCUT_ER</span><span class="plain-syntax">])/2 &gt;= </span><span class="constant-syntax">MIN_TWOCUT_ZONE_SIZE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_from1</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_PARALLEL_TWOCUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_to1</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_PARALLEL_TWOCUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">way</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_dir1</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_PARALLEL_TWOCUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">from2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_from2</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_PARALLEL_TWOCUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">to2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_to2</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_PARALLEL_TWOCUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">way2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_dir2</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_PARALLEL_TWOCUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">size</span><span class="plain-syntax"> - </span><span class="identifier-syntax">best_spread</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_TWOCUT_ER</span><span class="plain-syntax">])/2 &gt;= </span><span class="constant-syntax">MIN_TWOCUT_ZONE_SIZE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_from1</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_TWOCUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_to1</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_TWOCUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">way</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_dir1</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_TWOCUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">from2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_from2</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_TWOCUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">to2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_to2</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_TWOCUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">way2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">best_dir2</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_TWOCUT_ER</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP25">&#167;25</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26" class="paragraph-anchor"></a><b>&#167;26. </b>The return value of <span class="extract"><span class="extract-syntax">SpatialMap::assign_generation_count</span></span> is the number of rooms which
it, and its recursive incarnations, visit in total. But as noted above, it
also records data in the arrays it is passed pointers to; that's what the
last eleven arguments are for. Otherwise: <span class="extract"><span class="extract-syntax">at</span></span> is the room we are currently at,
and <span class="extract"><span class="extract-syntax">from</span></span> is the one we've just come from, or <span class="extract"><span class="extract-syntax">NULL</span></span> if this is the opening
call; <span class="extract"><span class="extract-syntax">size</span></span> is the number of rooms in the submap.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::assign_generation_count</span><button class="popup" onclick="togglePopup('usagePopup48')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup48">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::assign_generation_count</span></span>:<br/><a href="4-sm.html#SP25">&#167;25</a>, <a href="4-sm.html#SP26_2">&#167;26.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">size</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">best_spread</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">best_from1</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">best_to1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">best_dir1</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">best_from2</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">best_to2</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">best_dir2</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">contact_generation</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">contact_from</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">contact_to</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">contact_dir</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rooms_visited</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">generation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">at</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">locking_to_neighbours</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP11" class="function-link"><span class="function-syntax">SpatialMap::read_slock</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP26_1" class="named-paragraph-link"><span class="named-paragraph">Exclude generating this way if we don't need to</span><span class="named-paragraph-number">26.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP26_2" class="named-paragraph-link"><span class="named-paragraph">Actually generate this way</span><span class="named-paragraph-number">26.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">locking_to_neighbours</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP26_1" class="named-paragraph-link"><span class="named-paragraph">Exclude generating this way if we don't need to</span><span class="named-paragraph-number">26.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP26_2" class="named-paragraph-link"><span class="named-paragraph">Actually generate this way</span><span class="named-paragraph-number">26.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rooms_visited</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP26_1" class="paragraph-anchor"></a><b>&#167;26.1. </b>We eliminate: routes from the current room to itself, or back the way
we just came to get here; routes to rooms with equal or higher generation
counts than the current one &mdash; those are places already visited; and
routes to rooms with lower generations &mdash; but those are contacts, so
we may need to record them before moving on.
</p>
<p class="commentary">What this leaves is cases where <span class="extract"><span class="extract-syntax">T_generation</span></span> is zero, that is, where
<span class="extract"><span class="extract-syntax">T</span></span> is a room with no generation count. This ensures <span class="extract"><span class="extract-syntax">SpatialMap::assign_generation_count</span></span>
is called at most once on each room.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Exclude generating this way if we don't need to</span><span class="named-paragraph-number">26.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">T</span><span class="plain-syntax"> == </span><span class="identifier-syntax">at</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">T</span><span class="plain-syntax"> == </span><span class="identifier-syntax">from</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">T_generation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T_generation</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">generation</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">T_generation</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T_generation</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">generation</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">observed_generation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">T_generation</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">observed_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">at</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">observed_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">T</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">observed_dir</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP26_1_1" class="named-paragraph-link"><span class="named-paragraph">Contact hasss been made</span><span class="named-paragraph-number">26.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP26">&#167;26</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP26_2" class="paragraph-anchor"></a><b>&#167;26.2. </b>At this point, it's as if we have been sent out to explore a labyrinth.
One problem we have is that we can't see what lies beyond here, with our
own eyes. "The underground rooms I can speak of only from report, because
the Egyptians in charge refused to let me see them, as they contain the
tombs of the kings who built the labyrinth, and also the tombs of the
sacred crocodiles" (Herodotus). So we must send out explorers who will
report back, but that costs us resources. "One doctrine called for
guarding every intersection such as this one. But I had already used two
men to guard our escape hole; if I left 10 per cent of my force at each
intersection, mighty soon I would be ten-percented to death" (Heinlein).
We must be careful of men, too: we can't afford to send out explorers
indefinitely because the running time and stack consumption would then be
prohibitive. The traditional approach is to unwind a ball of wool to avoid
going around in circles, but we'll instead use the generation counts &mdash; we
might imagine writing these on the ground everywhere we go.
</p>
<p class="commentary">So let us think of ourselves as dividing the party, and sending out a team of
explorers across the bridge from <span class="extract"><span class="extract-syntax">at</span></span> to <span class="extract"><span class="extract-syntax">T</span></span>, telling them to explore every
possible avenue, and record any contacts they make with the world we
already know about. We will wait here until they get back, and ask them how
many new places they managed to visit. Maybe there's a whole world over
there, maybe just a broom cupboard.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Actually generate this way</span><span class="named-paragraph-number">26.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">inner_contact_generation</span><span class="plain-syntax">[</span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">], </span><span class="identifier-syntax">inner_contact_dir</span><span class="plain-syntax">[</span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inner_contact_from</span><span class="plain-syntax">[</span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">], *</span><span class="identifier-syntax">inner_contact_to</span><span class="plain-syntax">[</span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP26_2_1" class="named-paragraph-link"><span class="named-paragraph">Give the new team of explorers a fresh clipboard</span><span class="named-paragraph-number">26.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="identifier-syntax">generation</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rooms_explored_in_the_beyond</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP26" class="function-link"><span class="function-syntax">SpatialMap::assign_generation_count</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">size</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_spread</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_from1</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_to1</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_dir1</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_from2</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_to2</span><span class="plain-syntax">, </span><span class="identifier-syntax">best_dir2</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inner_contact_generation</span><span class="plain-syntax">, </span><span class="identifier-syntax">inner_contact_from</span><span class="plain-syntax">, </span><span class="identifier-syntax">inner_contact_to</span><span class="plain-syntax">, </span><span class="identifier-syntax">inner_contact_dir</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rooms_visited</span><span class="plain-syntax"> += </span><span class="identifier-syntax">rooms_explored_in_the_beyond</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP26_2_2" class="named-paragraph-link"><span class="named-paragraph">Copy interesting items from the returning team's clipboard to ours</span><span class="named-paragraph-number">26.2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">locking_to_neighbours</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP26_2_3" class="named-paragraph-link"><span class="named-paragraph">Consider this link as a potential cut-position</span><span class="named-paragraph-number">26.2.3</span></a></span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP26">&#167;26</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP26_2_1" class="paragraph-anchor"></a><b>&#167;26.2.1. </b>Each fresh team of explorers gets a fresh clipboard on which to record what
they see &mdash; hence the new set of <span class="extract"><span class="extract-syntax">inner_contact_*</span></span> arrays. (They don't get
individual copies of the <span class="extract"><span class="extract-syntax">best_*</span></span> arrays, though &mdash; that's the point of these;
they're shared in common among all of the explorers.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Give the new team of explorers a fresh clipboard</span><span class="named-paragraph-number">26.2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inner_contact_generation</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = -1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">inner_contact_from</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">inner_contact_to</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">inner_contact_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = -1;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP26_2">&#167;26.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_2_2" class="paragraph-anchor"></a><b>&#167;26.2.2. </b>When the explorers get back, tired but happy, we look at their clipboard,
and see if those contacts excite us too &mdash; which they may not, because what
seemed to them a rediscovery might not seem that way to us; they've seen
more of the world than we have. So we copy their contacts onto our own
clipboard only if they are contacts to places we know about, too.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Copy interesting items from the returning team's clipboard to ours</span><span class="named-paragraph-number">26.2.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">observed_generation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inner_contact_generation</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">observed_generation</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">observed_generation</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">generation</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">observed_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inner_contact_from</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">observed_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inner_contact_to</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">observed_dir</span><span class="plain-syntax"> = </span><span class="identifier-syntax">inner_contact_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP26_1_1" class="named-paragraph-link"><span class="named-paragraph">Contact hasss been made</span><span class="named-paragraph-number">26.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP26_2">&#167;26.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_2_3" class="paragraph-anchor"></a><b>&#167;26.2.3. </b>Our clipboard contains a short list of observed contacts, sorted with
lowest observed generation first. (If more contacts are observed than will
fit on the clipboard, they're thrown away.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Consider this link as a potential cut-position</span><span class="named-paragraph-number">26.2.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_contacts_found</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">inner_contact_generation</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">no_contacts_found</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">no_contacts_found</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">spread</span><span class="plain-syntax"> = </span><span class="identifier-syntax">size</span><span class="plain-syntax"> - </span><span class="constant-syntax">2</span><span class="plain-syntax">*</span><span class="identifier-syntax">rooms_explored_in_the_beyond</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">spread</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">spread</span><span class="plain-syntax"> = -</span><span class="identifier-syntax">spread</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">no_contacts_found</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP26_2_3_1" class="named-paragraph-link"><span class="named-paragraph">Cutting on this link would disconnect the submap</span><span class="named-paragraph-number">26.2.3.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">no_contacts_found</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP26_2_3_2" class="named-paragraph-link"><span class="named-paragraph">Cutting on this link and the contact found would disconnect the submap</span><span class="named-paragraph-number">26.2.3.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP26_2">&#167;26.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_2_3_1" class="paragraph-anchor"></a><b>&#167;26.2.3.1. </b>If exploration outward from here never resulted in a contact with known
territory, then cutting this link strands the far side as a disconnected zone.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Cutting on this link would disconnect the submap</span><span class="named-paragraph-number">26.2.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">spread</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">best_spread</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_ONECUT_ER</span><span class="plain-syntax">]) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_spread</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_ONECUT_ER</span><span class="plain-syntax">] = </span><span class="identifier-syntax">spread</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_from1</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_ONECUT_ER</span><span class="plain-syntax">] = </span><span class="identifier-syntax">at</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_to1</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_ONECUT_ER</span><span class="plain-syntax">] = </span><span class="identifier-syntax">T</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_dir1</span><span class="plain-syntax">[</span><span class="constant-syntax">BEST_ONECUT_ER</span><span class="plain-syntax">] = </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP26_2_3">&#167;26.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_2_3_2" class="paragraph-anchor"></a><b>&#167;26.2.3.2. </b>If exploration found just one contact, then that link, plus this one, would
if both removed cut off the far side. We have to be careful that we never
cut along locks, only along map connections; we know that the <span class="extract"><span class="extract-syntax">at</span></span> to <span class="extract"><span class="extract-syntax">T</span></span>
link isn't a lock, because we never come here in <span class="extract"><span class="extract-syntax">locking_to_neighbours</span></span>
mode. But we don't know that for the observed contact, so we check by hand.
</p>
<p class="commentary">The division is "parallel" if the two links are in the same or opposite
direction, like the two long tubes of a trombone; this makes it easier to
slide the zones to and fro without angular distortion, so we prefer it if
we can get it.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Cutting on this link and the contact found would disconnect the submap</span><span class="named-paragraph-number">26.2.3.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP11" class="function-link"><span class="function-syntax">SpatialMap::read_slock</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inner_contact_from</span><span class="plain-syntax">[0], </span><span class="identifier-syntax">inner_contact_dir</span><span class="plain-syntax">[0], </span><span class="identifier-syntax">session</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> == </span><span class="identifier-syntax">inner_contact_to</span><span class="plain-syntax">[0]) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">r</span><span class="plain-syntax"> = </span><span class="constant-syntax">BEST_TWOCUT_ER</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">inner_contact_dir</span><span class="plain-syntax">[0] == </span><span class="identifier-syntax">i</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">inner_contact_dir</span><span class="plain-syntax">[0] == </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">r</span><span class="plain-syntax"> = </span><span class="constant-syntax">BEST_PARALLEL_TWOCUT_ER</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">spread</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">best_spread</span><span class="plain-syntax">[</span><span class="identifier-syntax">r</span><span class="plain-syntax">]) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_spread</span><span class="plain-syntax">[</span><span class="identifier-syntax">r</span><span class="plain-syntax">] = </span><span class="identifier-syntax">spread</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_from1</span><span class="plain-syntax">[</span><span class="identifier-syntax">r</span><span class="plain-syntax">] = </span><span class="identifier-syntax">at</span><span class="plain-syntax">; </span><span class="identifier-syntax">best_to1</span><span class="plain-syntax">[</span><span class="identifier-syntax">r</span><span class="plain-syntax">] = </span><span class="identifier-syntax">T</span><span class="plain-syntax">; </span><span class="identifier-syntax">best_dir1</span><span class="plain-syntax">[</span><span class="identifier-syntax">r</span><span class="plain-syntax">] = </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_from2</span><span class="plain-syntax">[</span><span class="identifier-syntax">r</span><span class="plain-syntax">] = </span><span class="identifier-syntax">inner_contact_from</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_to2</span><span class="plain-syntax">[</span><span class="identifier-syntax">r</span><span class="plain-syntax">] = </span><span class="identifier-syntax">inner_contact_to</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">best_dir2</span><span class="plain-syntax">[</span><span class="identifier-syntax">r</span><span class="plain-syntax">] = </span><span class="identifier-syntax">inner_contact_dir</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP26_2_3">&#167;26.2.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26_1_1" class="paragraph-anchor"></a><b>&#167;26.1.1. </b>This is a piece of code used twice in the above function: it puts the
contact <span class="extract"><span class="extract-syntax">observed_from</span></span> to <span class="extract"><span class="extract-syntax">observed_to</span></span> onto our clipboard, provided that
there's room and/or it is interesting enough. We use an insertion-sort to
keep the clipboard in ascending generation order: this would be slow if the
contact arrays were large, but <span class="extract"><span class="extract-syntax">CLIPBOARD_SIZE</span></span> is tiny.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Contact hasss been made</span><span class="named-paragraph-number">26.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">k</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">; </span><span class="identifier-syntax">k</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">contact_generation</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">] == -1) ||</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">observed_generation</span><span class="plain-syntax"> &lt;= </span><span class="identifier-syntax">contact_generation</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">])) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">l</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">l</span><span class="plain-syntax"> = </span><span class="constant-syntax">CLIPBOARD_SIZE</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">l</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">k</span><span class="plain-syntax">; </span><span class="identifier-syntax">l</span><span class="plain-syntax">--) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">contact_generation</span><span class="plain-syntax">[</span><span class="identifier-syntax">l</span><span class="plain-syntax">] = </span><span class="identifier-syntax">contact_generation</span><span class="plain-syntax">[</span><span class="identifier-syntax">l</span><span class="plain-syntax">-1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">contact_from</span><span class="plain-syntax">[</span><span class="identifier-syntax">l</span><span class="plain-syntax">] = </span><span class="identifier-syntax">contact_from</span><span class="plain-syntax">[</span><span class="identifier-syntax">l</span><span class="plain-syntax">-1]; </span><span class="identifier-syntax">contact_to</span><span class="plain-syntax">[</span><span class="identifier-syntax">l</span><span class="plain-syntax">] = </span><span class="identifier-syntax">contact_to</span><span class="plain-syntax">[</span><span class="identifier-syntax">l</span><span class="plain-syntax">-1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">contact_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">l</span><span class="plain-syntax">] = </span><span class="identifier-syntax">contact_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">l</span><span class="plain-syntax">-1];</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">contact_generation</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">] = </span><span class="identifier-syntax">observed_generation</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">contact_from</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">] = </span><span class="identifier-syntax">observed_from</span><span class="plain-syntax">; </span><span class="identifier-syntax">contact_to</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">] = </span><span class="identifier-syntax">observed_to</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">contact_dir</span><span class="plain-syntax">[</span><span class="identifier-syntax">k</span><span class="plain-syntax">] = </span><span class="identifier-syntax">observed_dir</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP26_1">&#167;26.1</a>, <a href="4-sm.html#SP26_2_2">&#167;26.2.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP27" class="paragraph-anchor"></a><b>&#167;27. Zones 1 and 2 for a single cut. </b>Suppose we have decided to cut the submap between rooms <span class="extract"><span class="extract-syntax">R1</span></span> and <span class="extract"><span class="extract-syntax">R2</span></span>, in the
belief that this will disconnect the submap into two components. If that in
fact proves to be the case (as it always should) then we set the <span class="extract"><span class="extract-syntax">zone</span></span> field
to <span class="extract"><span class="extract-syntax">Z1</span></span> for all rooms in the R1 component, and <span class="extract"><span class="extract-syntax">Z2</span></span> on the R1 side. We set
<span class="extract"><span class="extract-syntax">Z1_count</span></span> and <span class="extract"><span class="extract-syntax">Z2_count</span></span> to the sizes of these components, and return <span class="extract"><span class="extract-syntax">TRUE</span></span>.
If, however, cutting does not disconnect the submap, then some mistake has
been made; we return <span class="extract"><span class="extract-syntax">FALSE</span></span> and the rest is undefined.
</p>
<p class="commentary">It is essential for <span class="extract"><span class="extract-syntax">Z1</span></span> and <span class="extract"><span class="extract-syntax">Z2</span></span> to be different. What we will do is to
spread out these zone values from <span class="extract"><span class="extract-syntax">R1</span></span> and <span class="extract"><span class="extract-syntax">R2</span></span> along all spatial
relationships not being cut; if this results in R2 being hit by the flood
from R1, or vice versa, then we're in the <span class="extract"><span class="extract-syntax">FALSE</span></span> case.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::divide_into_zones_onecut</span><button class="popup" onclick="togglePopup('usagePopup49')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup49">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::divide_into_zones_onecut</span></span>:<br/><a href="4-sm.html#SP24_1_2">&#167;24.1.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R1</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R2</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Z1_count</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">Z2_count</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Z1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Z2</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">R2</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can't divide"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Z1</span><span class="plain-syntax">; </span><span class="identifier-syntax">R2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="identifier-syntax">zone</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Z2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">Z1_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; *</span><span class="identifier-syntax">Z2_count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">contacts</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">Z1_count</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP28" class="function-link"><span class="function-syntax">SpatialMap::divide_into_zones_onecut_r</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R1</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">R1</span><span class="plain-syntax">, </span><span class="identifier-syntax">R2</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">contacts</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">contacts</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">Z2_count</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP28" class="function-link"><span class="function-syntax">SpatialMap::divide_into_zones_onecut_r</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R2</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">R2</span><span class="plain-syntax">, </span><span class="identifier-syntax">R1</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">contacts</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Z1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">R1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="identifier-syntax">Z1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">R2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="identifier-syntax">Z2</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> ((*</span><span class="identifier-syntax">Z1_count</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp; ((*</span><span class="identifier-syntax">Z2_count</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP28" class="paragraph-anchor"></a><b>&#167;28. </b>And this is the recursive flooding function &mdash; essentially it's a much
simplified version of the exploration code above. <span class="extract"><span class="extract-syntax">from</span></span> is the room we're
currently at; <span class="extract"><span class="extract-syntax">zone_capital</span></span> is the one we started from, within our zone;
<span class="extract"><span class="extract-syntax">foreign_capital</span></span> is corresponding room of the other zone, so (a) we
mustn't travel on the direct route between the capitals &mdash; that's the line
which has been cut &mdash; and (b) we abandon the moment we find our zone
impinging on the foreign zone, because that means there's no way to divide
our original component into two disjoint connected zones.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::divide_into_zones_onecut_r</span><button class="popup" onclick="togglePopup('usagePopup50')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup50">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::divide_into_zones_onecut_r</span></span>:<br/><a href="4-sm.html#SP27">&#167;27</a>, <a href="4-sm.html#SP28_1">&#167;28.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">from</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">our_capital</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">foreign_capital</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">borders</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rooms_visited</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">our_zone</span><span class="plain-syntax"> = </span><span class="identifier-syntax">at</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP11" class="function-link"><span class="function-syntax">SpatialMap::read_slock</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP28_1" class="named-paragraph-link"><span class="named-paragraph">Consider whether to spread the zone to room T</span><span class="named-paragraph-number">28.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP28_1" class="named-paragraph-link"><span class="named-paragraph">Consider whether to spread the zone to room T</span><span class="named-paragraph-number">28.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rooms_visited</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP28_1" class="paragraph-anchor"></a><b>&#167;28.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Consider whether to spread the zone to room T</span><span class="named-paragraph-number">28.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">T_zone</span><span class="plain-syntax"> = </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax">, </span><span class="identifier-syntax">foreign_zone</span><span class="plain-syntax"> = </span><span class="identifier-syntax">foreign_capital</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T_zone</span><span class="plain-syntax"> == </span><span class="identifier-syntax">our_zone</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">at</span><span class="plain-syntax"> == </span><span class="identifier-syntax">our_capital</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T</span><span class="plain-syntax"> == </span><span class="identifier-syntax">foreign_capital</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">at</span><span class="plain-syntax"> == </span><span class="identifier-syntax">foreign_capital</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T</span><span class="plain-syntax"> == </span><span class="identifier-syntax">our_capital</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T_zone</span><span class="plain-syntax"> == </span><span class="identifier-syntax">foreign_zone</span><span class="plain-syntax">) { (*</span><span class="identifier-syntax">borders</span><span class="plain-syntax">)++; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="identifier-syntax">our_zone</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rooms_visited</span><span class="plain-syntax"> +=</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP28" class="function-link"><span class="function-syntax">SpatialMap::divide_into_zones_onecut_r</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">our_capital</span><span class="plain-syntax">, </span><span class="identifier-syntax">foreign_capital</span><span class="plain-syntax">, </span><span class="identifier-syntax">borders</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP28">&#167;28</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP29" class="paragraph-anchor"></a><b>&#167;29. Zones 1 and 2 for a double cut. </b>This is more or less the same, but simpler, since it can't determine whether
we've chosen the cuts correctly, so doesn't even try.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::divide_into_zones_twocut</span><button class="popup" onclick="togglePopup('usagePopup51')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup51">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::divide_into_zones_twocut</span></span>:<br/><a href="4-sm.html#SP24_1_2">&#167;24.1.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">div_F1</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">div_T1</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">other_F</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">div_T2</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Z1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Z2</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax"> = </span><span class="identifier-syntax">div_F1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">div_F1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Z1</span><span class="plain-syntax">; </span><span class="identifier-syntax">div_T1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Z2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP30" class="function-link"><span class="function-syntax">SpatialMap::divide_into_zones_twocut_r</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">div_F1</span><span class="plain-syntax">, </span><span class="identifier-syntax">div_F1</span><span class="plain-syntax">, </span><span class="identifier-syntax">div_T1</span><span class="plain-syntax">, </span><span class="identifier-syntax">other_F</span><span class="plain-syntax">, </span><span class="identifier-syntax">div_T2</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP30" class="function-link"><span class="function-syntax">SpatialMap::divide_into_zones_twocut_r</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">div_T1</span><span class="plain-syntax">, </span><span class="identifier-syntax">div_F1</span><span class="plain-syntax">, </span><span class="identifier-syntax">div_T1</span><span class="plain-syntax">, </span><span class="identifier-syntax">other_F</span><span class="plain-syntax">, </span><span class="identifier-syntax">div_T2</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP30" class="paragraph-anchor"></a><b>&#167;30. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::divide_into_zones_twocut_r</span><button class="popup" onclick="togglePopup('usagePopup52')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup52">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::divide_into_zones_twocut_r</span></span>:<br/><a href="4-sm.html#SP29">&#167;29</a>, <a href="4-sm.html#SP30_1">&#167;30.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">not_X1</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">not_Y1</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">not_X2</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">not_Y2</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">Z</span><span class="plain-syntax"> = </span><span class="identifier-syntax">at</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP11" class="function-link"><span class="function-syntax">SpatialMap::read_slock</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP30_1" class="named-paragraph-link"><span class="named-paragraph">Consider once again whether to spread the zone to room T</span><span class="named-paragraph-number">30.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP30_1" class="named-paragraph-link"><span class="named-paragraph">Consider once again whether to spread the zone to room T</span><span class="named-paragraph-number">30.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP30_1" class="paragraph-anchor"></a><b>&#167;30.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Consider once again whether to spread the zone to room T</span><span class="named-paragraph-number">30.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">T</span><span class="plain-syntax"> != </span><span class="identifier-syntax">at</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">at</span><span class="plain-syntax"> == </span><span class="identifier-syntax">not_X1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T</span><span class="plain-syntax"> == </span><span class="identifier-syntax">not_Y1</span><span class="plain-syntax">)) || ((</span><span class="identifier-syntax">at</span><span class="plain-syntax"> == </span><span class="identifier-syntax">not_Y1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T</span><span class="plain-syntax"> == </span><span class="identifier-syntax">not_X1</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">at</span><span class="plain-syntax"> == </span><span class="identifier-syntax">not_X2</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T</span><span class="plain-syntax"> == </span><span class="identifier-syntax">not_Y2</span><span class="plain-syntax">)) || ((</span><span class="identifier-syntax">at</span><span class="plain-syntax"> == </span><span class="identifier-syntax">not_Y2</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T</span><span class="plain-syntax"> == </span><span class="identifier-syntax">not_X2</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Z</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP30" class="function-link"><span class="function-syntax">SpatialMap::divide_into_zones_twocut_r</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">not_X1</span><span class="plain-syntax">, </span><span class="identifier-syntax">not_Y1</span><span class="plain-syntax">, </span><span class="identifier-syntax">not_X2</span><span class="plain-syntax">, </span><span class="identifier-syntax">not_Y2</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP30">&#167;30</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP31" class="paragraph-anchor"></a><b>&#167;31. Tactics. </b>At long last we can forget about dividing submaps, and concentrate on the
four tactics for improving the layout of a given submap. We're going to do
all kinds of heuristic things here, some of them with iffy running times,
which is one reason why the above divide-and-conquer tricks were wise
(the other that divisions also reduce the complexity of the pieces we
need to work on).
</p>
<p class="commentary">We'll often experimentally change something, see what that does, then
change our minds. For really large-scale experimental changes to the grid
it's convenient to have a sort of global undo. Note that lock positions
after restoration must be consistent, since they were consistent at save
time.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::save_component_positions</span><button class="popup" onclick="togglePopup('usagePopup53')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup53">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::save_component_positions</span></span>:<br/><a href="4-sm.html#SP24_1_4">&#167;24.1.4</a>, <a href="4-sm.html#SP32">&#167;32</a>, <a href="4-sm.html#SP36_1">&#167;36.1</a>, <a href="4-sm.html#SP38_1_1">&#167;38.1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">saved_gridpos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::restore_component_positions</span><button class="popup" onclick="togglePopup('usagePopup54')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup54">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::restore_component_positions</span></span>:<br/><a href="4-sm.html#SP24_1_4">&#167;24.1.4</a>, <a href="4-sm.html#SP32">&#167;32</a>, <a href="4-sm.html#SP36_1">&#167;36.1</a>, <a href="4-sm.html#SP38_1_1">&#167;38.1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_1" class="function-link"><span class="function-syntax">SpatialMap::set_room_position</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">saved_gridpos</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP32" class="paragraph-anchor"></a><b>&#167;32. The cooling tactic. </b>The whole universe was in a hot dense state: as we begin each component,
every room is at (0,0,0) unless locking causes it to offset slightly, so that
almost every exit is very hot indeed. We now enter the era of cooling,
when a great expansion occurs.
</p>
<p class="commentary">This is an iterative process, and if we ran this algorithm indefinitely it
would very likely lock up, continually moving rooms back and forth but never
solving its underlying geometric problems. So cooling may only continue so
long as component heat is strictly reduced on each round.
</p>
<p class="commentary">Cooling has the great virtue that each round runs in \(O(S)\) time, where \(S\)
is the number of rooms in the submap. It's quite hard to estimate the
total running time, but in practice the number of rounds seldom exceeds
3 or 4, even on quite bad maps, and because cooling is essentially a
local process there's no reason to expect the number of rounds to grow much
if \(S\) grows. So my guess is that cooling is \(O(S)\) in practice.
</p>
<p class="commentary">Another virtue is that cooling alone works in many easy cases. If there are
no locks, and no multiple exits between pairs of rooms A to B, then cooling
is guaranteed to find a perfect (heat 0) grid positioning if one exists.
There are plenty of Inform projects for which that happens: "Bronze",
for instance, has a single component of 55 rooms, and one round of cooling
reduces this to absolute zero.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::cool_submap</span><button class="popup" onclick="togglePopup('usagePopup55')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup55">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::cool_submap</span></span>:<br/><a href="4-sm.html#SP24">&#167;24</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">initial_heat</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">), </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax"> = </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"\nTACTIC: Cooling submap %d: initial heat %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">heat_before_round</span><span class="plain-syntax"> = </span><span class="identifier-syntax">initial_heat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rounds</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Cooling round %d.\n"</span><span class="plain-syntax">, ++</span><span class="identifier-syntax">rounds</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">cooled</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP31" class="function-link"><span class="function-syntax">SpatialMap::save_component_positions</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) </span><a href="4-sm.html#SP33" class="function-link"><span class="function-syntax">SpatialMap::cool_component_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">heat_before_round</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP31" class="function-link"><span class="function-syntax">SpatialMap::restore_component_positions</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Cooling round %d raised heat, so undone.\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">rounds</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Cooling round %d leaves penalty %d.\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">rounds</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">heat_before_round</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">heat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Cooling submap %d done (%d round(s)): cooled by %d at cost of %d drognas\n\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">rounds</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">initial_heat</span><span class="plain-syntax"> - </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">cooling_spending</span><span class="plain-syntax"> += </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP33" class="paragraph-anchor"></a><b>&#167;33. </b>Cooling is done room by room within the component, but we get slightly
better results if it is allowed to spread through the component along exits
as they cool than if it is simply performed on the rooms in creation order.
Since the map likely contains circular routes, rooms are flagged so that they
can only be cooled once in a given round.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::cool_component_from</span><button class="popup" onclick="togglePopup('usagePopup56')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup56">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::cool_component_from</span></span>:<br/><a href="4-sm.html#SP32">&#167;32</a>, <a href="4-sm.html#SP33_2">&#167;33.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">cooled</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">cooled</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">exit_heats</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_DIRECTIONS</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">exit_rooms</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_DIRECTIONS</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP33_1" class="named-paragraph-link"><span class="named-paragraph">Find the exits from this room and their current heats</span><span class="named-paragraph-number">33.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP33_2" class="named-paragraph-link"><span class="named-paragraph">Iteratively cool as many exits as possible</span><span class="named-paragraph-number">33.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP33_1" class="paragraph-anchor"></a><b>&#167;33.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Find the exits from this room and their current heats</span><span class="named-paragraph-number">33.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">exit_heats</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><a href="4-sm.html#SP22" class="function-link"><span class="function-syntax">SpatialMap::find_exit_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">exit_rooms</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP33">&#167;33</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP33_2" class="paragraph-anchor"></a><b>&#167;33.2. </b>An important point here is that we don't re-measure the heat of the exits
after cooling. If we did, we might find that cooling is having no effect, and
then lock up. We're simply trying to deal with the heat as it looked at the
start of the process; this means there are at most 12 iterations.
</p>
<p class="commentary">The reason we do this in what looks an indirect way (why iterate at all?) is
to cope better with cases where there are two different exits from R to S.
This frequently happens in IF maps:
</p>
<blockquote>
<p>The Exalted Throne is above the Ziggurat. [...] South from the Throne is the Ziggurat.</p>
</blockquote>
<p class="commentary">Now there are two exits from Z to E: up and north. They cannot simultaneously
be cooled. The rule we follow is that we never cool an exit if another exit
between the two rooms is already cold &mdash; this keeps us from endless flipping
our choice (up from Z to E on cooling round 1, then north on round 2, then up
on round 3, and so on).
</p>
<p class="commentary">However, it makes a big difference to the style of the map we produce which
choice we make. Because the code below tries the exits in direction number
order, and because lateral directions (N, NE, E, SE, S, SW, W, NW) have
lower direction numbers than vertical (U, D), the effect is to prefer lateral
choices over vertical ones. This is a good choice for two reasons: (i) given
the way we're going to plot the map on a web page, vertical offsets are
harder to judge by eye; and (ii) IF authors often use "both N and U"-style
connections to convey that the landscape isn't totally flat, but they're
still talking about a two-dimensional surface. (Cartographers have always
done this. The French map IGN 3535 OT, N\'evache-Mont Thabor, shows the
Rois Mages mountains as if you could walk southeast from Modane and take in
all three in an afternoon stroll.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Iteratively cool as many exits as possible</span><span class="named-paragraph-number">33.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">exits_cooled</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">exit_heats</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">j</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">exit_heats</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">exit_rooms</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] == </span><span class="identifier-syntax">exit_rooms</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">])) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">exit_heats</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">exits_cooled</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">exit_heats</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP34" class="function-link"><span class="function-syntax">SpatialMap::cool_exit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">exit_heats</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">exits_cooled</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP33" class="function-link"><span class="function-syntax">SpatialMap::cool_component_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">exit_rooms</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">j</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">exit_heats</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">exit_rooms</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] == </span><span class="identifier-syntax">exit_rooms</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">])) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">exit_heats</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">exits_cooled</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">exits_cooled</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP33">&#167;33</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP34" class="paragraph-anchor"></a><b>&#167;34. </b>To cool an exit is to move the destination room into the perfect grid
position so that the exit's heat is 0. Note that we must always maintain
locking, and that we provide a convenient "undo" mechanism in case the
result made matters worse. (Cooling one exit may simply make other exits
hotter, since the destination room falls out of alignment with its other
neighbours.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">saved_to</span><span class="plain-syntax">; </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">Saved_position</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::undo_cool_exit</span><button class="popup" onclick="togglePopup('usagePopup57')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup57">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::undo_cool_exit</span></span>:<br/><a href="4-sm.html#SP35_1">&#167;35.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_23" class="function-link"><span class="function-syntax">SpatialMap::move_room_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">saved_to</span><span class="plain-syntax">, </span><span class="identifier-syntax">Saved_position</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP_WORKINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Undoing move of %S\n"</span><span class="plain-syntax">, </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">saved_to</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::cool_exit</span><button class="popup" onclick="togglePopup('usagePopup58')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup58">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::cool_exit</span></span>:<br/><a href="4-sm.html#SP33_2">&#167;33.2</a>, <a href="4-sm.html#SP35_1">&#167;35.1</a>, <a href="4-sm.html#SP36_1">&#167;36.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">to</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">saved_to</span><span class="plain-syntax"> = </span><span class="identifier-syntax">to</span><span class="plain-syntax">; </span><span class="identifier-syntax">Saved_position</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">to</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_5" class="function-link"><span class="function-syntax">SpatialMap::direction_as_vector</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">length</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">exit_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">exit</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_plus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_scale</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">length</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sg.html#SP6" class="function-link"><span class="function-syntax">Geometry::vec_eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">to</span><span class="plain-syntax">), </span><span class="identifier-syntax">N</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_23" class="function-link"><span class="function-syntax">SpatialMap::move_room_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">saved_to</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP_WORKINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Moving %S %s from %S: now at (%d,%d,%d)\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">to</span><span class="plain-syntax">), </span><a href="4-sm.html#SP8_12" class="function-link"><span class="function-syntax">SpatialMap::find_icon_label</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">exit</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="identifier-syntax">N</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax">, </span><span class="identifier-syntax">N</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP35" class="paragraph-anchor"></a><b>&#167;35. The quenching tactic. </b>After the age of cooling, we can expect the universe to be mostly cold, but
with local hot-spots where the geometry is distorted because the map is
simply awkward nearby. Because this tends to be a local problem, we try to
find a local solution &mdash; it's actually just individualised exit cooling.
</p>
<p class="commentary">This theoretically runs in \(O(S^3)\) time: note that the measurement of
submap heat is itself \(O(S)\), and we perform this inside a loop of \(O(S)\),
which in turn happens within a repetition which might run for every link
in the map, also \(O(S)\). In practice, there are never many quenching rounds,
so it's really "only" \(O(S^2)\). Still, this is why we don't want to quench
on large connected submaps.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::quench_submap</span><button class="popup" onclick="togglePopup('usagePopup59')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup59">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::quench_submap</span></span>:<br/><a href="4-sm.html#SP24_1_1">&#167;24.1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">avoid1</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">avoid2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">initial_heat</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax"> = </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"\nTACTIC: Quenching submap %d: initial heat %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">, </span><span class="identifier-syntax">last_heat</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">rounds</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">heat</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">last_heat</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Quenching round %d begins with heat at %d.\n"</span><span class="plain-syntax">, ++</span><span class="identifier-syntax">rounds</span><span class="plain-syntax">, </span><span class="identifier-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_heat</span><span class="plain-syntax"> = </span><span class="identifier-syntax">heat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">successes</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP22" class="function-link"><span class="function-syntax">SpatialMap::find_exit_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP35_1" class="named-paragraph-link"><span class="named-paragraph">Attempt to quench this heated link</span><span class="named-paragraph-number">35.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Quenching round %d had %d success(es).\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">rounds</span><span class="plain-syntax">, </span><span class="identifier-syntax">successes</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Quenching submap %d done: cooled by %d at cost of %d drognas\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">initial_heat</span><span class="plain-syntax"> - </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">quenching_spending</span><span class="plain-syntax"> += </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP35_1" class="paragraph-anchor"></a><b>&#167;35.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Attempt to quench this heated link</span><span class="named-paragraph-number">35.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">T</span><span class="plain-syntax"> == </span><span class="identifier-syntax">avoid1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">avoid2</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">T</span><span class="plain-syntax"> == </span><span class="identifier-syntax">avoid2</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">avoid1</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP_WORKINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Quenching %S %s to %S.\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><a href="4-sm.html#SP8_12" class="function-link"><span class="function-syntax">SpatialMap::find_icon_label</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP34" class="function-link"><span class="function-syntax">SpatialMap::cool_exit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">heat</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP34" class="function-link"><span class="function-syntax">SpatialMap::undo_cool_exit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP_WORKINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Undoing: would have resulted in heat %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><span class="identifier-syntax">h</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP_WORKINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Accepting: reduces heat to %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">h</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">successes</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP35">&#167;35</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP36" class="paragraph-anchor"></a><b>&#167;36. The diffusion tactic. </b>Where quenching fails to help much, this is usually because rooms are packed
too tightly together, and need to be eased apart. This makes space for
more interesting configurations and makes it easier to get rid of the very
large collision heats, though the heat of some individual links actually
rises, since there's a penalty for increasing length.
</p>
<p class="commentary">We call this process diffusion, since the heat eddies away into the local
neighbourhood as the rooms shimmy apart.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::diffuse_submap</span><button class="popup" onclick="togglePopup('usagePopup60')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup60">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::diffuse_submap</span></span>:<br/><a href="4-sm.html#SP24_1_1">&#167;24.1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">initial_heat</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax"> = </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"\nTACTIC: Diffusing submap %d: initial heat %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">, </span><span class="identifier-syntax">last_heat</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">rounds</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">heat</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">last_heat</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Diffusion round %d with heat at %d.\n"</span><span class="plain-syntax">, ++</span><span class="identifier-syntax">rounds</span><span class="plain-syntax">, </span><span class="identifier-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_heat</span><span class="plain-syntax"> = </span><span class="identifier-syntax">heat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP36_1" class="named-paragraph-link"><span class="named-paragraph">Try diffusion along this link</span><span class="named-paragraph-number">36.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Diffusing submap %d done after %d round(s): "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"cooled by %d at cost of %d drognas\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">rounds</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">initial_heat</span><span class="plain-syntax"> - </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">diffusion_spending</span><span class="plain-syntax"> += </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP36_1" class="paragraph-anchor"></a><b>&#167;36.1. </b>Essentially we try lengthening the link by 1 unit, and see if that makes
things better; however, it tends to be useless just moving one room, because
that's very likely only moving a collision heat (let's say) one place down
the grid. So we move not only the room but also a whole clump of nearby
rooms whose exits are cold (or which are locked to each other).
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Try diffusion along this link</span><span class="named-paragraph-number">36.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">exit_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> &gt; -1) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP_WORKINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Lengthening %S %s to %S to %d.\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><a href="4-sm.html#SP8_12" class="function-link"><span class="function-syntax">SpatialMap::find_icon_label</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">), </span><span class="identifier-syntax">L</span><span class="plain-syntax">+1);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP31" class="function-link"><span class="function-syntax">SpatialMap::save_component_positions</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">O</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">exit_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">L</span><span class="plain-syntax">+1;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP34" class="function-link"><span class="function-syntax">SpatialMap::cool_exit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_minus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="identifier-syntax">O</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) </span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP37" class="function-link"><span class="function-syntax">SpatialMap::diffuse_across</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">S</span><span class="plain-syntax"> != </span><span class="identifier-syntax">R</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_23" class="function-link"><span class="function-syntax">SpatialMap::translate_room</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">heat</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP31" class="function-link"><span class="function-syntax">SpatialMap::restore_component_positions</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">exit_lengths</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP_WORKINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Lengthening left heat undecreased at %d.\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP_WORKINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Lengthening reduced heat to %d.\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP36">&#167;36</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP37" class="paragraph-anchor"></a><b>&#167;37. </b>This recursively expands zone 2 to include rooms connected by cold links,
except that it's forbidden to including <span class="extract"><span class="extract-syntax">avoiding</span></span> (the room we are trying
to lengthen away from).
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::diffuse_across</span><button class="popup" onclick="togglePopup('usagePopup61')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup61">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::diffuse_across</span></span>:<br/><a href="4-sm.html#SP36_1">&#167;36.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">avoiding</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">at</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP11" class="function-link"><span class="function-syntax">SpatialMap::read_slock</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">T</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">)) </span><a href="4-sm.html#SP37" class="function-link"><span class="function-syntax">SpatialMap::diffuse_across</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">avoiding</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">T</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T</span><span class="plain-syntax"> != </span><span class="identifier-syntax">avoiding</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP22" class="function-link"><span class="function-syntax">SpatialMap::find_exit_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP37" class="function-link"><span class="function-syntax">SpatialMap::diffuse_across</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">avoiding</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP38" class="paragraph-anchor"></a><b>&#167;38. The radiation tactic. </b>Here, we look for misaligned links, because they'll look broken to the eye,
and see if it's possible to slide a block of rooms in one of the compass
directions so that the link becomes aligned again.
</p>
<p class="commentary">This is such a neat trick, and so (relatively!) fast, that we apply it in
two circumstances: not only when tidying up after diffusion, but also after
we have rejoined a divided submap. (It's especially good for that because
after a two-point cut we often have a situation where one of the cut links
is put back tidily but the other is dislocated.)
</p>
<p class="commentary">It's hard to prove that radiation is rapid, because it certainly wouldn't be
if used earlier on. What saves us is that by now there are few misaligned
links.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::radiate_submap</span><button class="popup" onclick="togglePopup('usagePopup62')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup62">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::radiate_submap</span></span>:<br/><a href="4-sm.html#SP24_1">&#167;24.1</a>, <a href="4-sm.html#SP24_1_1">&#167;24.1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">initial_heat</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax"> = </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"\nTACTIC: Radiating submap %d: initial heat %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">, </span><span class="identifier-syntax">last_heat</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">rounds</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">heat</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">last_heat</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Radiation round %d with heat at %d.\n"</span><span class="plain-syntax">, ++</span><span class="identifier-syntax">rounds</span><span class="plain-syntax">, </span><span class="identifier-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">last_heat</span><span class="plain-syntax"> = </span><span class="identifier-syntax">heat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">T</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP23" class="function-link"><span class="function-syntax">SpatialMap::exit_aligned</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP38_1" class="named-paragraph-link"><span class="named-paragraph">Attempt to radiate from this misaligned link</span><span class="named-paragraph-number">38.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Radiating submap %d done after %d round(s): "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"cooled by %d at cost of %d drognas\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">rounds</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">initial_heat</span><span class="plain-syntax"> - </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">radiation_spending</span><span class="plain-syntax"> += </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP38_1" class="paragraph-anchor"></a><b>&#167;38.1. </b>We try some 40 possible translations of the R end of the link, hoping to
find that one or more of them will align with the T end. T will stay
fixed: note that by symmetry, if this doesn't work, we'll end up testing
the same link with the roles of R and T reversed later. Typically, there
are only three or four viable new positions for R.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_RADIATION_DISTANCE</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Attempt to radiate from this misaligned link</span><span class="named-paragraph-number">38.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP_WORKINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Map misaligned on %S %s to %S.\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><a href="4-sm.html#SP8_12" class="function-link"><span class="function-syntax">SpatialMap::find_icon_label</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_INDENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">O</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">j</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_5" class="function-link"><span class="function-syntax">SpatialMap::direction_as_vector</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">L</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">MAX_RADIATION_DISTANCE</span><span class="plain-syntax">; </span><span class="identifier-syntax">L</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_scale</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_1" class="function-link"><span class="function-syntax">SpatialMap::set_room_position</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_plus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">O</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP23" class="function-link"><span class="function-syntax">SpatialMap::exit_aligned</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP38_1_1" class="named-paragraph-link"><span class="named-paragraph">Radiation is geometrically possible here</span><span class="named-paragraph-number">38.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_1" class="function-link"><span class="function-syntax">SpatialMap::set_room_position</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">O</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Escape:</span><span class="plain-syntax"> ;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG_OUTDENT</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP38">&#167;38</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP38_1_1" class="paragraph-anchor"></a><b>&#167;38.1.1. </b>At this point setting this up is much the same as for diffusion:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Radiation is geometrically possible here</span><span class="named-paragraph-number">38.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP_WORKINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Aligned at offset %d, %d, %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP31" class="function-link"><span class="function-syntax">SpatialMap::save_component_positions</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) </span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_27" class="function-link"><span class="function-syntax">SpatialMap::radiate_across</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">S</span><span class="plain-syntax"> != </span><span class="identifier-syntax">R</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP_WORKINGS</span><span class="plain-syntax">, </span><span class="string-syntax">"Comoving %S\n"</span><span class="plain-syntax">, </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_23" class="function-link"><span class="function-syntax">SpatialMap::translate_room</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">heat</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP31" class="function-link"><span class="function-syntax">SpatialMap::restore_component_positions</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP_WORKINGS</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Radiating left heat undecreased at %d.\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP_WORKINGS</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="string-syntax">"Radiating reduced heat to %d.\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">goto</span><span class="plain-syntax"> </span><span class="identifier-syntax">Escape</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP38_1">&#167;38.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_27" class="paragraph-anchor"></a><b>&#167;8.27. </b>This is the clever part of radiation, and the reason why we only allow R
to radiate outward on cardinal points of the compass. Once again we will
move a whole clump of R's neighbours along with it, preserving their positions
relative to each other; but this time we define the boundary of the clump
by links in the radiation direction, or its opposite. The result is that
no exit can ever become misaligned during radiation; the only movements
happen parallel to the only links whose endpoints move with respect to each
other. (With just one exception, of course: the link between R and T,
where by construction the movement will make a previously unaligned link
become aligned.)
</p>
<p class="commentary">It follows that radiation can never increase the number of unaligned links.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::radiate_across</span><button class="popup" onclick="togglePopup('usagePopup63')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup63">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::radiate_across</span></span>:<br/><a href="4-sm.html#SP38_1_1">&#167;38.1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">avoiding</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">not_this_way</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">at</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">not_this_way_either</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_6" class="function-link"><span class="function-syntax">SpatialMap::opposite</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">not_this_way</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP11" class="function-link"><span class="function-syntax">SpatialMap::read_slock</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">T</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_27" class="function-link"><span class="function-syntax">SpatialMap::radiate_across</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">avoiding</span><span class="plain-syntax">, </span><span class="identifier-syntax">not_this_way</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">T</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">T</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">zone</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">T</span><span class="plain-syntax"> != </span><span class="identifier-syntax">avoiding</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> != </span><span class="identifier-syntax">not_this_way</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">i</span><span class="plain-syntax"> != </span><span class="identifier-syntax">not_this_way_either</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_27" class="function-link"><span class="function-syntax">SpatialMap::radiate_across</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">T</span><span class="plain-syntax">, </span><span class="identifier-syntax">avoiding</span><span class="plain-syntax">, </span><span class="identifier-syntax">not_this_way</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_28" class="paragraph-anchor"></a><b>&#167;8.28. The explosion tactic. </b>Sometimes, in the direst emergency, there's one tried and tested way to
get rid of a lot of concentrated heat: to explode. Specifically, we get
rid of collisions between rooms (which we absolutely forbid) by moving them
apart until there are no further collisions. We do this even if it should
increase the heat measure, though in practice the penalty for room collisions
is so high that this is unlikely to be an issue.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_EXPLOSION_DISTANCE</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::explode_submap</span><button class="popup" onclick="togglePopup('usagePopup64')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup64">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::explode_submap</span></span>:<br/><a href="4-sm.html#SP24_1_1">&#167;24.1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">initial_heat</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax"> = </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"\nTACTIC: Exploding submap %d: initial heat %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">heat</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">keep_trying</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">, </span><span class="identifier-syntax">moves</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">keep_trying</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">keep_trying</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">At</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">SpatialMap::occupied_in_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">At</span><span class="plain-syntax">) &gt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Collision: pushing %S away\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">x</span><span class="plain-syntax">, </span><span class="identifier-syntax">y</span><span class="plain-syntax">, </span><span class="identifier-syntax">coldest</span><span class="plain-syntax"> = </span><span class="constant-syntax">FUSION_POINT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">Coldest</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP5" class="function-link"><span class="function-syntax">Geometry::vec</span></a><span class="plain-syntax">(</span><span class="constant-syntax">MAX_EXPLOSION_DISTANCE</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">x</span><span class="plain-syntax"> = -</span><span class="constant-syntax">MAX_EXPLOSION_DISTANCE</span><span class="plain-syntax">; </span><span class="identifier-syntax">x</span><span class="plain-syntax">&lt;=</span><span class="constant-syntax">MAX_EXPLOSION_DISTANCE</span><span class="plain-syntax">; </span><span class="identifier-syntax">x</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">y</span><span class="plain-syntax"> = -</span><span class="constant-syntax">MAX_EXPLOSION_DISTANCE</span><span class="plain-syntax">; </span><span class="identifier-syntax">y</span><span class="plain-syntax">&lt;=</span><span class="constant-syntax">MAX_EXPLOSION_DISTANCE</span><span class="plain-syntax">; </span><span class="identifier-syntax">y</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">x</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">y</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">V</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_plus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">At</span><span class="plain-syntax">, </span><a href="4-sg.html#SP5" class="function-link"><span class="function-syntax">Geometry::vec</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">x</span><span class="plain-syntax">, </span><span class="identifier-syntax">y</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">SpatialMap::occupied_in_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">V</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_23" class="function-link"><span class="function-syntax">SpatialMap::move_room_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">V</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">h</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">h</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">coldest</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Coldest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">V</span><span class="plain-syntax">; </span><span class="identifier-syntax">coldest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">h</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_23" class="function-link"><span class="function-syntax">SpatialMap::move_room_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_plus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">At</span><span class="plain-syntax">, </span><span class="identifier-syntax">Coldest</span><span class="plain-syntax">), </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Moving %S to blank offset (%d,%d,%d) for heat %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="identifier-syntax">Coldest</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax">, </span><span class="identifier-syntax">Coldest</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax">, </span><span class="identifier-syntax">Coldest</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax">, </span><span class="identifier-syntax">coldest</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">keep_trying</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">moves</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">SpatialMap::find_submap_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Exploding submap %d done after %d move(s): "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"cooled by %d at cost of %d drognas\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">moves</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">initial_heat</span><span class="plain-syntax"> - </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">heat</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">explosion_spending</span><span class="plain-syntax"> += </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">drognas_spent</span><span class="plain-syntax"> - </span><span class="identifier-syntax">initial_spending</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_29" class="paragraph-anchor"></a><b>&#167;8.29. Stage 3, positioning the components. </b>Having cooled and diffused each component, we now treat them as rigid
bodies, but still have to establish their spatial relationship to each
other. We ensure that the components do not overlap by the crude method of
making their bounding cuboids disjoint, even though this will often mean
that there is wasted space on the page. (Thus we do not, for instance, use
the trick adopted by the British Ordnance Survey in mapping the outlying
island of St Kilda on an inset square of what would otherwise be empty
ocean on OS18 "Sound of Harris", despite its being separated by about
60km from the position shown.)
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(4) Position the components in space</span><span class="named-paragraph-number">8.29</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ncom</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">LS</span><span class="plain-syntax"> = </span><a href="1-ia.html#SP7" class="function-link"><span class="function-syntax">Indexing::get_list_of_submaps</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAPS</span><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) </span><span class="identifier-syntax">ncom</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> **</span><span class="identifier-syntax">sorted</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Memory::calloc</span><span class="plain-syntax">(</span><span class="identifier-syntax">ncom</span><span class="plain-syntax">, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *), </span><span class="constant-syntax">INDEX_SORTING_MREASON</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_29_2" class="named-paragraph-link"><span class="named-paragraph">Sort the components into decreasing order of size</span><span class="named-paragraph-number">8.29.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">previous_mc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">Drill_square_O</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Zero_vector</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">Drill_square_At</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Zero_vector</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">drill_square_side</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">cuboid</span><span class="plain-syntax"> </span><span class="identifier-syntax">box</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP10" class="function-link"><span class="function-syntax">Geometry::empty_cuboid</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">ncom</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sorted</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">positioned</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_29_1" class="named-paragraph-link"><span class="named-paragraph">Position this map component in space</span><span class="named-paragraph-number">8.29.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=</span><span class="identifier-syntax">ncom</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">j</span><span class="plain-syntax">&gt;=0; </span><span class="identifier-syntax">j</span><span class="plain-syntax">--) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sorted</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">positioned</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="4-sm.html#SP42" class="function-link"><span class="function-syntax">SpatialMap::no_links_to_placed_components</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) == </span><span class="constant-syntax">1</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_29_1" class="named-paragraph-link"><span class="named-paragraph">Position this map component in space</span><span class="named-paragraph-number">8.29.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Memory::I7_array_free</span><span class="plain-syntax">(</span><span class="identifier-syntax">sorted</span><span class="plain-syntax">, </span><span class="constant-syntax">INDEX_SORTING_MREASON</span><span class="plain-syntax">, </span><span class="identifier-syntax">ncom</span><span class="plain-syntax">, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_29_1" class="paragraph-anchor"></a><b>&#167;8.29.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Position this map component in space</span><span class="named-paragraph-number">8.29.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">previous_mc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">x_max</span><span class="plain-syntax"> = </span><span class="identifier-syntax">box</span><span class="plain-syntax">.</span><span class="element-syntax">corner1</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax"> - </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">population</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp; (</span><a href="4-sm.html#SP40" class="function-link"><span class="function-syntax">SpatialMap::component_is_isolated</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_29_1_2" class="named-paragraph-link"><span class="named-paragraph">Use the drill-square strategy to place this component</span><span class="named-paragraph-number">8.29.1.2</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP40" class="function-link"><span class="function-syntax">SpatialMap::component_is_adjoining</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_29_1_3" class="named-paragraph-link"><span class="named-paragraph">Use the optimised inset strategy to place this component</span><span class="named-paragraph-number">8.29.1.3</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_29_1_1" class="named-paragraph-link"><span class="named-paragraph">Use the side-by-side strategy to place this component</span><span class="named-paragraph-number">8.29.1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP11" class="function-link"><span class="function-syntax">Geometry::merge_cuboid</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">box</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">previous_mc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">positioned</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8_29">&#167;8.29</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP8_29_1_1" class="paragraph-anchor"></a><b>&#167;8.29.1.1. </b>Here we simply place the component immediately to the right of its
predecessor, with the same baseline, and on the level of the benchmark room.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Use the side-by-side strategy to place this component</span><span class="named-paragraph-number">8.29.1.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Component %d (size %d): side by side strategy\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">population</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_18" class="function-link"><span class="function-syntax">SpatialMap::move_component</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP5" class="function-link"><span class="function-syntax">Geometry::vec</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">x_max</span><span class="plain-syntax">, </span><span class="identifier-syntax">box</span><span class="plain-syntax">.</span><span class="identifier-syntax">corner0</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax"> - </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP4" class="function-link"><span class="function-syntax">SpatialMap::benchmark_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">) - </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8_29_1">&#167;8.29.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_29_1_2" class="paragraph-anchor"></a><b>&#167;8.29.1.2. </b>The drill square is a way to place large numbers of single-room components,
such as exist in IF works where rooms are being plaited together live during
play and have no initial map. Side-by-side placement would be horrible for
such rooms. We will form the most nearly square rectangle which can hold
them, arranged so that it's slightly wider than it is tall. In effect, this
rectangle &mdash; the "drill square" &mdash; is then placed side-by-side as if it's
one big component.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Use the drill-square strategy to place this component</span><span class="named-paragraph-number">8.29.1.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Component %d (size %d): drill square strategy\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">population</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">drill_square_side</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Drill_square_O</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP5" class="function-link"><span class="function-syntax">Geometry::vec</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">box</span><span class="plain-syntax">.</span><span class="element-syntax">corner1</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">box</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP4" class="function-link"><span class="function-syntax">SpatialMap::benchmark_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Drill_square_At</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Drill_square_O</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sing</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">LS</span><span class="plain-syntax"> = </span><a href="1-ia.html#SP7" class="function-link"><span class="function-syntax">Indexing::get_list_of_submaps</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAPS</span><span class="plain-syntax">(</span><span class="identifier-syntax">sing</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">sing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">population</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) &amp;&amp; (</span><a href="4-sm.html#SP40" class="function-link"><span class="function-syntax">SpatialMap::component_is_isolated</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sing</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">drill_square_side</span><span class="plain-syntax">*</span><span class="identifier-syntax">drill_square_side</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">N</span><span class="plain-syntax">) </span><span class="identifier-syntax">drill_square_side</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">drill_square_side</span><span class="plain-syntax">*</span><span class="identifier-syntax">drill_square_side</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">N</span><span class="plain-syntax">) </span><span class="identifier-syntax">drill_square_side</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Drill square: side %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">drill_square_side</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_18" class="function-link"><span class="function-syntax">SpatialMap::move_component</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_minus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Drill_square_At</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Drill_square_At</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_plus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Drill_square_At</span><span class="plain-syntax">, </span><a href="4-sg.html#SP5" class="function-link"><span class="function-syntax">Geometry::vec</span></a><span class="plain-syntax">(0, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Drill_square_At</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax"> - </span><span class="identifier-syntax">Drill_square_O</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax"> == </span><span class="identifier-syntax">drill_square_side</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Drill_square_At</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_plus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Drill_square_At</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP5" class="function-link"><span class="function-syntax">Geometry::vec</span></a><span class="plain-syntax">(1, -</span><span class="identifier-syntax">drill_square_side</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8_29_1">&#167;8.29.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_29_1_3" class="paragraph-anchor"></a><b>&#167;8.29.1.3. </b>Insetting is used if our new component has a map connection in the IN or
OUT directions with an already-placed component; if we can, we want to place
the new component into the map as close as possible to the room it connects
with.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_OFFSET</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Use the optimised inset strategy to place this component</span><span class="named-paragraph-number">8.29.1.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"Component %d (size %d): optimised inset strategy\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">population</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outer</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">inner</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP42" class="function-link"><span class="function-syntax">SpatialMap::find_link_to_placed_components</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">outer</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">inner</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">Best_offset</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP5" class="function-link"><span class="function-syntax">Geometry::vec</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">x_max</span><span class="plain-syntax">, </span><span class="identifier-syntax">box</span><span class="plain-syntax">.</span><span class="identifier-syntax">corner0</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax"> - </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP4" class="function-link"><span class="function-syntax">SpatialMap::benchmark_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">) - </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">outer</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">inner</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">dx</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">dy</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">dz</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">min_s</span><span class="plain-syntax"> = </span><span class="constant-syntax">FUSION_POINT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">dx</span><span class="plain-syntax"> = -</span><span class="constant-syntax">MAX_OFFSET</span><span class="plain-syntax">; </span><span class="identifier-syntax">dx</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">MAX_OFFSET</span><span class="plain-syntax">; </span><span class="identifier-syntax">dx</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">dy</span><span class="plain-syntax"> = -</span><span class="constant-syntax">MAX_OFFSET</span><span class="plain-syntax">; </span><span class="identifier-syntax">dy</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">MAX_OFFSET</span><span class="plain-syntax">; </span><span class="identifier-syntax">dy</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">dz</span><span class="plain-syntax"> = -</span><span class="constant-syntax">MAX_OFFSET</span><span class="plain-syntax">; </span><span class="identifier-syntax">dz</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">MAX_OFFSET</span><span class="plain-syntax">; </span><span class="identifier-syntax">dz</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">dx</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">dy</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">dz</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">Offset</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_plus</span></a><span class="plain-syntax">(</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_minus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">outer</span><span class="plain-syntax">), </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">inner</span><span class="plain-syntax">)),</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP5" class="function-link"><span class="function-syntax">Geometry::vec</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">dx</span><span class="plain-syntax">, </span><span class="identifier-syntax">dy</span><span class="plain-syntax">, </span><span class="identifier-syntax">dz</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP8_29_1_3_1" class="named-paragraph-link"><span class="named-paragraph">Try this possible offset component position</span><span class="named-paragraph-number">8.29.1.3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_18" class="function-link"><span class="function-syntax">SpatialMap::move_component</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">Best_offset</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8_29_1">&#167;8.29.1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_29_1_3_1" class="paragraph-anchor"></a><b>&#167;8.29.1.3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Try this possible offset component position</span><span class="named-paragraph-number">8.29.1.3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_18" class="function-link"><span class="function-syntax">SpatialMap::move_component</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">Offset</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP41" class="function-link"><span class="function-syntax">SpatialMap::find_component_placement_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">s</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">min_s</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">min_s</span><span class="plain-syntax"> = </span><span class="identifier-syntax">s</span><span class="plain-syntax">; </span><span class="identifier-syntax">Best_offset</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Offset</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_18" class="function-link"><span class="function-syntax">SpatialMap::move_component</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_negate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Offset</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8_29_1_3">&#167;8.29.1.3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_29_2" class="paragraph-anchor"></a><b>&#167;8.29.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Sort the components into decreasing order of size</span><span class="named-paragraph-number">8.29.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">LS</span><span class="plain-syntax"> = </span><a href="1-ia.html#SP7" class="function-link"><span class="function-syntax">Indexing::get_list_of_submaps</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAPS</span><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">positioned</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAPS</span><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) </span><span class="identifier-syntax">sorted</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">qsort</span><span class="plain-syntax">(</span><span class="identifier-syntax">sorted</span><span class="plain-syntax">, (</span><span class="identifier-syntax">size_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">ncom</span><span class="plain-syntax">, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *), </span><a href="4-sm.html#SP39" class="function-link"><span class="function-syntax">SpatialMap::compare_components</span></a><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8_29">&#167;8.29</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP39" class="paragraph-anchor"></a><b>&#167;39. </b>The following means the components are sorted in descending size order,
but in order of creation within each size; when we get down to the
singletons, we sort by order of creation of the single rooms they
contain.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::compare_components</span><button class="popup" onclick="togglePopup('usagePopup65')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup65">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::compare_components</span></span>:<br/><a href="4-sm.html#SP8_29_2">&#167;8.29.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ent1</span><span class="plain-syntax">, </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ent2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mc1</span><span class="plain-syntax"> = *((</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> **) </span><span class="identifier-syntax">ent1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mc2</span><span class="plain-syntax"> = *((</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> **) </span><span class="identifier-syntax">ent2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mc2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">population</span><span class="plain-syntax"> - </span><span class="identifier-syntax">mc1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">population</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">d</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mc1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">population</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mc1</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">first_room_in_submap</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mc2</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">first_room_in_submap</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">R1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">R2</span><span class="plain-syntax">)) { </span><span class="comment-syntax"> which should always happen, but just in case of an error</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">reg1</span><span class="plain-syntax"> = </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::region_of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">reg2</span><span class="plain-syntax"> = </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::region_of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">reg1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">reg2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">reg1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">reg2</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">reg1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax"> = </span><span class="identifier-syntax">reg1</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax"> - </span><span class="identifier-syntax">reg2</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">d</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R1</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax"> - </span><span class="identifier-syntax">R2</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">d</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">mc1</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax"> - </span><span class="identifier-syntax">mc2</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP40" class="paragraph-anchor"></a><b>&#167;40. </b>We should define what we mean by "adjoining" and "isolated". The first
means it has a link (which must be IN or OUT) to an already-positioned
component; the second means it has no link at all to any other component.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::component_is_adjoining</span><button class="popup" onclick="togglePopup('usagePopup66')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup66">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::component_is_adjoining</span></span>:<br/><a href="4-sm.html#SP8_29_1">&#167;8.29.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP42" class="function-link"><span class="function-syntax">SpatialMap::no_links_to_placed_components</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::component_is_isolated</span><button class="popup" onclick="togglePopup('usagePopup67')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup67">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::component_is_isolated</span></span>:<br/><a href="4-sm.html#SP8_29_1">&#167;8.29.1</a>, <a href="4-sm.html#SP8_29_1_2">&#167;8.29.1.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP42" class="function-link"><span class="function-syntax">SpatialMap::no_links_to_other_components</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP41" class="paragraph-anchor"></a><b>&#167;41. </b>In theory this has \(O(R^2)\) running time, but it's very unlikely that there
are \(R\) components of size 1, so in practice it's much better than that.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::find_component_placement_heat</span><button class="popup" onclick="togglePopup('usagePopup68')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup68">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::find_component_placement_heat</span></span>:<br/><a href="4-sm.html#SP8_29_1_3_1">&#167;8.29.1.3.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">other</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">LS</span><span class="plain-syntax"> = </span><a href="1-ia.html#SP7" class="function-link"><span class="function-syntax">Indexing::get_list_of_submaps</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAPS</span><span class="plain-syntax">(</span><span class="identifier-syntax">other</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">other</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">positioned</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">SpatialMap::occupied_in_submap</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">other</span><span class="plain-syntax">, </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FUSION_POINT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP42" class="function-link"><span class="function-syntax">SpatialMap::find_cross_component_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">heat</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">FUSION_POINT</span><span class="plain-syntax">) </span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><span class="constant-syntax">FUSION_POINT</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP42" class="paragraph-anchor"></a><b>&#167;42. </b>Where:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::find_cross_component_heat</span><button class="popup" onclick="togglePopup('usagePopup69')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup69">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::find_cross_component_heat</span></span>:<br/><a href="4-sm.html#SP41">&#167;41</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP43" class="function-link"><span class="function-syntax">SpatialMap::cross_component_links</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">heat</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">heat</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::find_link_to_placed_components</span><button class="popup" onclick="togglePopup('usagePopup70')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup70">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::find_link_to_placed_components</span></span>:<br/><a href="4-sm.html#SP8_29_1_3">&#167;8.29.1.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">outer</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">inner</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP43" class="function-link"><span class="function-syntax">SpatialMap::cross_component_links</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">outer</span><span class="plain-syntax">, </span><span class="identifier-syntax">inner</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::no_links_to_placed_components</span><button class="popup" onclick="togglePopup('usagePopup71')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup71">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::no_links_to_placed_components</span></span>:<br/><a href="4-sm.html#SP8_29">&#167;8.29</a>, <a href="4-sm.html#SP40">&#167;40</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-sm.html#SP43" class="function-link"><span class="function-syntax">SpatialMap::cross_component_links</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::no_links_to_other_components</span><button class="popup" onclick="togglePopup('usagePopup72')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup72">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::no_links_to_other_components</span></span>:<br/><a href="4-sm.html#SP40">&#167;40</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-sm.html#SP43" class="function-link"><span class="function-syntax">SpatialMap::cross_component_links</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP43" class="paragraph-anchor"></a><b>&#167;43. </b>So, now we have to define our Swiss-army-knife function to cope with all
these requirements. We not only count non-lattice connections to other
components (IN and OUT links, basically), but also score how bad they are,
if requested, and record the first we find, if requested.
</p>
<p class="commentary">There can't be any lattice connections to other components, because two
rooms connected that way are by definition in the same component.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::cross_component_links</span><button class="popup" onclick="togglePopup('usagePopup73')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup73">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::cross_component_links</span></span>:<br/><a href="4-sm.html#SP42">&#167;42</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">outer</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> **</span><span class="identifier-syntax">inner</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">heat</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">posnd</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax"> = </span><a href="1-ia.html#SP8" class="function-link"><span class="function-syntax">Indexing::get_set_of_instances</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_links</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">heat</span><span class="plain-syntax">) *</span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_NONLATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">d</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R2</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap_cross</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">d</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">R2</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">R2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax"> != </span><span class="identifier-syntax">sub</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">posnd</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">R2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">positioned</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">no_links</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">inner</span><span class="plain-syntax">) *</span><span class="identifier-syntax">inner</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">outer</span><span class="plain-syntax">) *</span><span class="identifier-syntax">outer</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">heat</span><span class="plain-syntax">) *</span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">SpatialMap::heat_sum</span></a><span class="plain-syntax">(*</span><span class="identifier-syntax">heat</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_30" class="function-link"><span class="function-syntax">SpatialMap::find_cross_link_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">R2</span><span class="plain-syntax">, </span><span class="identifier-syntax">d</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_FAUX_ROOMS</span><span class="plain-syntax">(</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax"> == </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">posnd</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">positioned</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_NONLATTICE_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">d</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R2</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">SpatialMap::read_smap_cross</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">d</span><span class="plain-syntax">, </span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">R2</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">R2</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax"> == </span><span class="identifier-syntax">sub</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">no_links</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">outer</span><span class="plain-syntax">) *</span><span class="identifier-syntax">outer</span><span class="plain-syntax"> = </span><span class="identifier-syntax">S</span><span class="plain-syntax">; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">inner</span><span class="plain-syntax">) *</span><span class="identifier-syntax">inner</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">heat</span><span class="plain-syntax">) *</span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">SpatialMap::heat_sum</span></a><span class="plain-syntax">(*</span><span class="identifier-syntax">heat</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_30" class="function-link"><span class="function-syntax">SpatialMap::find_cross_link_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">R2</span><span class="plain-syntax">, </span><span class="identifier-syntax">d</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">no_links</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-sm.html#SP43_1" class="named-paragraph-link"><span class="named-paragraph">Look for van der Waals forces</span><span class="named-paragraph-number">43.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_links</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP43_1" class="paragraph-anchor"></a><b>&#167;43.1. </b>When there are no map connections or locks, there may still be a very weak
bond between rooms simply because they belong to the same region. We only
look at these weak bonds for singleton regions, for simplicity and to keep
running time in check.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Look for van der Waals forces</span><span class="named-paragraph-number">43.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">population</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_room_in_submap</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">) { </span><span class="comment-syntax"> which should always happen, but just in case of an error</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">reg</span><span class="plain-syntax"> = </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::region_of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">reg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, *</span><span class="identifier-syntax">closest_S</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">closest</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_FAUX_ROOMS</span><span class="plain-syntax">(</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">S</span><span class="plain-syntax"> != </span><span class="identifier-syntax">R</span><span class="plain-syntax">) &amp;&amp; (</span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::region_of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">) == </span><span class="identifier-syntax">reg</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">posnd</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">submap</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">positioned</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">diff</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">*(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax"> - </span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">diff</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">diff</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">-</span><span class="identifier-syntax">diff</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">closest_S</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">diff</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">closest</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">closest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">diff</span><span class="plain-syntax">; </span><span class="identifier-syntax">closest_S</span><span class="plain-syntax"> = </span><span class="identifier-syntax">S</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">closest_S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SPATIAL_MAP</span><span class="plain-syntax">, </span><span class="string-syntax">"vdW force between %S and %S\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">closest_S</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">no_links</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">outer</span><span class="plain-syntax">) *</span><span class="identifier-syntax">outer</span><span class="plain-syntax"> = </span><span class="identifier-syntax">closest_S</span><span class="plain-syntax">; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">inner</span><span class="plain-syntax">) *</span><span class="identifier-syntax">inner</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">heat</span><span class="plain-syntax">) *</span><span class="identifier-syntax">heat</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">SpatialMap::heat_sum</span></a><span class="plain-syntax">(*</span><span class="identifier-syntax">heat</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_30" class="function-link"><span class="function-syntax">SpatialMap::find_cross_link_heat</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">closest_S</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="constant-syntax">3</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP43">&#167;43</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_30" class="paragraph-anchor"></a><b>&#167;8.30. </b>"How bad they are" uses another heat-like measure. This one gives an
enormous penalty for being wrong vertically; people just don't like
reading maps where an inside room is displayed on the floor above or below.
It also gives preference to the green jagged arrow directions when placing
insets &mdash; this makes the map line up elegantly.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::find_cross_link_heat</span><button class="popup" onclick="togglePopup('usagePopup74')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup74">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::find_cross_link_heat</span></span>:<br/><a href="4-sm.html#SP43">&#167;43</a>, <a href="4-sm.html#SP43_1">&#167;43.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">dir</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">S</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bad room distance"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-sm.html#SP8_30" class="function-link"><span class="function-syntax">SpatialMap::component_metric</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">), </span><span class="identifier-syntax">dir</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::component_metric</span><span class="plain-syntax">(</span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">P1</span><span class="plain-syntax">, </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">P2</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">dir</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">vector</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP7" class="function-link"><span class="function-syntax">Geometry::vec_minus</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P1</span><span class="plain-syntax">, </span><span class="identifier-syntax">P2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">dir</span><span class="plain-syntax"> == </span><span class="constant-syntax">10</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">dir</span><span class="plain-syntax"> == </span><span class="constant-syntax">11</span><span class="plain-syntax">)) { </span><span class="comment-syntax"> IN and OUT respectively</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">b</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">b</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">b</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">b</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">dir</span><span class="plain-syntax"> == </span><span class="constant-syntax">11</span><span class="plain-syntax">) </span><span class="identifier-syntax">b</span><span class="plain-syntax"> = -</span><span class="identifier-syntax">b</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> += </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">dir</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) { </span><span class="comment-syntax"> SOUTH, the notional direction for van der Waals forces</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">b</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">b</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">b</span><span class="plain-syntax"> += </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">*</span><span class="identifier-syntax">b</span><span class="plain-syntax"> + </span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax">*</span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax"> + </span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax">*</span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax"> + </span><span class="constant-syntax">100</span><span class="plain-syntax">*</span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax">*</span><span class="identifier-syntax">D</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_31" class="paragraph-anchor"></a><b>&#167;8.31. Stage 5, bounding the universe. </b>Short and sweet. We make <span class="extract"><span class="extract-syntax">Universe</span></span> the minimal-sized cuboid containing each room.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(5) Find the universal bounding cuboid</span><span class="named-paragraph-number">8.31</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">Universe</span><span class="plain-syntax"> = </span><a href="4-sg.html#SP10" class="function-link"><span class="function-syntax">Geometry::empty_cuboid</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_FAUX_ROOMS</span><span class="plain-syntax">(</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-sg.html#SP10" class="function-link"><span class="function-syntax">Geometry::adjust_cuboid</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">Universe</span><span class="plain-syntax">, </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">));</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8">&#167;8</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP8_32" class="paragraph-anchor"></a><b>&#167;8.32. Stage 6, removing blank planes. </b>We need to avoid what might be an infinite loop in awkward cases where
locking means that blank planes are inevitable.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">(6) Remove any blank lateral planes</span><span class="named-paragraph-number">8.32</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">safety_count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NUMBER_CREATED</span><span class="plain-syntax">(</span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">safety_count</span><span class="plain-syntax">-- &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">blank_z</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">blank_plane_found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">z</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">z</span><span class="plain-syntax"> = </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">Universe</span><span class="plain-syntax">.</span><span class="element-syntax">corner1</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">z</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">session</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">calc</span><span class="plain-syntax">.</span><span class="element-syntax">Universe</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="identifier-syntax">z</span><span class="plain-syntax">--) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">occupied</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_FAUX_ROOMS</span><span class="plain-syntax">(</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">).</span><span class="identifier-syntax">z</span><span class="plain-syntax"> == </span><span class="identifier-syntax">z</span><span class="plain-syntax">) </span><span class="identifier-syntax">occupied</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">occupied</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">blank_z</span><span class="plain-syntax"> = </span><span class="identifier-syntax">z</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">blank_plane_found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">blank_plane_found</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_FAUX_ROOMS</span><span class="plain-syntax">(</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">).</span><span class="identifier-syntax">z</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">blank_z</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP8_23" class="function-link"><span class="function-syntax">SpatialMap::translate_room</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">D_vector</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP44" class="paragraph-anchor"></a><b>&#167;44. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::index_room_connections</span><button class="popup" onclick="togglePopup('usagePopup75')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup75">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::index_room_connections</span></span>:<br/>Map Element - <a href="3-me.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">RW</span><span class="plain-syntax"> = </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">); </span><span class="comment-syntax"> name of the origin room</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax"> = </span><a href="1-ia.html#SP8" class="function-link"><span class="function-syntax">Indexing::get_set_of_instances</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dir</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_FAUX_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax">, </span><span class="identifier-syntax">dir</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dir</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">direction_index</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">opp</span><span class="plain-syntax"> = </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::opposite_direction</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">dir</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">od</span><span class="plain-syntax"> = </span><span class="identifier-syntax">opp</span><span class="plain-syntax">?(</span><span class="identifier-syntax">opp</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">direction_index</span><span class="plain-syntax">):(-1);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">D</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">S</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">D</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::open_indented_p</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="string-syntax">"tight"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">icon</span><span class="plain-syntax"> = </span><span class="string-syntax">"e_arrow"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">S</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">D</span><span class="plain-syntax">)) </span><span class="identifier-syntax">icon</span><span class="plain-syntax"> = </span><span class="string-syntax">"e_arrow_door"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax">) </span><span class="identifier-syntax">icon</span><span class="plain-syntax"> = </span><span class="string-syntax">"e_arrow_door_blocked"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_TAG_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"img"</span><span class="plain-syntax">, </span><span class="string-syntax">"border=0 src=inform:/map_icons/%s.png"</span><span class="plain-syntax">, </span><span class="identifier-syntax">icon</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&amp;nbsp;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::write_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">dir</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" to "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::write_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" via "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::write_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::write_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" (a door)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">S</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">opp</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">B</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">od</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">B</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" (but "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::write_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">opp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" from "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::write_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" is nowhere)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">B</span><span class="plain-syntax"> != </span><span class="identifier-syntax">R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" (but "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::write_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">opp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" from "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::write_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" is "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::write_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">B</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">fimd</span><span class="plain-syntax">.</span><span class="element-syntax">exits_set_at</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">at</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><a href="2-iu.html#SP2" class="function-link"><span class="function-syntax">IndexUtilities::link</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">at</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_FAUX_DIRECTIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">faux_set</span><span class="plain-syntax">, </span><span class="identifier-syntax">dir</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dir</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">direction_index</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP8_13" class="function-link"><span class="function-syntax">SpatialMap::room_exit</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::open_indented_p</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="string-syntax">"hanging"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;i&gt;add:&lt;/i&gt; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">DW</span><span class="plain-syntax"> = </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">dir</span><span class="plain-syntax">); </span><span class="comment-syntax"> name of the direction</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">DW</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Str::put_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">Characters::toupper</span><span class="plain-syntax">(</span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">)));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">, </span><span class="string-syntax">" from "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">RW</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">RW</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">, </span><span class="string-syntax">"here"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">, </span><span class="string-syntax">" is .[=0x000A=]"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PasteButtons::paste_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&amp;nbsp;%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">DW</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k</span><span class="plain-syntax">&gt;0) </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP45" class="paragraph-anchor"></a><b>&#167;45. Unit testing. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">SpatialMap::perform_map_internal_test</span><button class="popup" onclick="togglePopup('usagePopup76')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup76">Usage of <span class="code-font"><span class="function-syntax">SpatialMap::perform_map_internal_test</span></span>:<br/>Map Element - <a href="3-me.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">index_session</span><span class="plain-syntax"> *</span><span class="identifier-syntax">session</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">connected_submap</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sub</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">LS</span><span class="plain-syntax"> = </span><a href="1-ia.html#SP7" class="function-link"><span class="function-syntax">Indexing::get_list_of_submaps</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAPS</span><span class="plain-syntax">(</span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"Map component %d: extent (%d...%d, %d...%d, %d...%d): population %d\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">corner1</span><span class="plain-syntax">.</span><span class="element-syntax">x</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">corner1</span><span class="plain-syntax">.</span><span class="identifier-syntax">y</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">corner0</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">corner1</span><span class="plain-syntax">.</span><span class="identifier-syntax">z</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sub</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">bounds</span><span class="plain-syntax">.</span><span class="element-syntax">population</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">faux_instance</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_SUBMAP</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">sub</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%3d, %3d, %3d: "</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">).</span><span class="identifier-syntax">x</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">).</span><span class="identifier-syntax">y</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Room_position</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">).</span><span class="identifier-syntax">z</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-fi.html#SP13" class="function-link"><span class="function-syntax">FauxInstances::write_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><a href="2-fi.html#SP11" class="function-link"><span class="function-syntax">FauxInstances::benchmark</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">session</span><span class="plain-syntax">)) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" (benchmark)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-sg.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-im.html">1</a></li><li class="progresschapter"><a href="2-il.html">2</a></li><li class="progresschapter"><a href="3-tpt.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-mc.html">mc</a></li><li class="progresssection"><a href="4-sg.html">sg</a></li><li class="progresscurrent">sm</li><li class="progresssection"><a href="4-rhm.html">rhm</a></li><li class="progresssection"><a href="4-rem.html">rem</a></li><li class="progressnext"><a href="4-rhm.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>