mirror of
https://github.com/ganelson/inform.git
synced 2024-07-08 10:04:21 +03:00
441 lines
62 KiB
HTML
441 lines
62 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>S/wt</title>
|
|
<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="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
<nav role="navigation">
|
|
<h1><a href="../webs.html">Sources</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"><b>extensions and kits</b></a></li>
|
|
<li><a href="../units.html">unit test tools</a></li>
|
|
/ul>
|
|
<h2>Extensions</h2>
|
|
<ul>
|
|
<li><a href="../basic_inform/index.html">Basic Inform</a></li>
|
|
<li><a href="../standard_rules/index.html">Standard Rules</a></li>
|
|
</ul>
|
|
<h2>Kits</h2>
|
|
<ul>
|
|
<li><a href="../BasicInformKit/index.html">BasicInformKit</a></li>
|
|
<li><a href="../BasicInformExtrasKit/index.html">BasicInformExtrasKit</a></li>
|
|
<li><a href="../CommandParserKit/index.html">CommandParserKit</a></li>
|
|
<li><a href="../EnglishLanguageKit/index.html">EnglishLanguageKit</a></li>
|
|
<li><a href="../WorldModelKit/index.html">WorldModelKit</a></li>
|
|
</ul>
|
|
|
|
|
|
</nav>
|
|
<main role="main">
|
|
|
|
<!--Weave of 'S/mpr' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../extensions.html">Kits</a></li><li><a href="index.html">WorldModelKit</a></li><li><b>MapRouteFinding</b></li></ul><p class="purpose">Testing and changing the fundamental spatial relations.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Map Route-Finding</a></li><li><a href="#SP2">§2. Cache Control</a></li><li><a href="#SP3">§3. Fast Route-Finding</a></li><li><a href="#SP4">§4. Slow Route-Finding</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Map Route-Finding. </b>The general problem we have to solve here is: given x, y∈ R, where R
|
|
is the set of rooms and we write x~ y if there is a map connection from
|
|
x to y,
|
|
</p>
|
|
|
|
<ul class="items"><li>(i) find the smallest m such that there exist x = r_1~ r_2~ ...~ r_m = y∈ R,
|
|
or determine that no such m exists, and
|
|
</li><li>(ii) find d, the first direction to take from x to lead to r_2, or
|
|
set d=0 if no such path exists or if m=1 so that x=y.
|
|
</li></ul>
|
|
<p class="inwebparagraph">Thus a typical outcome might be either "a shortest path from the Town Square
|
|
to the Hilltop takes 11 moves, starting by going northeast from the Town
|
|
Square", or alternatively "there's no path from the Town Square to the
|
|
Hilltop at all". Note that the length of the shortest path is unambiguous,
|
|
but that there might be many alternative paths of this minimum length:
|
|
we deliberately do not specify which path is chosen if so, and the two
|
|
algorithms used below do not necessarily choose the same one.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Route-finding is not an easy operation in computation terms: the various
|
|
algorithms available have theoretical running times which are easy (if
|
|
sobering) to compute, but which are not in practice typical of what will
|
|
happen, because they are quite sensitive to the map in question. Are all
|
|
the rooms laid out in a long line? Are there clusters of connected rooms
|
|
like islands? Are there dense clumps of interconnecting rooms? Are there
|
|
huge but possibly time-saving loops? And so on. Overhead is also
|
|
important. We present a choice of two algorithms: the "fast" one
|
|
has a theoretical running time of O(n^3), where n is the number
|
|
of rooms, whereas the "slow" one runs in O(n^2), yet in practice
|
|
the fast one easily outperforms the slow on typical heavy-use cases with
|
|
large maps.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The other issue is memory usage: we essentially have to strike a bargain
|
|
between speed and memory overhead. Our "slow" algorithm needs only
|
|
O(n) storage, whereas our "fast" algorithm needs O(n^2), and this
|
|
is very significant in the Z-machine where array space is in desperately
|
|
short supply and where, if n > 50 or so, the user is already likely to
|
|
be fighting for the last few bytes in readable memory.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The user is therefore offered the choice, by selecting the use options
|
|
"Use fast route-finding" and "Use slow route-finding": and the defaults,
|
|
if neither option is explicitly set, are fast on Glulx and slow on the
|
|
Z-machine. If both use options are explicitly set — which might happen
|
|
due to a disagreement between extensions — "fast" wins.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">FAST_ROUTE_FINDING</span><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">SLOW_ROUTE_FINDING</span><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">TARGET_GLULX</span><span class="plain">;</span>
|
|
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">FAST_ROUTE_FINDING</span><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">ifnot</span><span class="plain">;</span>
|
|
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">SLOW_ROUTE_FINDING</span><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. Cache Control. </b>We provide code to enable our route-finding algorithms to cache their partial
|
|
results from one usage to the next (though at present only the "fast"
|
|
algorithm does this). The difficulty here is that the result of a route
|
|
search depends on three things, any of which may change:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(a) which subset of rooms we are route-finding through;
|
|
</li><li>(b) which subset of doors we are allowing ourselves to use; and
|
|
</li><li>(c) the current map connections between rooms.
|
|
</li></ul>
|
|
<p class="inwebparagraph">We keep track of (c) by watching for calls to <code class="display"><span class="extract">SignalMapChange()</span></code> from the
|
|
routines in "WorldModel.i6t" which alter the map. (a) and (b), however,
|
|
require tracking from call to call what the current subset of rooms and
|
|
doors is. (It is not sufficient to remember the criteria used last time
|
|
and this time, because circumstances could have changed such that the
|
|
criteria produce a different outcome. For instance, searching through
|
|
lighted rooms and using unlocked doors will produce a different result
|
|
if a door has been locked or unlocked since last time, or if a room has
|
|
become lighted or not.) We store the set of applicable rooms and doors
|
|
by enumerating them in the property <code class="display"><span class="extract">room_index</span></code> and by the flags in the
|
|
<code class="display"><span class="extract">DoorRoutingViable</span></code> array respectively.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">NUM_DOORS</span><span class="plain"> = </span><span class="identifier">ICOUNT_DOOR</span><span class="plain">;</span>
|
|
<span class="reserved">Constant</span><span class="plain"> </span><span class="identifier">NUM_ROOMS</span><span class="plain"> = </span><span class="identifier">ICOUNT_ROOM</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">DoorRoutingViable</span><span class="plain"> </span><span class="constant">-</span><span class="plain">> </span><span class="identifier">NUM_DOORS</span><span class="plain">+1;</span>
|
|
|
|
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">map_has_changed</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
|
|
<span class="identifier">Global</span><span class="plain"> </span><span class="identifier">last_filter</span><span class="plain">; </span><span class="identifier">Global</span><span class="plain"> </span><span class="identifier">last_use_doors</span><span class="plain">;</span>
|
|
|
|
<span class="plain">[ </span><span class="identifier">SignalMapChange</span><span class="plain">; </span><span class="identifier">map_has_changed</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">; ];</span>
|
|
|
|
<span class="plain">[ </span><span class="identifier">MapRouteTo</span><span class="plain"> </span><span class="identifier">from</span><span class="plain"> </span><span class="reserved">to</span><span class="plain"> </span><span class="identifier">filter</span><span class="plain"> </span><span class="identifier">use_doors</span><span class="plain"> </span><span class="identifier">count</span><span class="plain"> </span><span class="identifier">oy</span><span class="plain"> </span><span class="identifier">oyi</span><span class="plain"> </span><span class="identifier">ds</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="reserved">nothing</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="reserved">nothing</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="reserved">to</span><span class="plain"> == </span><span class="reserved">nothing</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="reserved">nothing</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="reserved">to</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="reserved">nothing</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">filter</span><span class="plain">) && (</span><span class="identifier">filter</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="reserved">nothing</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">filter</span><span class="plain">) && (</span><span class="identifier">filter</span><span class="plain">(</span><span class="reserved">to</span><span class="plain">) == </span><span class="constant">0</span><span class="plain">)) </span><span class="reserved">return</span><span class="plain"> </span><span class="reserved">nothing</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">last_filter</span><span class="plain"> ~= </span><span class="identifier">filter</span><span class="plain">) || (</span><span class="identifier">last_use_doors</span><span class="plain"> ~= </span><span class="identifier">use_doors</span><span class="plain">)) </span><span class="identifier">map_has_changed</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
|
|
<span class="identifier">oyi</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
|
|
<span class="reserved">objectloop</span><span class="plain"> (</span><span class="identifier">oy</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">filter</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) || (</span><span class="identifier">filter</span><span class="plain">(</span><span class="identifier">oy</span><span class="plain">))) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">oy</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain"> == </span><span class="constant">-1</span><span class="plain">) </span><span class="identifier">map_has_changed</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
|
|
<span class="identifier">oy</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain"> = </span><span class="identifier">oyi</span><span class="plain">++;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">oy</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain"> >= </span><span class="constant">0</span><span class="plain">) </span><span class="identifier">map_has_changed</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
|
|
<span class="identifier">oy</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain"> = </span><span class="constant">-1</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">oyi</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
|
|
<span class="reserved">objectloop</span><span class="plain"> (</span><span class="identifier">oy</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">K4_door</span><span class="plain">) {</span>
|
|
<span class="identifier">ds</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">use_doors</span><span class="plain"> & </span><span class="constant">2</span><span class="plain">) ||</span>
|
|
<span class="plain">(</span><span class="identifier">oy</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">open</span><span class="plain">) || ((</span><span class="identifier">oy</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">openable</span><span class="plain">) && (</span><span class="identifier">oy</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">locked</span><span class="plain">))) </span><span class="identifier">ds</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">DoorRoutingViable</span><span class="plain">-></span><span class="identifier">oyi</span><span class="plain"> ~= </span><span class="identifier">ds</span><span class="plain">) </span><span class="identifier">map_has_changed</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
|
|
<span class="identifier">DoorRoutingViable</span><span class="plain">-></span><span class="identifier">oyi</span><span class="plain"> = </span><span class="identifier">ds</span><span class="plain">;</span>
|
|
<span class="identifier">oyi</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">map_has_changed</span><span class="plain">) {</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">FAST_ROUTE_FINDING</span><span class="plain">; </span><span class="identifier">ComputeFWMatrix</span><span class="plain">(</span><span class="identifier">filter</span><span class="plain">, </span><span class="identifier">use_doors</span><span class="plain">); #</span><span class="identifier">endif</span><span class="plain">;</span>
|
|
<span class="identifier">map_has_changed</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">; </span><span class="identifier">last_filter</span><span class="plain"> = </span><span class="identifier">filter</span><span class="plain">; </span><span class="identifier">last_use_doors</span><span class="plain"> = </span><span class="identifier">use_doors</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">FAST_ROUTE_FINDING</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">count</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">FastCountRouteTo</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">to</span><span class="plain">, </span><span class="identifier">filter</span><span class="plain">, </span><span class="identifier">use_doors</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">FastRouteTo</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">to</span><span class="plain">, </span><span class="identifier">filter</span><span class="plain">, </span><span class="identifier">use_doors</span><span class="plain">);</span>
|
|
<span class="plain">#</span><span class="identifier">ifnot</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">count</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">SlowCountRouteTo</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">to</span><span class="plain">, </span><span class="identifier">filter</span><span class="plain">, </span><span class="identifier">use_doors</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">SlowRouteTo</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">to</span><span class="plain">, </span><span class="identifier">filter</span><span class="plain">, </span><span class="identifier">use_doors</span><span class="plain">);</span>
|
|
<span class="plain">#</span><span class="identifier">endif</span><span class="plain">;</span>
|
|
<span class="plain">];</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. Fast Route-Finding. </b>The following is a form of Floyd's adaptation of Warshall's algorithm for
|
|
finding the transitive closure of a directed graph.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">We need to store a matrix which for each pair of rooms R_i and R_j
|
|
records a_{ij}, the shortest path length from R_i to R_j or 0 if no
|
|
path exists, and also d_{ij}, the first direction to take on leaving
|
|
R_i along a shortest path to R_j, or 0 if no path exists. For the sake
|
|
of economy we represent the directions as their instance counts (numbered
|
|
from 0 in order of creation), not as their direction object values, and
|
|
then store a single word for each pair (i, j): we store d_{ij} + D
|
|
a_{ij}. This restricts us on a signed 16-bit virtual machine, and with the
|
|
conventional set of D=12 directions, to the range 0<= a_{ij}<=
|
|
5461, that is, to path lengths of 5461 steps or fewer. A work of IF with
|
|
5461 rooms will not fit in the Z-machine anyway: such a work would be on
|
|
Glulx, which is 32-bit, and where 0<= a_{ij}<= 357,913,941.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">We begin with a_{ij} = 0 for all pairs except where there is a viable
|
|
map connection between R_i and R_j: for those we set a_{ij}=1 and
|
|
d_{ij} equal to the direction of that map connection.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Following Floyd and Warshall we test if each known shortest path R_{x} to
|
|
R_{y} can be used to shorten the best known path from R_{x} to anywhere
|
|
else: that is, we look for cases where a_{xy} + a_{yj} < a_{xj}, since
|
|
those show that going from R_x to R_j via R_y takes fewer steps than
|
|
going directly. See for instance Robert Sedgewick, Algorithms (1988),
|
|
chapter 32.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The trouble with the Floyd-Warshall algorithm is not so much that it takes
|
|
in principle O(n^3) time to construct the matrix: it does, but the
|
|
coefficient is low, and in the early stages of the outer loop the fact that
|
|
the vertex degree is at most D and usually much lower helps to reduce the
|
|
work further. The trouble is that there is no way to compute only the part
|
|
of the matrix we want: we have to have the entire thing, and that means
|
|
storing n^2 words of data, by which point we have computed not only the
|
|
fastest route from R_x to R_y but also the fastest route from anywhere
|
|
to anywhere else. Even when the original map is sparse, the Floyd-Warshall
|
|
matrix is not, and it is difficult to store in any very compressed way
|
|
without greatly increasing the complexity of the code. This is why we cache
|
|
the results: we might as well, since we had to build the entire memory
|
|
structure anyway, and it means the time expense is only paid once (or once
|
|
for every time the state of doors and map connections changes), and the
|
|
cache is useful for all future routes whatever their endpoints.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">#</span><span class="identifier">ifdef</span><span class="plain"> </span><span class="identifier">FAST_ROUTE_FINDING</span><span class="plain">;</span>
|
|
<span class="reserved">Array</span><span class="plain"> </span><span class="identifier">FWMatrix</span><span class="plain"> </span><span class="constant">--</span><span class="plain">> </span><span class="identifier">NUM_ROOMS</span><span class="plain">*</span><span class="identifier">NUM_ROOMS</span><span class="plain">;</span>
|
|
|
|
<span class="plain">[ </span><span class="identifier">FastRouteTo</span><span class="plain"> </span><span class="identifier">from</span><span class="plain"> </span><span class="reserved">to</span><span class="plain"> </span><span class="identifier">filter</span><span class="plain"> </span><span class="identifier">use_doors</span><span class="plain"> </span><span class="identifier">diri</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> </span><span class="identifier">dir</span><span class="plain"> </span><span class="identifier">oy</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="reserved">to</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="reserved">nothing</span><span class="plain">;</span>
|
|
<span class="identifier">i</span><span class="plain"> = (</span><span class="identifier">FWMatrix</span><span class="plain">-->(</span><span class="identifier">from</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">*</span><span class="identifier">NUM_ROOMS</span><span class="plain"> + </span><span class="reserved">to</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">))/</span><span class="identifier">No_Directions</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="reserved">nothing</span><span class="plain">;</span>
|
|
<span class="identifier">diri</span><span class="plain"> = (</span><span class="identifier">FWMatrix</span><span class="plain">-->(</span><span class="identifier">from</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">*</span><span class="identifier">NUM_ROOMS</span><span class="plain"> + </span><span class="reserved">to</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">))%</span><span class="identifier">No_Directions</span><span class="plain">;</span>
|
|
<span class="identifier">i</span><span class="plain">=0; </span><span class="reserved">objectloop</span><span class="plain"> (</span><span class="identifier">dir</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">K3_direction</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">i</span><span class="plain"> == </span><span class="identifier">diri</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">dir</span><span class="plain">;</span>
|
|
<span class="identifier">i</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="reserved">nothing</span><span class="plain">;</span>
|
|
<span class="plain">];</span>
|
|
|
|
<span class="plain">[ </span><span class="identifier">FastCountRouteTo</span><span class="plain"> </span><span class="identifier">from</span><span class="plain"> </span><span class="reserved">to</span><span class="plain"> </span><span class="identifier">filter</span><span class="plain"> </span><span class="identifier">use_doors</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="reserved">to</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
|
|
<span class="identifier">k</span><span class="plain"> = (</span><span class="identifier">FWMatrix</span><span class="plain">-->(</span><span class="identifier">from</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">*</span><span class="identifier">NUM_ROOMS</span><span class="plain"> + </span><span class="reserved">to</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">))/</span><span class="identifier">No_Directions</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">k</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">-1</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">k</span><span class="plain">;</span>
|
|
<span class="plain">];</span>
|
|
|
|
<span class="plain">[ </span><span class="identifier">ComputeFWMatrix</span><span class="plain"> </span><span class="identifier">filter</span><span class="plain"> </span><span class="identifier">use_doors</span><span class="plain"> </span><span class="identifier">oy</span><span class="plain"> </span><span class="identifier">ox</span><span class="plain"> </span><span class="identifier">oj</span><span class="plain"> </span><span class="identifier">axy</span><span class="plain"> </span><span class="identifier">ayj</span><span class="plain"> </span><span class="identifier">axj</span><span class="plain"> </span><span class="identifier">dir</span><span class="plain"> </span><span class="identifier">diri</span><span class="plain"> </span><span class="identifier">nd</span><span class="plain"> </span><span class="identifier">row</span><span class="plain">;</span>
|
|
<span class="reserved">objectloop</span><span class="plain"> (</span><span class="identifier">oy</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">) </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">oy</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain"> >= </span><span class="constant">0</span><span class="plain">)</span>
|
|
<span class="reserved">objectloop</span><span class="plain"> (</span><span class="identifier">ox</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">) </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ox</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain"> >= </span><span class="constant">0</span><span class="plain">)</span>
|
|
<span class="identifier">FWMatrix</span><span class="plain">-->(</span><span class="identifier">oy</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">*</span><span class="identifier">NUM_ROOMS</span><span class="plain"> + </span><span class="identifier">ox</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">) = </span><span class="constant">0</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">objectloop</span><span class="plain"> (</span><span class="identifier">oy</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">) </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">oy</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain"> >= </span><span class="constant">0</span><span class="plain">) {</span>
|
|
<span class="identifier">row</span><span class="plain"> = (</span><span class="identifier">oy</span><span class="plain">.</span><span class="identifier">IK1_Count</span><span class="plain">)*</span><span class="identifier">No_Directions</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="identifier">diri</span><span class="plain">=0: </span><span class="identifier">diri</span><span class="plain"><</span><span class="identifier">No_Directions</span><span class="plain">: </span><span class="identifier">diri</span><span class="plain">++) {</span>
|
|
<span class="identifier">ox</span><span class="plain"> = </span><span class="identifier">Map_Storage</span><span class="plain">-->(</span><span class="identifier">row</span><span class="plain">+</span><span class="identifier">diri</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ox</span><span class="plain">) && (</span><span class="identifier">ox</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">) && (</span><span class="identifier">ox</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain"> >= </span><span class="constant">0</span><span class="plain">)) {</span>
|
|
<span class="identifier">FWMatrix</span><span class="plain">-->(</span><span class="identifier">oy</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">*</span><span class="identifier">NUM_ROOMS</span><span class="plain"> + </span><span class="identifier">ox</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">) = </span><span class="identifier">No_Directions</span><span class="plain"> + </span><span class="identifier">diri</span><span class="plain">;</span>
|
|
<span class="reserved">continue</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">use_doors</span><span class="plain"> && (</span><span class="identifier">ox</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">K4_door</span><span class="plain">) &&</span>
|
|
<span class="plain">((</span><span class="identifier">use_doors</span><span class="plain"> & </span><span class="constant">2</span><span class="plain">) || (</span><span class="identifier">DoorRoutingViable</span><span class="plain">->(</span><span class="identifier">ox</span><span class="plain">.</span><span class="identifier">IK4_Count</span><span class="plain">)))) {</span>
|
|
<span class="plain">@</span><span class="identifier">push</span><span class="plain"> </span><span class="identifier">location</span><span class="plain">; </span><span class="identifier">location</span><span class="plain"> = </span><span class="identifier">oy</span><span class="plain">;</span>
|
|
<span class="identifier">ox</span><span class="plain"> = </span><span class="identifier">ox</span><span class="plain">.</span><span class="identifier">door_to</span><span class="plain">();</span>
|
|
<span class="plain">@</span><span class="identifier">pull</span><span class="plain"> </span><span class="identifier">location</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">ox</span><span class="plain">) && (</span><span class="identifier">ox</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">) && (</span><span class="identifier">ox</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain"> >= </span><span class="constant">0</span><span class="plain">)) {</span>
|
|
<span class="identifier">FWMatrix</span><span class="plain">-->(</span><span class="identifier">oy</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">*</span><span class="identifier">NUM_ROOMS</span><span class="plain"> + </span><span class="identifier">ox</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">) = </span><span class="identifier">No_Directions</span><span class="plain"> + </span><span class="identifier">diri</span><span class="plain">;</span>
|
|
<span class="reserved">continue</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">objectloop</span><span class="plain"> (</span><span class="identifier">oy</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">) </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">oy</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain"> >= </span><span class="constant">0</span><span class="plain">)</span>
|
|
<span class="reserved">objectloop</span><span class="plain"> (</span><span class="identifier">ox</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">) </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ox</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain"> >= </span><span class="constant">0</span><span class="plain">) {</span>
|
|
<span class="identifier">axy</span><span class="plain"> = (</span><span class="identifier">FWMatrix</span><span class="plain">-->(</span><span class="identifier">ox</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">*</span><span class="identifier">NUM_ROOMS</span><span class="plain"> + </span><span class="identifier">oy</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">))/</span><span class="identifier">No_Directions</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">axy</span><span class="plain"> > </span><span class="constant">0</span><span class="plain">)</span>
|
|
<span class="reserved">objectloop</span><span class="plain"> (</span><span class="identifier">oj</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">) </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">oj</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain"> >= </span><span class="constant">0</span><span class="plain">) {</span>
|
|
<span class="identifier">ayj</span><span class="plain"> = (</span><span class="identifier">FWMatrix</span><span class="plain">-->(</span><span class="identifier">oy</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">*</span><span class="identifier">NUM_ROOMS</span><span class="plain"> + </span><span class="identifier">oj</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">))/</span><span class="identifier">No_Directions</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ayj</span><span class="plain"> > </span><span class="constant">0</span><span class="plain">) {</span>
|
|
<span class="comment">!print "Is it faster to go from ", (name) ox, " to ",</span>
|
|
<span class="comment">! (name) oj, " via ", (name) oy, "?^";</span>
|
|
<span class="identifier">axj</span><span class="plain"> = (</span><span class="identifier">FWMatrix</span><span class="plain">-->(</span><span class="identifier">ox</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">*</span><span class="identifier">NUM_ROOMS</span><span class="plain"> + </span><span class="identifier">oj</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">))/</span>
|
|
<span class="identifier">No_Directions</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">axj</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) || (</span><span class="identifier">axy</span><span class="plain"> + </span><span class="identifier">ayj</span><span class="plain"> < </span><span class="identifier">axj</span><span class="plain">)) {</span>
|
|
<span class="comment">!print "Yes^";</span>
|
|
<span class="identifier">FWMatrix</span><span class="plain">-->(</span><span class="identifier">ox</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">*</span><span class="identifier">NUM_ROOMS</span><span class="plain"> + </span><span class="identifier">oj</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">) =</span>
|
|
<span class="plain">(</span><span class="identifier">axy</span><span class="plain"> + </span><span class="identifier">ayj</span><span class="plain">)*</span><span class="identifier">No_Directions</span><span class="plain"> +</span>
|
|
<span class="plain">(</span><span class="identifier">FWMatrix</span><span class="plain">-->(</span><span class="identifier">ox</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">*</span><span class="identifier">NUM_ROOMS</span><span class="plain"> + </span><span class="identifier">oy</span><span class="plain">.</span><span class="identifier">room_index</span><span class="plain">))%</span>
|
|
<span class="identifier">No_Directions</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">];</span>
|
|
<span class="plain">#</span><span class="identifier">ENDIF</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. Slow Route-Finding. </b>The alternative algorithm, used when only O(n) memory is available,
|
|
computes only some of the shortest paths leading to R_y, and is not cached —
|
|
both because the storage is likely to be reused often by other searches and
|
|
because there is little gain from doing so, given that a subsequent search
|
|
with different endpoints will not benefit from the results of this one. On
|
|
the other hand, to call it "slow" is a little unfair. It is somewhat like
|
|
Prim's algorithm for finding a minimum spanning tree, rooted at R_y, and
|
|
grows the tree outward from R_y until either R_x is reached — in which
|
|
case we stop immediately — or the (directed) component containing R_y
|
|
has been exhausted — in which case R_x, which must lie outside this, can
|
|
have no path to R_y. In principle, the running time is O(dn^2), where
|
|
d<= D is the maximum vertex degree and n is the number of rooms in
|
|
the component containing R_y: in practice the degree is often much less
|
|
than 12, while the algorithm finishes quickly in cases where R_y is
|
|
relatively isolated and inaccessible or where a shortish route does exist,
|
|
and those are very common cases in typical usage. There will be circumstances
|
|
where, because few routes need to be found and because of the shape of the
|
|
map, the "slow" algorithm will outperform the "fast" one: this is why
|
|
the user is allowed to control which algorithm is used.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">For each room R_z, the property <code class="display"><span class="extract">vector</span></code> stores the direction object of
|
|
the way to go to its parent room in the tree rooted at R_y. Thus if the
|
|
algorithm succeeds in finding a route from R_x to R_y then we generate
|
|
the route by starting at R_x and repeatedly going in the <code class="display"><span class="extract">vector</span></code> direction
|
|
from where we currently stand until we reach R_y. Since every room needs
|
|
a <code class="display"><span class="extract">vector</span></code> value, this requires n words of storage. (The <code class="display"><span class="extract">vector</span></code> values
|
|
store only enough of the minimal spanning tree to go upwards through the
|
|
tree, but that's the only way we need to traverse it.)
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The method can be summed up thus:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<ul class="items"><li>(a) Begin with every vector blank except that of R_y, the destination.
|
|
</li><li>(b) Repeatedly: For every room in the domain set, try each direction: if this
|
|
leads to a room whose vector was determined on the last round (not on
|
|
this one, as that may be a suboptimal route), set the vector to point to that
|
|
room.
|
|
</li><li>(c) Stop as soon as the vector from the origin is set, or when a round happens
|
|
in which no further vectors are found: in which case, we have completely
|
|
explored the component of the map from which the destination can be reached,
|
|
and the origin isn't in it, so we can return "no".
|
|
</li></ul>
|
|
<p class="inwebparagraph">To prove the correctness of this, we show inductively that after round n
|
|
we have set the <code class="display"><span class="extract">vector</span></code> for every room having a shortest path to R_y of
|
|
length n, and that every <code class="display"><span class="extract">vector</span></code> points to a room having a <code class="display"><span class="extract">vector</span></code> in
|
|
the direction of the shortest path from there to R_y.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">#</span><span class="identifier">ifndef</span><span class="plain"> </span><span class="identifier">FAST_ROUTE_FINDING</span><span class="plain">;</span>
|
|
<span class="plain">[ </span><span class="identifier">SlowRouteTo</span><span class="plain"> </span><span class="identifier">from</span><span class="plain"> </span><span class="reserved">to</span><span class="plain"> </span><span class="identifier">filter</span><span class="plain"> </span><span class="identifier">use_doors</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">dir</span><span class="plain"> </span><span class="identifier">in_direction</span><span class="plain"> </span><span class="identifier">progressed</span><span class="plain"> </span><span class="identifier">sl</span><span class="plain"> </span><span class="identifier">through_door</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="reserved">nothing</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="reserved">nothing</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="reserved">to</span><span class="plain"> == </span><span class="reserved">nothing</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="reserved">nothing</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="reserved">to</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="reserved">nothing</span><span class="plain">;</span>
|
|
<span class="reserved">objectloop</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">) </span><span class="identifier">obj</span><span class="plain">.</span><span class="identifier">vector</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">;</span>
|
|
<span class="reserved">to</span><span class="plain">.</span><span class="identifier">vector</span><span class="plain"> = </span><span class="constant">1</span><span class="plain">;</span>
|
|
<span class="comment">!print "Routing from ", (the) from, " to ", (the) to, "^";</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="reserved">true</span><span class="plain">) {</span>
|
|
<span class="identifier">progressed</span><span class="plain"> = </span><span class="reserved">false</span><span class="plain">;</span>
|
|
<span class="comment">!print "Pass begins^";</span>
|
|
<span class="reserved">objectloop</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">filter</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) || (</span><span class="identifier">filter</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">)))</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain">.</span><span class="identifier">vector</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">)</span>
|
|
<span class="reserved">objectloop</span><span class="plain"> (</span><span class="identifier">dir</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">K3_direction</span><span class="plain">) {</span>
|
|
<span class="identifier">in_direction</span><span class="plain"> = </span><span class="identifier">Map_Storage</span><span class="plain">-->((</span><span class="identifier">obj</span><span class="plain">.</span><span class="identifier">IK1_Count</span><span class="plain">)*</span><span class="identifier">No_Directions</span><span class="plain"> + </span><span class="identifier">dir</span><span class="plain">.</span><span class="identifier">IK3_Count</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">in_direction</span><span class="plain"> == </span><span class="reserved">nothing</span><span class="plain">) </span><span class="reserved">continue</span><span class="plain">;</span>
|
|
<span class="comment">!print (the) obj, " > ", (the) dir, " > ", (the) in_direction, "^";</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">in_direction</span><span class="plain">)</span>
|
|
<span class="plain">&& (</span><span class="identifier">in_direction</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">)</span>
|
|
<span class="plain">&& (</span><span class="identifier">in_direction</span><span class="plain">.</span><span class="identifier">vector</span><span class="plain"> > </span><span class="constant">0</span><span class="plain">)</span>
|
|
<span class="plain">&& ((</span><span class="identifier">filter</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) || (</span><span class="identifier">filter</span><span class="plain">(</span><span class="identifier">in_direction</span><span class="plain">)))) {</span>
|
|
<span class="identifier">obj</span><span class="plain">.</span><span class="identifier">vector</span><span class="plain"> = </span><span class="identifier">dir</span><span class="plain"> | </span><span class="identifier">WORD_HIGHBIT</span><span class="plain">;</span>
|
|
<span class="comment">!print "* ", (the) obj, " vector is ", (the) dir, "^";</span>
|
|
<span class="identifier">progressed</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
|
|
<span class="reserved">continue</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">use_doors</span><span class="plain"> && (</span><span class="identifier">in_direction</span><span class="plain"> </span><span class="reserved">ofclass</span><span class="plain"> </span><span class="identifier">K4_door</span><span class="plain">) &&</span>
|
|
<span class="plain">((</span><span class="identifier">use_doors</span><span class="plain"> & </span><span class="constant">2</span><span class="plain">) ||</span>
|
|
<span class="plain">(</span><span class="identifier">in_direction</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">open</span><span class="plain">) ||</span>
|
|
<span class="plain">((</span><span class="identifier">in_direction</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">openable</span><span class="plain">) && (</span><span class="identifier">in_direction</span><span class="plain"> </span><span class="reserved">hasnt</span><span class="plain"> </span><span class="identifier">locked</span><span class="plain">)))) {</span>
|
|
<span class="identifier">sl</span><span class="plain"> = </span><span class="identifier">location</span><span class="plain">; </span><span class="identifier">location</span><span class="plain"> = </span><span class="identifier">obj</span><span class="plain">;</span>
|
|
<span class="identifier">through_door</span><span class="plain"> = </span><span class="identifier">in_direction</span><span class="plain">.</span><span class="identifier">door_to</span><span class="plain">();</span>
|
|
<span class="identifier">location</span><span class="plain"> = </span><span class="identifier">sl</span><span class="plain">;</span>
|
|
<span class="comment">!print "Through door is ", (the) through_door, "^";</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">through_door</span><span class="plain">)</span>
|
|
<span class="plain">&& (</span><span class="identifier">through_door</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">)</span>
|
|
<span class="plain">&& (</span><span class="identifier">through_door</span><span class="plain">.</span><span class="identifier">vector</span><span class="plain"> > </span><span class="constant">0</span><span class="plain">)</span>
|
|
<span class="plain">&& ((</span><span class="identifier">filter</span><span class="plain"> == </span><span class="constant">0</span><span class="plain">) || (</span><span class="identifier">filter</span><span class="plain">(</span><span class="identifier">through_door</span><span class="plain">)))) {</span>
|
|
<span class="identifier">obj</span><span class="plain">.</span><span class="identifier">vector</span><span class="plain"> = </span><span class="identifier">dir</span><span class="plain"> | </span><span class="identifier">WORD_HIGHBIT</span><span class="plain">;</span>
|
|
<span class="comment">!print "* ", (the) obj, " vector is ", (the) dir, "^";</span>
|
|
<span class="identifier">progressed</span><span class="plain"> = </span><span class="reserved">true</span><span class="plain">;</span>
|
|
<span class="reserved">continue</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">objectloop</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">) </span><span class="identifier">obj</span><span class="plain">.</span><span class="identifier">vector</span><span class="plain"> = </span><span class="identifier">obj</span><span class="plain">.</span><span class="identifier">vector</span><span class="plain"> &~ </span><span class="identifier">WORD_HIGHBIT</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain">.</span><span class="identifier">vector</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">from</span><span class="plain">.</span><span class="identifier">vector</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">progressed</span><span class="plain"> == </span><span class="reserved">false</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">from</span><span class="plain">.</span><span class="identifier">vector</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">];</span>
|
|
|
|
<span class="plain">[ </span><span class="identifier">SlowCountRouteTo</span><span class="plain"> </span><span class="identifier">from</span><span class="plain"> </span><span class="reserved">to</span><span class="plain"> </span><span class="identifier">filter</span><span class="plain"> </span><span class="identifier">use_doors</span><span class="plain"> </span><span class="identifier">obj</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="reserved">nothing</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">-1</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="reserved">to</span><span class="plain"> == </span><span class="reserved">nothing</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">-1</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> == </span><span class="reserved">to</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">0</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">from</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain"> && </span><span class="reserved">to</span><span class="plain"> </span><span class="reserved">has</span><span class="plain"> </span><span class="identifier">mark_as_room</span><span class="plain">) {</span>
|
|
<span class="identifier">obj</span><span class="plain"> = </span><span class="identifier">MapRouteTo</span><span class="plain">(</span><span class="identifier">from</span><span class="plain">,</span><span class="reserved">to</span><span class="plain">,</span><span class="identifier">filter</span><span class="plain">,</span><span class="identifier">use_doors</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">obj</span><span class="plain"> == </span><span class="reserved">nothing</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="constant">-1</span><span class="plain">;</span>
|
|
<span class="identifier">i</span><span class="plain"> = </span><span class="constant">0</span><span class="plain">; </span><span class="identifier">obj</span><span class="plain"> = </span><span class="identifier">from</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">obj</span><span class="plain"> ~= </span><span class="reserved">to</span><span class="plain">) && (</span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">NUM_ROOMS</span><span class="plain">)) { </span><span class="identifier">i</span><span class="plain">++; </span><span class="identifier">obj</span><span class="plain"> = </span><span class="identifier">MapConnection</span><span class="plain">(</span><span class="identifier">obj</span><span class="plain">,</span><span class="identifier">obj</span><span class="plain">.</span><span class="identifier">vector</span><span class="plain">); }</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="constant">-1</span><span class="plain">;</span>
|
|
<span class="plain">];</span>
|
|
<span class="plain">#</span><span class="identifier">ENDIF</span><span class="plain">;</span>
|
|
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="S-wt.html">Back to 'WorldModel Template'</a></li><li><a href="S-rt.html">Continue with 'RTP Template'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|