~johanvandegriff/ruegolike

f9caeee2647bf025d45a90c97bf81fc85a5b5b61 — Johan Vandegriff 1 year, 5 months ago 1e2ec35
cave level gen and guaranteed stairs reachable (flood fill)
5 files changed, 166 insertions(+), 5116 deletions(-)

D Roguelike Vision Algorithms - Adam Milazzo's Personal Site (2020-05-15 9_27_23 PM).html
D RoguelikeVisionAlgorithms.txt
M display.go
M generate.go
M main.go
D Roguelike Vision Algorithms - Adam Milazzo's Personal Site (2020-05-15 9_27_23 PM).html => Roguelike Vision Algorithms - Adam Milazzo's Personal Site (2020-05-15 9_27_23 PM).html +0 -4832
@@ 1,4832 0,0 @@
<!DOCTYPE html> <html style><!--
 Page saved with SingleFile 
 url: http://www.adammil.net/blog/v125_Roguelike_Vision_Algorithms.html#raycast 
 saved date: Thu May 14 2020 21:27:23 GMT-0400 (Eastern Daylight Time)
--><meta charset=utf-8>
<title>Roguelike Vision Algorithms - Adam Milazzo's Personal Site</title>
<meta name=viewport content="width=device-width, initial-scale=1">
<style>body{box-sizing:border-box;margin:0.5em;background-color:#999;font-family:Verdana,sans-serif;font-size:10pt}*,*:before,*:after{box-sizing:inherit}h1{font-size:150%}h2{font-size:125%}h3{font-size:115%;margin-bottom:0px}h4{font-size:100%;margin-bottom:0px}h1,h2,h3,h4{margin-top:0px}p:first-of-type{margin-top:0px}.left{float:left}.clear{clear:both}header,footer{background-color:#354463;color:white;border:1px solid black}header{margin-bottom:0.25em;padding:0.25em}header h1{margin:0px 0px 0px 0.75em}header aside,header blockquote{text-align:right;font-size:90%}header blockquote{margin:0px}footer{padding:0.125em 0.25em;margin-top:0.25em;font-size:80%;text-align:center}.navbar{width:100%;overflow:hidden;background-color:#5f7797;border:1px solid black}.navbar a{padding:0.375em 1em;float:left;width:auto;display:block;color:white;text-decoration:none}.navbar a{border-right:1px solid #354463}.navbar a:hover,.navbar a.selected{background-color:#354463}.navbar a.selected{font-weight:bold}.mainArea{background-color:#f0f0f0;color:black;padding:0.5em;border:1px solid black;border-top:0px}main.twoCol{width:87.4%;float:right}.sidebar{width:12.5%;min-width:10em}.box{background-color:#5f7797;color:white;border:1px solid black;margin:0px 0.5em 0.5em 0px}.box:last-of-type{margin-bottom:0px}.box A{color:white}.box .title{width:100%;padding:0.25em 0.5em;font-weight:bold;text-transform:uppercase;background-color:#354463}.box .title span::before{content:":: "}.box .content{padding:0.25em 0.5em;font-size:80%;text-align:center}.box .content ul{padding:0px 0px 0px 1em;margin:0.1875em 0px}.box .content li{margin-top:0.375em}.box .content li:first-of-type{margin-top:0px}.code{margin-left:1em;margin-bottom:1em;background-color:#cccccc;clear:both;overflow:auto}.blogPost{background-color:white;padding:0.25em 0.5em;border:1px solid #999}.blogPost>.header{margin-bottom:0.5em}.blogPost>.header h2{margin-bottom:0px}.blogPost>.header .date{color:#666;font-size:85%}.blogPost>.content{padding-bottom:1em;text-align:justify}.comments{margin-top:1em}.comment{background-color:white;padding:0.25em 0.5em;border:1px solid #999;margin-top:1em}.comment .header{margin-bottom:0.5em}.comment .header .title{font-weight:bold}.comment .header .date{color:#666}.comment .poster{text-align:right}form input,form textarea{margin:0.125em 0px}form input[type=text],form input[type=email],form input[type=password],form textarea{width:100%}form textarea{height:10em}@media only screen and (min-width:1200px){form{max-width:40em}}@media only screen and (min-width:769px) and (max-width:1199px){form{max-width:40em}.sidebar{width:20%}main.twoCol{width:79.8%}}@media only screen and (max-width:768px){.hide-small{display:none!important}.navbar a{border:none}header h1,header blockquote{text-align:center;margin:0px}header blockquote{font-size:80%}.sidebar,main.twoCol{width:100%}.box{margin-right:0px;margin-top:1em}.code{margin-left:0px}form,form input[type=submit]{width:100%}ul,ol{padding-left:1.25em}}</style>
<link rel=alternate type=application/rss+xml title=RSS href=http://www.adammil.net/blog/rss.xml><style>.pln{color:#000}@media screen{.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun{color:#660}}pre.prettyprint{padding:2px;border:1px solid #888}</style><link type=image/x-icon rel="shortcut icon" href="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="><style>.sf-hidden{display:none!important}</style><link rel=canonical href=http://www.adammil.net/blog/v125_Roguelike_Vision_Algorithms.html#raycast></head>
<body>
<header>
 <aside class=hide-small>May 14, 2020 18:07:25</aside>
 <h1>Web Rarely</h1>
 <blockquote>The program isn't debugged until the last user is dead.</blockquote>
</header>
<nav class=navbar>
 <a href=# class="menuButton show-small sf-hidden">Menu »</a>
 <span id=menu class=hide-small>
 <a href=http://www.adammil.net/index.html>Home</a>
 <a href=http://www.adammil.net/me.html>Me</a>
 <a href=http://www.adammil.net/art.html>Art</a>
 <a href=http://www.adammil.net/baking.html>Baking</a>
 <a href=http://www.adammil.net/code.html>Code</a>
 <a href=http://www.adammil.net/math/index.html>Math</a>
 <a href=http://www.adammil.net/japanese/index.html>Japanese</a>
 <a href=http://www.adammil.net/blog/index.html class=selected>Rarely</a>
 <a href=http://www.adammil.net/resume.html>Résumé (CV)</a>
 <a href=http://www.adammil.net/contact.html>Contact</a>
 </span>
</nav>
<div class=mainArea>
<main class=twoCol>
<div class=blogPost>
<div class=header>
 <h2>Roguelike Vision Algorithms</h2>
 <span class=date>2014-10-08</span>
</div>
<div class=content>
<style>.simpleTable .green{background-color:#99ff99}.simpleTable .yellow{background-color:#f0ff99}.simpleTable .orange{background-color:#ffcc78}.simpleTable .red{background-color:#ff9999}.sshotc{display:inline-block;text-align:center;vertical-align:top}.sshot{background-color:black;color:#333333;display:inline-block;font-size:16pt;margin:0px}.sshot .red{color:#800000}.sshot .green{color:#008000}.sshot .blue{color:#000080}.sshot .yellow{color:#808000}.sshot .purple{color:#800080}.sshot .cyan{color:#008080}.sshot .gray{color:#808080}.sshot .lt{color:white}.sshot .bddk{color:#660000}.sshot .bdlt{color:#ff3333}.caption{font-size:9pt;text-align:center}</style>
<h3>Table of Contents</h3>
<ol>
<li><a href=#intro>Introduction</a></li>
<li><a href=#props>Desirable Algorithm Properties</a></li>
<li><a href=#survey>Existing Algorithms</a>
 <ol type=a>
 <li><a href=#raycast>Ray casting</a></li>
 <li><a href=#shadowcast>Shadow casting</a> (point-to-tile or point-to-point)</li>
 <li><a href=#diamondwalls>Diamond walls</a> (point-to-tile or point-to-point)</li>
 <li><a href=#halfwidth>Half-width walls</a> (point-to-tile or point-to-point)</li>
 <li><a href=#permissive>Permissive field of view</a> (tile-to-tile)</li>
 <li><a href=#digital>Digital field of view</a> (diamond-to-diamond)</li>
 <li><a href=#mine>My algorithm</a></li>
 </ol>
</li>
<li><a href=#compare>Comparison</a>
 <ol type=a>
 <li><a href=#cmpcorn>Corner peeking</a></li>
 <li><a href=#cmpcorr>Corridor asymmetry</a></li>
 <li><a href=#cmpnarrow>Narrow spaces</a></li>
 <li><a href=#cmpdiag>Diagonal spaces</a></li>
 <li><a href=#cmprooms>Rooms</a></li>
 <li><a href=#cmppillar>Pillars</a></li>
 <li><a href=#cmpsymmetry>Symmetrical versions</a></li>
 <li><a href=#cmpperf>Performance</a></li>
 </ol>
</li>
<li><a href=#code>Code</a>
 <ol type=a>
 <li><a href=#raycode>Ray casting</a></li>
 <li><a href=#shadowcode>Shadow casting</a></li>
 <li><a href=#diamondcode>Diamond walls</a></li>
 <li><a href=#permissivecode>Permissive field of view</a></li>
 <li><a href=#mycode>My algorithm</a></li>
 </ol>
</li>
<li><a href=#further>Further Possibilities</a>
 <ol type=a>
 <li><a href=#nethack>NetHack-style lighting</a></li>
 <li><a href=#lightsources>Light sources</a></li>
 <li><a href=#falloff>Light falloff</a></li>
 <li><a href=#colored>Colored lighting</a></li>
 </ol>
</li>
</ol>
<a name=intro></a>
<h3>Introduction</h3>
<p>One task when implementing a roguelike is to figure out how to compute the region of the dungeon that's visible to the
player or another monster. There are many existing algorithms, but they all have flaws, so I set out to develop a new
algorithm that is fast, exact, and aesthetically pleasing to me. Although I didn't create a perfect algorithm, I still
think my algorithm is an improvement over the others.</p>
<p>The visible region is called a monster's <i>field of view</i>, and determines whether the monster can see a
particular part of the dungeon terrain. I'll assume that the dungeon is tile-based, which is usual. Whether the player
can see a tile (called having <i>line of sight</i> and abbreviated LOS) is occasionally different from whether the
player can see a monster in that tile, and frequently different from whether he can target that monster with a ranged
weapon or spell (called having <i>line of targeting</i> here and abbreviated LOT).</p>
<a name=props></a>
<h3>Desirable Algorithm Properties</h3>
I'll first describe some frequently desirable traits of a field-of-view algorithm and then show why most existing
algorithms lack one or more of these traits.
<ul>
<li><b>Symmetry:</b> If you can see tile B while standing on tile A, then you should be able to see tile A when
 standing on tile B. This is generally considered desirable, partly because it's fair, and partly because the
 asymmetry in vision that almost all asymmetrical algorithms produce leads to poor tactical gameplay when the line of
 targeting is the same as the line of sight (as is normally the case). An algorithm that manages to be asymmetrical in
 the opposite of the normal way might actually be better than a symmetric algorithm.
</li>
<li><b>Expansive walls:</b> When standing in a (convex) room, you can see all of the room's walls, and when standing in
 a long corridor you can see all the wall tiles along the sides of the corridor. Although it rarely affects gameplay
 tactics much, it looks ugly and can make exploration tedious if an algorithm does not have this property.
</li>
<li><b>Expanding pillar shadows:</b> When sight is blocked by a pillar (an opaque tile not connected to others), the
 pillar should cast a shadow in the shape of a circular sector. This usually allows for more tactical gameplay, since
 it's easier to hide from, ambush, and escape other monsters. However, many roguelikes don't generate pillars, making
 this less relevant for them.
</li>
<li><b>No blind corners:</b> You can see at least two tiles around a corner, so that if you move diagonally around the
 corner, you won't find yourself next to (and being gored by) a monster you couldn't see. This also implies that you
 can see at least two tiles to either side before stepping into a hallway. This is desirable in most cases, since it's
 tedious if players must step carefully around every corner. Some algorithms allow you to see infinitely far around
 corners, protecting you from monsters with ranged weapons as well.
</li>
<li><b>No artifacts:</b> Although there can be reasonable disagreement over what the "right" behavior is for a
 field-of-view algorithm, an algorithm should at least do what it's supposed to. Generally this means that the
 algorithm should define the world geometry and accurately model light propagation within that geometry. The main
 causes of artifacts are the algorithm simply not corresponding to the world geometry, the algorithm being implemented
 using approximate rather than exact math, and bugs in the implementation.
</li>
<li><b>Efficiency:</b> The algorithm shouldn't take a long time, and preferrably should avoid testing the same tiles
 repeatedly.
</li>
</ul>
<a name=survey></a>
<h3>Existing Algorithms</h3>
<p>This is not an exhaustive list of algorithms, but covers the most frequently used ones.</p>
<a name=raycast></a>
<h4>Ray casting</h4>
<b>Pros:</b> Simple. Pretty fast. Expanding pillar shadows. Good balance of light and shadow. No blind corners.
<b>Cons:</b> Asymmetrical. Lots of gaps. No expansive walls. Quirky.
<p>Ray casting involves casting rays from the player to every point along the edge of the map or every point along the
circumference of the player's view radius. The rays are cast using a simple line-drawing algorithm, usually <a target=_new href=https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm>Bresenham's</a>, which stops as soon as
it hits a wall. Ray casting is the simplest algorithm, and quite fast, but it has numerous problems. First, it's highly
asymmetrical. Bresenham's algorithm isn't symmetrical, but even if you use a symmetrical line-drawing algorithm (which
causes its own problems), the result will still be asymmetrical because the endpoints of the lines aren't simply
reversed when you alternate positions. The algorithm also has gaps in both visible points and shadows and is generally
very quirky. Gaps in the walls can be fixed up in a post-processing pass, which removes the ugliest artifacts, but this
slows the algorithm and doesn't fix the other problems. The algorithm tests tiles multiple times, making it somewhat
inefficient, but due to its simplicity it still ends up being pretty fast, especially with a small sight radius. (Ray
casting has a reputation for being the fastest algorithm by far, but that's mainly due to people's generally poor
implementations of more complex algorithms. A well-implemented shadow casting algorithm beats ray casting every time.)
Leaving aside the numerous gaps and asymmetries and just considering the shapes of light and shadow, ray casting
produces nicer results in my opinion than more complicated algorithms like shadow casting and diamond walls. Also, most
of its problems become less severe as the sight radius decreases, and with a circular sight radius of 4 or less it
actually works very nicely, with no post-processing required (although some artifacts remain).</p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>───────────</span>─<span class=lt>─</span>─<span class=lt>─</span>──<span class=lt>─</span>─┤
<span class=lt>∙@∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>─────┬┬─∙┌┬</span>─<span class=lt>─</span>┐<span class=lt>∙∙∙∙∙+</span>
     ├┘∙∙└┤  └─────┤
</pre>
<div class=caption>Gaps in walls<br>(can be fixed with post-processing)</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙@∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙┼</span>∙<span class=lt>∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙</span>∙∙
</pre>
<div class=caption>Gaps in shadow</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙@∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙┼∙┼∙┼∙∙∙∙</span>
∙∙∙<span class=bddk>∙</span><span class=lt>∙∙</span>∙<span class=lt>∙∙<span class=bdlt>∙</span></span>∙∙∙
∙∙<span class=lt>∙∙∙</span>∙∙∙<span class=lt>∙∙∙</span>∙∙
</pre>
<div class=caption>Shadow asymmetry</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>──────────</span>─<span class=lt>─</span>─<span class=lt>─</span>──<span class=lt>─</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>─────┬┬─∙┌</span>┬<span class=lt>─</span>─<span class=lt>┐</span><span class=bddk>∙∙</span><span class=lt>∙</span>
     ├┘∙∙└┤  └───
</pre>
<div class=caption>More gaps (see next two)</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>───────────</span>─<span class=lt>─</span>─<span class=lt>─</span>──
<span class=lt>∙@∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>─────┬┬─∙┌┬</span>─<span class=lt>─</span>┐<span class=lt><span class=bdlt>∙∙</span>∙</span>
     ├┘∙∙└┤  └───
</pre>
<div class=caption>Shadow disappears</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>────────────</span>─<span class=lt>─</span>─<span class=lt>─</span>─
<span class=lt>∙∙@∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>─────┬┬─∙┌┬─</span>─<span class=lt>┐</span><span class=bddk>∙</span><span class=lt><span class=bdlt>∙</span>∙</span>
     ├┘∙∙└┤  └───
</pre>
<div class=caption>Shadow partly reappears</div>
</div>
<p></p>
<p>Code to implement ray casting is <a href=#raycode>below</a>.</p>
<a name=shadowcast></a>
<h4>Shadow casting (point-to-tile or point-to-point)</h4>
<b>Pros:</b> Fast. Expanding pillar shadows. Expansive walls. Continuous point visibility.
<b>Cons:</b> Diagonal vision much narrower than cardinal. Blind corners. Beam expands too much through a door.
Asymmetrical. Nontrivial to eliminate all artifacts.
<p>Shadow casting is the technique of casting circular sectors of light outward from the player. When a sector hits a
wall, the sector may be reduced in angle or split into two sectors which are then processed independently.
Implementations vary, but a good implementation will visit each tile only once, or nearly so, and a small and roughly
constant amount of work is done per tile. This makes shadow casting one of the fastest algorithms if implemented well,
but in poor implementations it can perform relatively slowly in diagonal tunnels and in open areas with lots of small
obstructions. "Shadow casting" is a bit of a misnomer because what's actually cast is light, but I'll use it since
"light casting" seems too similar to "ray casting". In every case I've seen, shadow casting has used square tiles, but
other tile shapes are possible.</p>
<p>In the usual implementation, shadow casting renders a tile visible if there is an unobstructed line from the center
of the player's tile to any part of the target tile. Here's an example to illustrate how shadow casting works for a
single octant. (Not all implementations work in octants.) In the first picture, a 45-degree sector of light is projected
down the 45-degree octant. The green line bounds the top of the sector and the blue line bounds the bottom. The
fractions displayed are the slopes of the lines, which are always from 0 to 1 (inclusive). Tiles with circles are
considered visible. Then, the algorithm works from left to right (increasing X). For each column, it scans from the top
tile within the sector down to the bottom tile within the sector. If a transition from clear to opaque or vice versa is
found, the sector is adjusted. In the second picture, the first three columns have been scanned and a transition from
opaque to clear has been found in the fourth column, so the top vector is adjusted downward. In the next picture, a
clear-to-opaque transition has been found and the bottom vector is adjusted upward. In the final picture, you can see
that both types of transitions were found in the fifth column, so the sector splits into two sectors, each of which
continue independently. The algorithm stops when it hits the maximum sight distance or all the sectors become empty
(bottom slope &gt; top slope).</p>
<p><img src=data:image/png;base64,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> <img src=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAMAAAAJixmgAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAAUABAQAAA8BCQkAEREAGRkAICAAKioAMTEAOTkAPz8/AABIAAB0AEsIAH8NBH8NCH8NAnsQBX8TB38VFn8LEn8eFn8iG38mJH8JLH8JJ38xL384M388Nn8+AEhIOX9BSAAAdAAASABISAB0dABIdAB0QkIASEgATEwAU1MAWFgARX8GS38FUX8FX38DYWEAa2sAZH8CcnIAe3sAS39QTX9SUX9WVX9ZSHR0Z2dnZX9nZ39pa39tb39wd3d3cX9ydX92eX95fn9+ABOAACaBACb/BCj/Ci7/ETP/Gzz/AEicAFKGAHS/P1KAP1K/KWeuL2qzIED/LEr/ME7/NFH/OFX/PFj/SEicQVSDR1qPS16XRVa5V2qve3yDSmT/UGn/WnH/Y3bHZHr/aH7/A4ARBIARCIIUDIQYEYAPEIYcFIUZE4gfFIkgG4okHI0oLoUWKIkfII4rJJAvKpM1MJY6NJk/OZtDQ4EKTIEKQYYWQ4wjQ5Y3epAjQJ5JRKBNTKRVUKZZVKhcWKthbalaYK5oZLBsaLJva7RycLd3dLl7eLt/fL2DSJzgb4LfbIH/c4bncYrxe473eo79fpH+dL//nEgAv3QAnEhIgIAAhIQIhI4eiIgQjIwYipImkJAglJQomJgwnJw4v5xIoKBApKRIqKhQrKxYsLBgtLRouLhwvb164JxI/790gICAi5v/k6L/nqv/o7D/q7f/r7r/s73/g8CJh8KNi8SQj8aVlMCHk8iYm8yfm8ygusKGo9CnpdGpq9SvrNStr9ays9i2t9q6u9y+v+CcnOD/v97Cv8j/v///4L+/w8OHxsaOy8uXz8+fwti0yti009On19ev0tm039+//+Cc//+/wsLCz8/PxMv/z9X/1dr/29//w+DFx+LKy+TNz+bR2ODC0+jU1+rY2+zc3+7g3+P/4+PH5+fP6+vX7+/f4+b/5+r/6+3/4/Dk5/Hm5/Lo7fXu4P//7/D/8/Pn9vbu///g9fb/9Pj0+/v3+/v/+/z7////AAAAGff12wAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuM4zml1AAAA3zSURBVHhe7Z0LnBVVHcdvBCJLdSxMtFKTUhB6LLIVYT5iawkwKMpHL820XaKAWtnoJfIIRIGsQNZDkIsS+Ni1zFSMSAnU0ETShFVSzBBQCcEVgcWdT+fxn7lzZs6ZM3dn7uy8vp+Pe8/cv3fufO/MnLn3/jjnFgyRYXcknN7VngxzClfD4xJLNYgoqM6F4XGJJRcWyYVz4aSRC4vkwhkRPrS4UFjAWhkRbhz9+tYP/J3dAY9LLL6EW09lspRsCG/94KNsiZAN4ZbRNxcK1/M74HGJxZ8w6bEydQ63vP1R0lGzXZydczhTwkbjAraX6R3wuMTiT5i+8chSp2UjF04aubBILpwLJ41cWCQXzoWTRqnC58DjEosmLj3HKRz7fFgj1Dt1+bDukE3dOZwLi+TCDnLhXDhu5MIiubCDrAo3FwqFhHwvHY5wI/9SmpAN4UM3JCcfDkW49dQBhbdx52wI06i0OVPnMKG1XzLSw9CEkxKXhreH+T9syYYwzYYbR7/O7oD1xpZw9jB548H7rAwd0kAuHDdyYZFc2EEunHbh4RkTfqFvtoRX16IsCe+7CqH3Z0h4/UQ0+SFXpxX7fLizcenwExF676djmA8HzH9V9TOPQ30+Rm7jlw8HOEcp8nrHvbXohy/SVvyuw+UQ3jcN1c7rYM1MCK+bgCZvhHYGhNtnITSzDRYyIPx8PRq/FtqEtAt33FOLpu6CBUrKhXdNRbXzeW8FpFv4gQmofju0gTQLt5HeapbVWwEpFt5ejyY8AO0iljCMxEuNcMd8R28FWMKNcUkPwxHeSXqre1jLgSnccnKq9vDa8aj+ebbsBIRbT3s4RcJtMxGa0w53OADh5gUp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> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAMAAAAJixmgAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAACQkAABUHEREAGRkAAAUoICAAKioAMTEAOTkAPz8/AABIAAtQAAB0ABF0AH4OC38MB3YUBH8SDX8aE38LEX8dFn8iGn8lHn8pJH8KN38HJ38xK381NX89AEhIAFF+PX9ESAAAdAAASABISAB0dABIdAB0QkIASkoAU1MAWFgAQX8GXX8DYWEAa2sAYn8DcnIAdX8AensAc3cYTFx0RH9KTH9RW2ZIU2BYUX9WU39YW39fSHR0X39iZ2dnY39lZ39pan9sb39wd3d3dn92fn9+GC+zHDnHHzzeCi3rACb+DDD/FzblFDf/IT7ZAEicBkqpAHS/Ok6LL0m+J0LVNkzGPVPDJEvsJ0b+ME7/N1T/SEicQFOGR1i3UV6tV2KnY2ubbXKRdXeJQl3/V2zNSmT/UWv+WXH/aHrJZHv+A4APBIARCIIUDIQYEYAPE4ITEIYcFIkgGYslHI0oK4ccI4ohII4rJJAvJJEwKZM0MJEwMJY6M5g+O5Y5OZtDQIELQ4gZWoIJUIYTbowbaI0gdZs8Q5xFQJ5JRKBNTqFNSqNTUKZZVKhcWathYK5oZLBsaLJvarRycLd3dLl7eLt/fb2DSJzgbIH/dYn/f5H/dL//nEgAv3QAnEhIgIAAhIQIiIgQi4wYiJIlkJAglJQomJgwnJw4gYZCha1hv5xIoKBApKRIqKhQrKxYpKdpq7FjsLBgtLRouLhwvb164JxI/790gICAgL6FqrCeh5bYiZr/mqfel6b/pbDcqbX/s73/hcGLiMKNjMSSlMiZm8yfm8ygusOJscuao9CnpNCpq9Svr9ayuNCks9i2t9q6u9y+v+CcnOD/v97Cu8T/v///4L+/w8OHxsaOy8uXz8+f09On19ev39+//+Cc//+/yMjIxc3+zdT/1tv/w+DFx+LKy+TNz+bR2eLH0+jU1+rY2+zc3+7g3uL+4+PH5+fP6+vX7+/f5+r/5PDk5/Lo7fXt4P//7/D/8/Pn9vbu///g8/T/9Pj09/j/+/v3/v7+AAAAJHBP7QAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuM4zml1AAABEiSURBVHhe7Z17fBTFHcAPsQj2MRasWqsWaVWgDWKqta0VfKWPYKQPsIBFEBpoXpWA5QMNpS9bKA+VIhA0LqLRVqqtj4S2aRoo1FagqCVW1EKEgIhJVIgRgch+Oo/f7M4+Zndvd+9yu3ffP7jZ+7F3+83szs7ub3YuoRoZsT7inFrgyAizcAGsF1kKQERCQU4Y1ossOWEjOeGccNTICRvJCWeJ8LF7E4mVtJQlwjWj3939qf/QN2C9yOJJuOUCKkvIDuHdn36BLmGyQ7h+9COJxD3sDVgvsngTxi1WVh3D9R9+ATfUtIqz5xjOKmG1ZiWtZfIGrBdZvAmTjkc2NVoCOeGokRM2khPOCUeNnLCRnHBOOGokK3wtrBdZXNKl15qFMz4/7CJ0auzyw267bOyO4ZywkZywiZxwTjjTyAkbyQmbyFbhukQiEZH70uEI17Cb0pjsED52X3Tyw6EIt1wwOPFB5pwdwiRVWpdVxzCmZVA0soehCUclXRpeDbOBLdkhTHLDNaPfpW/A52Ys4dQw7niwNiuLdmkgJ5xp5ISN5IRN5IRzwplGQOGrskx4U/+sEu5cVIqySXhbJaq8wiyc8flh/+nScxH6xHWZlx8OmP+Vxkd+DPX/fCbmh4McoxhZfGMZmteGXzPvtJQS4fb5qOxuWsoO4S0z0Ox9rJgNwl1LEVraBQtZILxjFpqxBcrZIHx3GVrQDmVM3IXfqEJlG6FMibnw5go09zUoM2It3IW7zsu6YQGIs/D2yrLKbVDW0IThSbz4CHcvQ6WL3oEFHU24JlOyhyEJH6hC5ZtZ0QAXrj8vXjW8qQxVHaQlEyDccuHzcRLuXIjQclNrBYBw3co4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">
<img src=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAMAAAAJixmgAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAFhYAAAUoADYFADw0JCQANjYAPz8/AAFHAAB0ABF0AH4OB34WFWgeFn8LEX8dAHYiBnU3Gn8lI38JOn8HIn0qKn8zMn87AEhIAlZ6AGpFAGNZCXBLOn9CSAAAdAAASABISAB0dABIdAB0R0cAVlYAR38FWH4EZmYAaH8Cd3gAdHgVYms5bXMkUV9cTFtmRldyRH5LS39QXWhEU2BYVX9aSHR0VGNpX39iZ2dnY29uZ39pb35yd3d3dH91fn9+ABaXABy/AD+6AB7LADvHCDzWGjfLGzndBSvsASb+BzLlDTH9FDToFTf+Ij7bAEibB1CKAEamAHS/IU+JOE2PNEuYPVGFO1GdKEKtK0i5M0u0N1C9KnWDJmSuJ0HVLFnYNkzHO1XdJUPhJkb+ME7/OFX/SEicQFOGT12vRVa4UV6tUmSOX2ifTWK5V2OmZGyZb3OPbHGRdniHRVzJQlzcQFvvQV3+V2zNUmnURGnlSWT9U2vmUmv+WnL/ZXrpY3r/CYAPB4IUEIYcGIokGYM8IoEOJoQUNYELN4UWII4rJ5AvKJIzPoshMZc7OZtDSoUTUIIKU4gYQJQyWZY2ZpYyc48iQJ5JW59GRKBNSqNTV6BLUadaWKphf4RGYK5oZbFtabNxd7Jtdbl8WpuQTIKvcoK+fr2ESJzgbIH+cIPrdYn/fpH+dL//nEgAv3QAnEhIgIAAiooUhZAnk5Mmmpo0iY5amZ5zjKhUmKRJmLd0v5xIoKBBqalTs7Nmu7t24JxI/790gICAlZ6ri7ivubuMs7eUiZr+mKf/mrTgpLjpqbX/s73/hcGLjMSSlcmanc2iq8OKvcOIpc6ip9Ksr9aysdWvt9q6v+CcnOD/ucXYv97Cu8T+v///4L+/xcWMzc2bx9Opy9m11NSp3t6+/+Cc//+/yMjIxc3+zdT/1dv/x+LJz+bR2uHE1+rZ3u3g3eL/5eXL7e3b5+jg5+r+6fPq6vX/8/Pn9vbu///g9PT/9fn19/j/+/v3/v7+AAAAAAAAiyiaWwAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuM4zml1AAABhGSURBVHhe7V0PdBTHeRdNwW73Wjc0hth9xK0DAQs7ie1HYz8c1KZpYItlkrZJkzalNKC0pC3YaktaVSq7ujoNKFLauqVQqZaitqBArJyM+y/CBrWJlAohmoin1CiFJkCQhCWMdATrYN/r9818szv7Z3bvdHeSDt3P7/lm72NW+9PMfPPN/PYblVhuPN5V4LijLBSPewmXUb2CRRkRUaCsSJjqFSyKhN0oEi4SLjQUCbtRJDxPCL/xQknJIVaaJ4TbN12/+JP/w76gegWLtAhfup+RRcwPwhd/6tvsCjA/CJ/Y9JWSki/xL6hewSI9wuCx5tUYPvFD3wZHzZp4/ozheUXYaj/EWhm/oHoFi/QIY+Axn5yWhCLhQkORsBtFwkXChYYiYTeKhIuECw2ZEn4v1StYRMil7/USnvP6cAShO247fTiqy952Y7hI2I0iYQ+KhIuE5xqKhN0oEvZgvhI+XlJSUiD70rkh3M43pQHzg/AbXy4cfTgnhC/dv7zkTs55fhBGqfT4vBrDgEv3FYZ6mDPChSKX5q6F+Yst84MwasPtm66zL+i+cxa5aWEIPLjPmkddmlAkPNdQJOxGkbAHRcJFwnMN2RFOLZ1fhEfjxrwi3Gcai+cR4fEGzTzoG8NzXh+etly6JhaLPTYH9eEs9V+Vfd0STVuyrmsO6sPZjFGAwj66R6sdwMLcm5byQrjV1BrGWWleEB6rN8w+Ks8HwqdNs26UyvOAcLJRM5pTdDEPCA/GtTjzVoTCJjxx/pXOzpfPv06XCDfhVKtp7E/SBUNBEz6XYChNvHKLvvEQHqvXzFNUJhQw4VudiUTnKxcunDuWKD1qN7JMuN/U6q5QWaCA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></p>
<p>Here are some of the features and problems of shadow casting (with the usual square tiles).</p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙@┼</span>∙∙∙∙∙
<span class=lt>∙∙∙┼∙</span>∙∙∙∙∙
<span class=lt>∙∙</span>┼∙∙<span class=lt>∙</span>∙∙∙∙
<span class=lt>∙</span>┼∙∙∙∙<span class=lt>∙</span>∙∙∙
┼∙∙∙∙∙∙<span class=lt>∙</span>∙∙
</pre>
<div class=caption>Thin diagonal spaces</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙@┼</span>∙∙∙┼∙
<span class=lt>∙∙∙∙∙</span>∙∙∙∙∙
<span class=lt>∙∙∙∙┼∙</span>∙∙┼∙
<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙</span>∙∙∙
<span class=lt>∙∙∙∙∙</span>∙∙<span class=lt>∙</span>∙∙
</pre>
<div class=caption>In this case too</div>
</div>
<div class=sshotc>
<pre class=sshot>───<span class=lt>─────</span>───
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
──┬┬<span class=lt>─@┌</span>┬───
  ├┘<span class=lt>∙∙└</span>┤   
 ┌┘<span class=lt>∙∙│∙</span>└┐  
</pre>
<div class=caption>Has blind corners</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>───────────</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>─────┬┬─∙┌┬</span>
     ├┘∙∙└┤
    ┌┘∙∙│∙└
</pre>
<div class=caption>Asymmetrical<br>(compare w/ previous)</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙</span>∙∙∙
<span class=lt>∙∙∙∙∙┼∙∙∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Gaps in pillar shadows<br>(not an artifact, just ugly)</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙</span>∙<span class=bdlt>∙∙</span>∙│ 
<span class=lt>∙∙∙∙┼∙│</span>∙∙│ 
<span class=lt>∙∙∙∙∙∙│∙∙│</span> 
<span class=lt>∙∙∙∙∙∙∙∙∙└</span>─
<span class=lt>∙@∙∙∙│</span>∙∙∙∙∙
</pre>
<div class=caption>Red shouldn't be visible<br>(implementation artifact)</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙│</span>                   │∙∙∙∙∙∙∙∙∙∙∙
<span class=lt>∙└───────────────────┤∙∙∙∙∙∙∙┼∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙■∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───────┬┬─∙┌┬────────┤∙∙∙∙∙∙∙┼∙∙∙</span>
       ├┘∙∙└┤        │∙∙∙∙∙∙∙∙∙∙∙
</pre>
<div class=caption>Always a three-high beam through a door, and the beam isn't blocked by pillars<br>
 (not an artifact, but very ugly)
</div>
</div>
<p></p>
<p>The asymmetry displayed above is an example of how asymmetrical algorithms tend to create unsatisfying tactical
situations. If you can target what you can see, then the monster in the middle of the corridor would have an advantage
over a monster on the side of it, despite the monster on the side appearing to have better cover. The monster on the
side could be shot without even seeing the attacker. Asymmetries like these are why symmetry is considered a desirable
property. However, if the asymmetry was reversed, it might actually be an improvement over symmetrical algorithms by
allowing you to take cover, giving a more tactical feel to the gameplay (although it would probably be best if the
visibility was symmetrical but not the targeting). There is an algorithm called "reverse shadow casting" which reverses the asymmetry, but it generally looks much poorer and runs much slower.</p>
<p>A small modification to the shadow casting code suffices to make it symmetrical, though. This works by changing the
algorithm so it considers a tile visible only if there's an unobstructed line from the center of the player's tile to
the center of the target tile (rather than any part of the target tile). This fixes some problems and causes others, as you can see below.</p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>──</span>─────────
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>──</span>───┬┬─∙┌┬
     ├┘∙∙└┤
    ┌┘∙∙│∙└
</pre>
<div class=caption>Symmetrical,<br>no expansive walls</div>
</div>
<div class=sshotc>
<pre class=sshot>    ┌<span class=lt>─────</span>─
    │<span class=lt>∙∙∙∙∙∙</span>
    │<span class=lt>∙∙∙∙∙∙</span>
    <span class=lt>│∙∙∙∙∙∙</span>
    <span class=lt>│@∙∙∙∙∙</span>
</pre>
<div class=caption>No expansive walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙</span>∙
<span class=lt>∙∙∙∙∙∙∙</span>∙∙∙∙
<span class=lt>∙∙∙∙∙┼</span>∙∙∙∙∙
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>No shadow gaps</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙</span>∙∙∙∙∙│ 
<span class=lt>∙∙∙∙┼</span>∙<span class=lt>│</span>∙∙│ 
<span class=lt>∙∙∙∙∙∙│</span>∙∙<span class=lt>│</span> 
<span class=lt>∙∙∙∙∙∙∙∙∙</span>└─
<span class=lt>∙@∙∙∙│</span>∙∙∙∙∙
</pre>
<div class=caption>Artifact is gone</div>
</div>
<div class=sshotc>
<pre class=sshot>   │∙∙∙∙∙∙∙∙∙∙<span class=lt>∙</span>∙∙∙∙∙∙
<span class=lt>──</span>─┤∙∙∙<span class=lt>∙∙∙∙┼</span>∙∙∙┼∙∙∙∙∙
<span class=lt>@∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>──</span>─┤∙∙∙<span class=lt>∙∙∙∙┼</span>∙∙∙┼∙∙∙∙∙
   │∙∙∙∙∙∙∙∙∙∙<span class=lt>∙</span>∙∙∙∙∙∙
</pre>
<div class=caption>Better propagation through narrow spaces</div>
</div>
<p></p>
<p>Code to implement basic shadow casting is <a href=#shadowcode>below</a>.</p>
<a name=diamondwalls></a>
<h4>Diamond walls (point-to-tile or point-to-point)</h4>
<b>Pros:</b> Pretty fast. Expanding pillar shadows. Expansive walls. No blind corners. Mostly continuous point visibility.
<b>Cons:</b> Beam expands too much through a door. Asymmetrical; a small change fixes this but loses expansive walls and
causes more visual discontinuities.
<p>Like shadow casting, the diamond walls algorithm treats a tile as visible if there's an unobstructed line from the
center of the player's tile to any part of the target tile. However, for the purpose of occlusion it treats walls as
though they were diamonds (embedded in the tile, the remainder being empty space). This eliminates the thin diagonal
spaces from the standard shadow casting algorithm and allows better peeking around corners, but it causes a couple
problems of its own. The main new problem is that it is, in my opinion, a bit too permissive, meaning that it makes too
many tiles visible. Nonetheless it seems like an improvement on standard shadow casting. (I chose to implement it by
modifying my shadow casting code.) As for efficiency, it is somewhat slower than plain shadow casting, since it needs to
do more work per tile, but it's still reasonably fast.</p>
<p>Treating walls as diamonds actually makes a lot of sense in roguelikes, although it sounds ridiculous. The reason is
that most roguelikes allow monsters to move between diagonally adjacent walls, and if the walls were square, their
corners would be touching, leaving no space. This is illustrated in the picture below. Making the physics of the world
more consistent naturally leads to more intuitive lighting. Diamond walls also allow better vision around corners, which
is usually desirable.</p>
<p><img src="data:image/png;base64,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"> <img src="data:image/png;base64,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"> <img src=data:image/png;base64,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></p>
<p>Unfortunately, there is a theoretical problem with diamond walls. The description states that lines tangent to a wall
diamond aren't considered to intersect it and zero-width beams of light still illuminate tiles. This provides better
vision around corners but also allows the following case where a monster can see through a wall. Implementations are
expected to disallow seeing through walls as a special case, which prevents the problem but requires inconsistent
physics.</p>
<p><img src="data:image/png;base64,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"></p>
<p>Here are some features and problems of shadow casting with diamond walls.</p>
<p>
<div class=sshotc>
<pre class=sshot>   <span class=lt>│∙∙∙∙∙</span>∙∙
   <span class=lt>│∙∙∙∙∙∙</span>∙
   │∙<span class=lt>∙∙∙∙∙</span>∙
───┤∙∙∙<span class=lt>∙∙∙┼</span>
∙∙∙■∙∙∙∙∙<span class=lt>┼@</span>
</pre>
<div class=caption>Visibility through diagonals</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>@┼</span>∙∙∙∙∙∙∙∙∙
<span class=lt>∙∙∙∙</span>∙∙∙∙∙∙∙
<span class=lt>∙┼∙∙∙∙</span>∙∙∙∙∙
<span class=lt>∙∙∙∙∙∙∙∙</span>∙∙∙
<span class=lt>∙┼</span>∙<span class=lt>∙∙∙∙∙∙∙</span>∙
</pre>
<div class=caption>Here too</div>
</div>
<div class=sshotc>
<pre class=sshot>─<span class=lt>─────────</span>─
∙∙<span class=lt>∙∙∙∙∙∙∙</span>∙∙
──┬┬<span class=lt>─@┌</span>┬───
  ├<span class=lt>┘∙∙└</span>┤   
 ┌<span class=lt>┘∙∙│∙</span>└┐  
</pre>
<div class=caption>No blind corners</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>───────────</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>─────┬┬─∙┌┬</span>
     ├┘∙∙└┤
    ┌┘∙∙│∙└
</pre>
<div class=caption>Still asymmetrical</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙
<span class=lt>∙∙∙∙∙┼∙∙∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Bigger shadow gaps<br>than shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>           │∙∙∙∙∙∙∙∙∙∙∙
<span class=lt>───────────┤∙∙∙∙∙∙∙┼∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙■∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙┌┬────────┤∙∙∙∙∙∙∙┼∙∙∙</span>
<span class=lt>∙└</span>┤        │∙∙∙∙∙∙∙∙∙∙∙
</pre>
<div class=caption>Same problem casting through narrow spaces</div>
</div>
<p></p>
<p>The same simple change can be made to turn the diamond wall algorithm into a symmetric one, and it has the same
benefits and drawbacks that it has for regular shadow casting.</p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>───</span>────────
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───</span>──┬┬─∙┌┬
     ├┘∙∙└┤
    ┌┘∙∙│∙└
</pre>
<div class=caption>Symmetrical,<br>no expansive walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>─────</span>─────┐
<span class=lt>∙∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙│</span>
</pre>
<div class=caption>No expansive walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙</span>∙∙∙∙
<span class=lt>∙∙∙∙∙┼</span>∙∙∙∙<span class=lt>∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>No shadow gaps</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>├───∙─</span>─────
│∙∙∙∙<span class=lt>∙</span>∙∙∙∙∙
│∙∙∙∙∙┼<span class=lt>∙</span>┼∙∙
│∙∙∙∙∙∙∙∙∙∙
│∙∙∙∙∙∙∙∙│<span class=lt>∙</span>
</pre>
<div class=caption>Discontinuous visibility</div>
</div>
<div class=sshotc>
<pre class=sshot>   │∙∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙∙∙
<span class=lt>───</span>┤∙∙<span class=lt>∙∙∙∙∙┼</span>∙∙∙┼∙∙∙∙∙
<span class=lt>@∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───</span>┤∙∙<span class=lt>∙∙∙∙∙┼</span>∙∙∙┼∙∙∙∙∙
   │∙∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙∙∙
</pre>
<div class=caption>Better propagation through narrow spaces</div>
</div>
<p></p>
<p>Code to implement diamond walls is <a href=#diamondcode>below</a>.</p>
<a name=halfwidth></a>
<h4>Half-width walls</h4>
<b>Pros &amp; cons:</b> The same as diamond walls, but more permissive and slightly slower.
<p>There is another idea similar to diamond walls except that it uses walls that are half the usual width. It also
solves the problem of not being able to see between diagonal tiles, but in my opinion looks poorer than diamond walls by
being too permissive. The implementation is also slightly slower since not every wall tile has the same shape. (The
shape depends on whether there is an adjacent wall for it to join with.) I implemented the algorithm but I don't
consider it worth the effort to present.</p>
<a name=permissive></a>
<h4>Permissive field of view (tile-to-tile)</h4>
<b>Pros:</b> Symmetry. No blind corners. Expansive walls. Continuous point visibility.
<b>Cons:</b> Slow. No expanding pillar shadows. Perhaps too much visibility around corners.
<p>The permissive field of view algorithm treats a tile as visible if there's an unobstructed line from any part of the
player's tile to any part of the target tile. Most implementations of this use an approximation, such as just testing
the corners against each other, which fails in some cases. Exact implementations work in all cases but tend to be fairly
slow. I provide an exact implementation (cleaned up and adapted from a demo by
<a target=_new href=https://user.xmission.com/~tyrecius/>Jonathon Duerig</a>). The main features of the algorithm
are that it's symmetrical and allows peeking very far around corners, but it's too permissive for my taste, so I haven't
made any effort to optimize the algorithm. That said, the algorithm looks and works much better if all creatures have a
short sight radius.</p>
<p>There exists a version of the permissive FOV algorithm that allows the permissivity to be changed at runtime. I
played with it, and half the usual permissivity looks decent to my eye, but then it's no longer symmetrical and I'd prefer to have a faster algorithm anyway.</p>
<p>
<div class=sshotc>
<pre class=sshot>   <span class=lt>│∙∙∙∙∙∙</span>∙<span class=lt>∙∙</span>
<span class=lt>───┤∙∙∙∙∙∙∙┼∙</span>
<span class=lt>∙∙∙■∙∙∙∙∙∙∙∙∙</span>
───┤∙∙∙∙∙∙∙<span class=lt>┼@</span>
   <span class=lt>│∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Thin pillar shadows</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>@∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙┼∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>∙<span class=lt>∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Pillar shadow gaps</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>─┴─────────■───</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>@┌</span>─────────■───
<span class=lt>∙│</span>∙∙∙∙∙∙∙∙∙∙∙∙∙
<span class=lt>+┤</span>∙∙∙∙∙∙∙∙│∙∙∙∙
</pre>
<div class=caption>Can see <i>all</i> the way around corners</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>│∙│</span>                 ┌┬───┐
<span class=lt>│∙├</span>┬──<span class=lt>──────────────┴┘∙∙∙│</span>
<span class=lt>│∙└┘∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙┌</span>─┘
<span class=lt>│@∙∙∙┌</span>─────────────────┘  
<span class=lt>└────┘</span>                    
</pre>
<div class=caption>Including down Kuo corridors</div>
</div>
<p></p>
<p>Code to implement the permissive field of view algorithm is <a href=#permissivecode>below</a>.</p>
<a name=digital></a>
<h4>Digital field of view (diamond-to-diamond)</h4>
<b>Pros &amp; cons:</b> Same as the permissive field of view algorithm.
<p>The digital field of view algorithm treats every tile as a diamond (embedded in the square, the remainder being empty
space) and considers a tile visible if there is an unobstructed line from any part of the player's diamond to any part
of the target diamond. As a result, it's slightly more permissive than even the permissive field of view algorithm
(since walls present less of an obstruction), but otherwise it shares all the same features and drawbacks while being
even slower. The idea is based on the rather unwieldy concept of
<a target=_new href=http://libdgtal.org/doc/stable/moduleArithDSSReco.html>digital straight line segments</a>, and I
did not bother to create an implementation of it. One interesting feature of the algorithm is that the knowledge of
the digital line segment from a line-of-sight calculation allows easy tracing of a projectile path through space without
hitting any walls, even down somewhat twisted tunnels (such as the Kuo corridor above). But the complexity seems to
outweight the benefit.</p>
<a name=mine></a>
<h3>My algorithm</h3>
None of the above algorithms really satisfy me. First of all, except for ray casting they're all either too permissive
or too restrictive – sometimes both at once, and ray casting has too many artifacts to be usable. Here are the
problems I intend to fix and the features I intend to have.
<ul>
<li>Less permissive than most other algorithms</li>
<li>More symmetrical than other algorithms</li>
<li>Able to be made symmetrical (at least versus non-passwall monsters) without losing expansive walls</li>
<li>Good vision through diagonal spaces, but not too much</li>
<li>Good light casting through narrow spaces, without losing expansive walls</li>
<li>Reduced shadow gaps compared to other algorithms</li>
<li>Efficiency on par with diamond walls</li>
<li>No blind corners</li>
<li>No artifacts</li>
<li>Consistent physics</li>
</ul>
To accomplish this, I'll represent the dungeon geometry as in the following image. (NOTE: Two corners in the second image should be beveled. I drew it incorrectly. Nonetheless, the image illustrates the utility of the inner square.)
<p><img src="data:image/png;base64,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"> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVAAAADQCAMAAABm8cmHAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAA8BAAMYABcCAB8DAAQgAC0EPz8/AABIAAlAAApIAA5gAAB0ABBwNztXODxULzhvMjpmMDlsH18mAH8OAHwVD38cE38fAG47AHMsH38qL08yKVUuIH8qJ38xKX8zL384AEhIAF1oAll5AGhKAGBhPH9ESAAAdAAASABISAB0dABIdAB0SEgAQX9IT39UU39YSHR0X39iZ2dnZ39paX9rb39wd3d3e397fn9+ABOAFi65GC+zGTCwIjOWDyvOCyraHzveBijpASb4ACb+Byv2Ayj6Aij9BSn4BCj/Ci3yCCz/DC//DzDuDDD/FzbmEzPqEDHsFDTpGTfkGznhEDP/FDb/GDn/HD3/IT3cAEicAHScAHS/P1G/L0fOJ0HWJUDYKELUK0TSLUXQMEfPN0zGM0rJOk7CPVHAIED/JET+KEf/K0n/ME7/NFH/OFX/PFj/SEicT12vR1e3QVO9Q1W7RVa5S1qzUV6sX2ifV2OnVGGpW2WiZ26XYmqbb3OPbHGRc3eLcXWNd3iHdXiJe3uDeXqFfX2BcHegQlzxQFv/QFz/RF//SGL/TGb/UGn/VGz/WHD/XHP/XHT/aHbIYXboYHf/ZHr/aH7/BIERFoIiII8sLoU4KZM0RJNMQJ9KUKdZVKldY5JoYK9oeLt/d4iZfr2FSJzgbIH/cIT/dIj/eIv/eIz/fI//f5H/dL//nEgAv3QAnEhIv5xI4JxI/790gICAi4uLgZiDk5OTm5ubpaWlrKystLS0vLy8g5T/h5j/i5v/i5z/j5//k6L/l6X/m6n/n6z/o7D/p7P/p7T/q7f/r7r/s73/g8CJn86kp9Krq9Svv+CcnOD/v97Ct8H/u8T/v8j/v///4L+//+Cc//+/wsLCy8vL0tLS29vbw8v/x87/y9L/z9X/09n/19z/2N3429//z+bR0+jV3+7g2+D/3+P/4uLi6+vr4+b/5+r/6+3/4P//7/D////g8/Pz8/T/9/f/9vn29/j/+Pj4+/v/+/z7/v7+AAAAAAAAAIWaKwAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuM4zml1AAABnISURBVHhe7Z0JfBxXfcfdMz0pvUibFgg9krRASROaZHpRtc+U0a5JQi2tnGJDoDisbhwCMTG24zhWu5asg3alQim0UKIDLzH10cRxJCNbKyG5UEBaGl+yLVUU1t4VG++GbN/n0///zf/NnjMbZfftrpX5fT4avXn/mfm/9913zbw51vBM3X6dZqvrqt2+poAU+789G6imUcBCVW8nbpZS7p8CUsozrNpO3Cyl3D8FpF7aAWNxsQKKxShAMvcf93MeX6YV0FSf+Fdcgvsmc+ydcxQwVIVAJxirbxoxiWXJOGBLl1gBtbRQgGQ69Hs5766jFVAA1kFgj4oAKJnGmxR/3DbB3kBahpLit2RBsSJVhUADntBcwGUSy5JxwBmzWMycogDJdIhAQ5O0AjKBhtm8CHE+akSly7fJNsEZQI0jXgNAMZ3DTPz84SQuOY8u83gC6ncS7BiglcW4DMWp2EV2SYcINCEOEo3gEg6bDOPxwyyE60aUUExsICSBgkOUWBqHjuA/APqYWaxNoFFqduJwnGoFOsbiPDnmZq4BQLrYwvQBXwDzA3YfNI7ib9jH+o3QSL/OWiDDC01uxphRuBGo3we/SatLZ6wTsh+sY3Xz2odhC3YCt+jEUJgvtDJWJyJ4HGMaob31MNYE2IMMIuexRM9BjC/GvcPvg2MZzRHsxliEs9E2xiARPNINbdVUdQJNzNX3cD5RF0pMucegnWwPX2pnOUDd3ZcuGiG9eyHkHuS8rTv56Lt6jfIigXZ1xZdb9y3zACBabG3U9syzqTAUayh+Qw3hMI95usKxUTYldoq03b8jyufYeGypxxU1gIagREfdPUvhgYvcyzbvPMWOi22N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"></p>
<p>A corner is beveled if neither of the two cardinally adjacent tiles are walls. Wall tiles are considered visible if a
beam of light intersects the wall shape while clear tiles are considered visible if light intersects the central square
(which can be at most 1/2 the width or height of the tile). Tangents to a shape do not intersect it, and a zero-width
sector of light can't illuminate anything.</p>
<p>Solid walls with beveled edges allow peeking around corners and seeing through diagonal spaces while avoiding the
theoretical problem of diamond walls. Not showing clear tiles unless light passes near the center should make it a bit
less permissive, reduce shadow gaps, reduce asymmetry, and fix the behavior of light passing through narrow spaces.</p>
<p>The problem with light passage through narrow spaces is illustrated in the second image above. No matter how far you
are down the tunnel, the circular sector will open up as it leaves the narrow space and, with other algorithms,
immediately illuminate the tiles above and below. As seen in the screenshots above, pillars cannot stop this
illumination. The reason is that, like the walls of the tunnel, the sector is still opening up after it passes between
the pillars. Not illuminating tiles only barely touched by light avoids this, and allows pillars to effectively stop the
light. This should also reduce shadow gaps by preventing small slivers of light from dispelling the shadow from a
tile.</p>
<p>Permissivity can be tuned by adjusting the angle of the bevel and the size of the inner square. Another shape besides
a square can be used, but it must fit within the area of the largest diamond that can be placed in the tile (i.e. it may
not extend beyond the shape of a pillar). For a square, the maximum is 1/2 the width of the tile. Testing shows
that using 1/2 the width gives good results. Using 3/8 the width of the tile allows for symmetrical sight between
creatures in and on the side of a narrow corridor, which is a nice feature, but it looks a bit too restrictive otherwise
(especially if there are many pillars), so I'll stick with 1/2. The actual implementation will use a modified shadow
casting algorithm, giving decent performance as long as I can avoid doing too much work per tile.</p>
<p>Here are some samples from the asymmetrical version.</p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙@┼</span>∙∙∙∙∙
<span class=lt>∙∙∙┼∙∙</span>∙∙∙∙
<span class=lt>∙∙┼</span>∙<span class=lt>∙∙∙∙</span>∙∙
<span class=lt>∙┼</span>∙∙∙<span class=lt>∙∙∙∙∙</span>
<span class=lt>┼</span>∙∙∙∙<span class=lt>∙∙∙∙∙</span>
</pre>
<div class=caption>Good diagonal vision</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>@┼</span>∙∙∙∙∙∙∙∙
<span class=lt>∙∙∙</span>∙∙∙∙∙∙∙
<span class=lt>∙┼∙∙∙</span>∙∙∙∙∙
<span class=lt>∙∙∙∙∙∙∙</span>∙∙∙
<span class=lt>∙┼</span>∙<span class=lt>∙∙∙∙∙∙</span>∙
</pre>
<div class=caption>Here too</div>
</div>
<div class=sshotc>
<pre class=sshot>──<span class=lt>───────</span>──
∙∙∙<span class=lt>∙∙∙∙∙</span>∙∙∙
──┬┬<span class=lt>─@┌</span>┬───
  ├<span class=lt>┘∙∙└</span>┤   
 ┌<span class=lt>┘∙∙│∙</span>└┐  
</pre>
<div class=caption>No blind corners</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙</span>∙∙∙
<span class=lt>∙∙∙∙∙┼</span>∙∙<span class=lt>∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Fewer shadow gaps</div>
</div>
<div class=sshotc>
<pre class=sshot>         │∙∙∙∙∙∙∙∙∙∙∙∙∙
<span class=lt>─────────┤</span>∙∙∙∙<span class=lt>∙∙∙┼</span>∙∙∙<span class=lt>┼</span>∙
<span class=lt>@∙∙∙∙∙∙∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>┬────────┤</span>∙∙∙∙<span class=lt>∙∙∙┼</span>∙∙∙<span class=lt>┼</span>∙
┤        │∙∙∙∙∙∙∙∙∙∙∙∙∙
</pre>
<div class=caption>Good behavior casting through narrow spaces</div>
</div>
<p></p>
<p>My algorithm has two symmetrical versions: one that's fully symmetrical and another that's symmetrical except for
some walls (i.e. symmetrical between monsters except sometimes against passwall monsters). Here's the version
that's mostly symmetrical. As you can see, it doesn't suffer from the same problems of other algorithms when made
symmetrical. Most importantly, it doesn't lose the expansive walls feature. This is the better of the two symmetrical
versions, unless you need symmetry versus passwall monsters.</p>
<p>
<div class=sshotc>
<pre class=sshot>           
<span class=lt>───────────</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>┬┬─</span>∙<span class=lt>┌┬─────</span>
├┘∙∙└┤     
</pre>
<div class=caption>Symmetrical non-walls,<br>expansive walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>──────────┐</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙│</span>
</pre>
<div class=caption>Expansive walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙
<span class=lt>∙∙∙∙∙∙∙┼</span>∙∙<span class=lt>∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>No shadow gaps</div>
</div>
<p></p>
<p>Here is the fully symmetrical version of my algorithm. It gains symmetry against all passwall monsters but loses
expansive walls as usual, although walls are no less expansive than other algorithms (except permissive FOV) and more
expansive than most. It is very similar but not identical to symmetrical diamond walls.</p>
<p>
<div class=sshotc>
<pre class=sshot>           
<span class=lt>───</span>────────
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>┬┬─</span>∙<span class=lt>┌</span>┬─────
├┘∙∙└┤     
</pre>
<div class=caption>Symmetrical,<br>no expansive walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>─────────</span>─┐
<span class=lt>∙∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙│</span>
</pre>
<div class=caption>No expansive walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙
<span class=lt>∙∙∙∙∙∙∙┼</span>∙∙<span class=lt>∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>No shadow gaps</div>
</div>
<p></p>
<p>Code to implement my algorithm is <a href=#mycode>below</a>.</p>
<a name=compare></a>
<h3>Comparison</h3>
Here's a comparison of my algorithm with the ray casting, shadow casting, diamond walls, and permissive field of view
algorithms. Unless otherwise stated, the comparison is done between the basic (usually asymmetrical) versions of the
algorithms. In some sections I've reduced the line height in order to make the height of a tile closer to its width,
allowing a better sense of symmetry on the two axes. Depending on your font and browser, this might look terrible,
especially in vertical walls. To toggle this effect,
<a href=http://www.adammil.net/blog/v125_Roguelike_Vision_Algorithms.html>click here</a>. (This requires Javascript, and the
effect is only enabled initially if Javascript is available.)<p></p>
<a name=cmpcorn></a>
<h4>Corner peeking</h4>
<p>
<div class=sshotc>
<pre class=sshot>──<span class=lt>───────</span>──
∙∙∙<span class=lt>∙∙∙∙∙</span>∙∙∙
──┬┬<span class=lt>─@┌</span>┬───
  ├<span class=lt>┘∙∙└</span>┤   
 ┌<span class=lt>┘∙∙│∙</span>└┐  
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>───<span class=lt>─────</span>───
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
──┬┬<span class=lt>─@┌</span>┬───
  ├┘<span class=lt>∙∙└</span>┤   
 ┌┘<span class=lt>∙∙│∙</span>└┐  
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>─<span class=lt>─────────</span>─
∙∙<span class=lt>∙∙∙∙∙∙∙</span>∙∙
──┬┬<span class=lt>─@┌</span>┬───
  ├<span class=lt>┘∙∙└</span>┤   
 ┌<span class=lt>┘∙∙│∙</span>└┐  
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>──<span class=lt>───────</span>──
∙∙∙<span class=lt>∙∙∙∙∙</span>∙∙∙
──┬┬<span class=lt>─@┌</span>┬───
  ├<span class=lt>┘∙∙└</span>┤   
 ┌<span class=lt>┘∙∙│∙</span>└┐  
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>───────────</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
──┬┬<span class=lt>─@┌</span>┬───
  ├<span class=lt>┘∙∙└</span>┤   
 ┌<span class=lt>┘∙∙│∙</span>└┐  
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<a name=cmpcorr></a>
<h4>Corridor asymmetry</h4>
Red tiles are where a monster can see the player but the player can't see the monster.
<p>
<div class=sshotc>
<pre class=sshot>∙└─────<span class=lt>───────</span>───────
∙<span class=bddk>∙∙∙∙∙∙∙</span><span class=lt>∙∙∙∙∙</span><span class=bddk>∙∙∙</span>∙<span class=bddk>∙∙∙∙</span>
───────┬┬<span class=lt>─@┌</span>┬────────
       ├<span class=lt>┘∙∙└</span>┤        
      ┌<span class=lt>┘∙∙│∙</span>└┐       
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>∙└──────<span class=lt>─────</span>────────
<span class=bddk>∙∙∙∙∙∙∙∙∙</span><span class=lt>∙∙∙</span><span class=bddk>∙∙∙∙∙∙∙∙∙</span>
───────┬┬<span class=lt>─@┌</span>┬────────
       ├┘<span class=lt>∙∙└</span>┤        
      ┌┘<span class=lt>∙∙│∙</span>└┐       
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>∙└──────<span class=lt>─────</span>────────
<span class=bddk>∙∙∙∙∙∙∙∙</span><span class=lt>∙∙∙∙∙</span><span class=bddk>∙∙∙∙∙∙∙∙</span>
───────┬┬<span class=lt>─@┌</span>┬────────
       ├┘<span class=lt>∙∙└</span>┤        
      ┌┘<span class=lt>∙∙│∙</span>└┐       
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>∙└─────<span class=lt>───────</span>───────
∙∙∙∙∙∙∙<span class=bddk>∙</span><span class=lt>∙∙∙∙∙</span><span class=bddk>∙</span>∙∙∙∙∙∙∙
───────┬┬<span class=lt>─@┌</span>┬────────
       ├<span class=lt>┘∙∙└</span>┤        
      ┌<span class=lt>┘∙∙│∙</span>└┐       
</pre>
<div class=caption>My algorithm (1/2-width inner square)</div>
</div>
<div class=sshotc>
<pre class=sshot>∙└─────<span class=lt>───────</span>───────
∙∙∙∙∙∙∙∙<span class=lt>∙∙∙∙∙</span>∙∙∙∙∙∙∙∙
───────┬┬<span class=lt>─@┌</span>┬────────
       ├<span class=lt>┘∙∙└</span>┤        
      ┌<span class=lt>┘∙∙│∙</span>└┐       
</pre>
<div class=caption>My algorithm (3/8-width inner square)</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙└───────────────────</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
───────┬┬<span class=lt>─@┌</span>┬────────
       ├<span class=lt>┘∙∙└</span>┤        
      ┌<span class=lt>┘∙∙│∙</span>└┐       
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<div id=lhContainer>
<a name=cmpnarrow></a>
<h4>Narrow spaces</h4>
In this and subsequent sections I've reduced the line height of some sections in order to make the height of a tile
closer to its width, allowing a better sense of symmetry on the two axes. Depending on your font and browser, this might
look terrible, especially in vertical walls. To toggle this effect,
<a href=http://www.adammil.net/blog/v125_Roguelike_Vision_Algorithms.html>click here</a>. (This requires Javascript, and
the effect is only enabled initially if Javascript is available.)
<p>
<div class=sshotc>
<pre class=sshot>   │∙∙∙∙∙∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>
   │∙∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───┤∙∙∙∙∙∙∙+</span>∙∙<span class=lt>∙+</span>∙∙<span class=lt>∙</span>
<span class=lt>@∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───┤∙∙∙∙∙∙∙+</span>∙∙<span class=lt>∙+</span>∙∙<span class=lt>∙</span>
   │∙∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙</span>∙
   │∙∙∙∙∙∙∙+∙∙∙+<span class=lt>∙∙∙</span>
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>   │∙∙∙∙∙∙∙∙∙∙∙∙∙∙<span class=lt>∙</span>
   │∙∙∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙</span>∙
<span class=lt>───┤∙∙∙∙∙∙∙+∙∙∙+∙∙∙</span>
<span class=lt>@∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───┤∙∙∙∙∙∙∙+∙∙∙+∙∙∙</span>
   │∙∙∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙</span>∙
   │∙∙∙∙∙∙∙+∙∙∙+∙∙<span class=lt>∙</span>
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>   │∙∙∙∙∙∙∙∙∙∙∙<span class=lt>∙∙∙∙</span>
   │∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───┤∙∙∙∙∙∙∙+∙∙∙+∙∙∙</span>
<span class=lt>@∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───┤∙∙∙∙∙∙∙+∙∙∙+∙∙∙</span>
   │∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙</span>
   │∙∙∙∙∙∙∙+∙∙∙<span class=lt>+∙∙∙</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>   │∙∙∙∙∙∙∙∙∙∙∙∙∙<span class=lt>∙∙</span>
   │∙∙∙∙∙∙∙<span class=lt>∙∙∙∙∙∙</span>∙∙
<span class=lt>───┤</span>∙<span class=lt>∙∙∙∙∙∙+</span>∙∙∙<span class=lt>+</span>∙∙∙
<span class=lt>@∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───┤</span>∙<span class=lt>∙∙∙∙∙∙+</span>∙∙∙<span class=lt>+</span>∙∙∙
   │∙∙∙∙∙∙∙<span class=lt>∙∙∙∙∙∙</span>∙∙
   │∙∙∙∙∙∙∙+∙∙∙+∙<span class=lt>∙∙</span>
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot>   │∙∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>
   │∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>∙
<span class=lt>───┤∙∙∙∙∙∙∙+∙∙∙+∙∙∙</span>
<span class=lt>@∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───┤∙∙∙∙∙∙∙+∙∙∙+∙∙∙</span>
   │∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>∙
   │∙∙∙∙∙∙<span class=lt>∙+∙∙∙+∙∙∙</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot>     │∙∙∙∙∙∙∙∙∙∙∙∙∙
<span class=lt>─────┤∙∙∙∙∙∙∙+∙∙∙+</span>∙
<span class=lt>@∙∙∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>─────┤∙∙∙∙∙∙∙+∙∙∙+</span>∙
     │∙∙∙∙∙∙∙∙∙∙∙∙∙
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>     │∙∙∙∙∙∙∙∙∙∙∙∙∙
<span class=lt>─────┤∙∙∙∙∙∙∙+∙∙∙+∙</span>
<span class=lt>@∙∙∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>─────┤∙∙∙∙∙∙∙+∙∙∙+∙</span>
     │∙∙∙∙∙∙∙∙∙∙∙∙∙
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>     │∙∙∙∙∙∙∙∙∙∙∙∙∙
<span class=lt>─────┤∙∙∙∙∙∙∙+∙∙∙+∙</span>
<span class=lt>@∙∙∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>─────┤∙∙∙∙∙∙∙+∙∙∙+∙</span>
     │∙∙∙∙∙∙∙∙∙∙∙∙∙
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>     │∙∙∙∙∙∙∙∙∙∙∙∙∙
<span class=lt>─────┤</span>∙∙<span class=lt>∙∙∙∙∙+</span>∙∙∙<span class=lt>+</span>∙
<span class=lt>@∙∙∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>─────┤</span>∙∙<span class=lt>∙∙∙∙∙+</span>∙∙∙<span class=lt>+</span>∙
     │∙∙∙∙∙∙∙∙∙∙∙∙∙
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot>     │∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙</span>
<span class=lt>─────┤∙∙∙∙∙∙∙+∙∙∙+∙</span>
<span class=lt>@∙∙∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>─────┤∙∙∙∙∙∙∙+∙∙∙+∙</span>
     │∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<a name=cmpdiag></a>
<h4>Diagonal spaces</h4>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙+</span>
<span class=lt>∙∙∙∙∙∙</span>+∙
<span class=lt>∙∙∙∙∙</span>+∙∙
<span class=lt>∙∙∙∙+</span>∙∙∙
<span class=lt>∙∙∙+</span>∙∙∙∙
<span class=lt>∙∙+</span>∙∙∙∙∙
<span class=lt>@+</span>∙∙∙∙∙∙
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙</span>+
<span class=lt>∙∙∙∙∙∙</span>+∙
<span class=lt>∙∙∙∙∙</span>+∙∙
<span class=lt>∙∙∙∙</span>+∙∙∙
<span class=lt>∙∙∙</span>+∙∙∙∙
<span class=lt>∙∙</span>+∙∙∙∙∙
<span class=lt>@+</span>∙∙∙∙∙∙
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙+</span>
<span class=lt>∙∙∙∙∙∙+</span>∙
<span class=lt>∙∙∙∙∙+</span>∙∙
<span class=lt>∙∙∙∙+</span>∙∙∙
<span class=lt>∙∙∙+</span>∙∙∙∙
<span class=lt>∙∙+</span>∙∙∙∙∙
<span class=lt>@+</span>∙∙∙∙∙∙
</pre>
<div class=caption>Others</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>┌───</span>────
<span class=lt>│∙∙∙</span>∙∙∙∙
<span class=lt>│∙∙∙∙</span>∙∙∙
<span class=lt>│∙∙∙∙∙</span>∙∙
│<span class=lt>∙∙∙∙∙</span>∙∙
│∙∙<span class=lt>∙∙∙∙</span>∙
┤∙∙∙∙<span class=lt>∙∙+</span>
■∙∙∙∙∙<span class=lt>+@</span>
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌</span>───────
│<span class=lt>∙</span>∙∙∙∙∙∙
│∙<span class=lt>∙</span>∙∙∙∙∙
│∙∙<span class=lt>∙</span>∙∙∙∙
│∙∙∙<span class=lt>∙</span>∙∙∙
│∙∙∙∙<span class=lt>∙</span>∙∙
┤∙∙∙∙∙<span class=lt>∙+</span>
■∙∙∙∙∙<span class=lt>+@</span>
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌────</span>───
<span class=lt>│∙∙∙∙</span>∙∙∙
<span class=lt>│∙∙∙∙∙</span>∙∙
<span class=lt>│∙∙∙∙∙</span>∙∙
<span class=lt>│∙∙∙∙∙∙</span>∙
│∙<span class=lt>∙∙∙∙∙</span>∙
┤∙∙∙<span class=lt>∙∙∙+</span>
■∙∙∙∙∙<span class=lt>+@</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌────</span>───
<span class=lt>│∙∙∙∙</span>∙∙∙
<span class=lt>│∙∙∙∙</span>∙∙∙
<span class=lt>│∙∙∙∙∙</span>∙∙
<span class=lt>│∙∙∙∙∙</span>∙∙
│∙∙<span class=lt>∙∙∙∙</span>∙
┤∙∙∙∙<span class=lt>∙∙+</span>
■∙∙∙∙∙<span class=lt>+@</span>
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌──────</span>─
<span class=lt>│∙∙∙∙∙∙</span>∙
<span class=lt>│∙∙∙∙∙∙</span>∙
<span class=lt>│∙∙∙∙∙∙</span>∙
<span class=lt>│∙∙∙∙∙∙</span>∙
<span class=lt>│∙∙∙∙∙∙</span>∙
<span class=lt>┤∙∙∙∙∙∙+</span>
■∙∙∙∙∙<span class=lt>+@</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot>┌───<span class=lt>─</span>───
│∙∙∙<span class=lt>∙∙</span>∙∙
│∙∙∙∙<span class=lt>∙</span>∙∙
│∙∙∙∙<span class=lt>∙∙</span>∙
<span class=lt>│∙</span>∙∙∙∙<span class=lt>∙</span>∙
<span class=lt>│∙∙∙</span>∙∙<span class=lt>∙+</span>
┤∙<span class=lt>∙∙∙∙+∙</span>
■∙∙∙∙<span class=lt>+∙@</span>
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>┌────<span class=lt>─</span>──
│∙∙∙∙<span class=lt>∙</span>∙∙
│∙∙∙∙<span class=lt>∙</span>∙∙
│∙∙∙∙∙<span class=lt>∙</span>∙
│∙∙∙∙∙<span class=lt>∙</span>∙
<span class=lt>│∙∙</span>∙∙∙<span class=lt>∙+</span>
┤∙∙<span class=lt>∙∙∙+∙</span>
■∙∙∙∙<span class=lt>+∙@</span>
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>┌──<span class=lt>───</span>──
│∙∙∙<span class=lt>∙∙∙</span>∙
│∙∙∙<span class=lt>∙∙∙</span>∙
<span class=lt>│</span>∙∙∙∙<span class=lt>∙∙</span>∙
<span class=lt>│∙∙</span>∙∙<span class=lt>∙∙</span>∙
<span class=lt>│∙∙∙∙</span>∙<span class=lt>∙+</span>
┤<span class=lt>∙∙∙∙∙+∙</span>
■∙∙∙∙<span class=lt>+∙@</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>┌───<span class=lt>──</span>──
│∙∙∙<span class=lt>∙∙</span>∙∙
│∙∙∙∙<span class=lt>∙∙</span>∙
│∙∙∙∙<span class=lt>∙∙</span>∙
<span class=lt>│∙</span>∙∙∙∙<span class=lt>∙</span>∙
<span class=lt>│∙∙∙</span>∙∙<span class=lt>∙+</span>
┤∙<span class=lt>∙∙∙∙+∙</span>
■∙∙∙∙<span class=lt>+∙@</span>
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot>┌─<span class=lt>─────</span>─
│∙<span class=lt>∙∙∙∙∙</span>∙
<span class=lt>│∙</span>∙<span class=lt>∙∙∙∙</span>∙
<span class=lt>│∙∙</span>∙<span class=lt>∙∙∙</span>∙
<span class=lt>│∙∙∙</span>∙<span class=lt>∙∙</span>∙
<span class=lt>│∙∙∙∙</span>∙<span class=lt>∙+</span>
<span class=lt>┤∙∙∙∙∙+∙</span>
■∙∙∙∙<span class=lt>+∙@</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>┌──</span>───<span class=lt>─</span>──
<span class=lt>│∙∙∙</span>∙∙<span class=lt>∙</span>∙∙
│<span class=lt>∙∙∙</span>∙∙∙<span class=lt>∙</span>∙
│∙<span class=lt>∙∙∙</span>∙∙<span class=lt>∙</span>∙
│∙∙<span class=lt>∙∙∙</span>∙<span class=lt>∙</span>∙
│∙∙∙<span class=lt>∙∙∙∙+</span>
<span class=lt>│∙</span>∙∙∙<span class=lt>∙∙+∙</span>
<span class=lt>│∙∙∙∙∙+∙∙</span>
│∙∙∙∙<span class=lt>+∙∙@</span>
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌</span>─────<span class=lt>─</span>──
│<span class=lt>∙</span>∙∙∙∙∙<span class=lt>∙</span>∙
│∙<span class=lt>∙</span>∙∙∙∙<span class=lt>∙</span>∙
│∙∙<span class=lt>∙</span>∙∙∙<span class=lt>∙</span>∙
│∙∙∙<span class=lt>∙</span>∙∙<span class=lt>∙</span>∙
│∙∙∙∙<span class=lt>∙</span>∙<span class=lt>∙+</span>
<span class=lt>│</span>∙∙∙∙∙<span class=lt>∙+∙</span>
│<span class=lt>∙∙∙∙∙+∙∙</span>
│∙∙∙∙<span class=lt>+∙∙@</span>
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌──</span>───<span class=lt>──</span>─
<span class=lt>│∙∙∙</span>∙∙<span class=lt>∙∙</span>∙
<span class=lt>│∙∙∙∙</span>∙<span class=lt>∙∙</span>∙
│<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙</span>∙
│∙<span class=lt>∙∙∙∙</span>∙<span class=lt>∙</span>∙
│∙∙<span class=lt>∙∙∙∙∙+</span>
<span class=lt>│∙∙</span>∙∙<span class=lt>∙∙+∙</span>
<span class=lt>│∙∙∙∙∙+∙∙</span>
│∙∙∙∙<span class=lt>+∙∙@</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌──</span>───<span class=lt>──</span>─
<span class=lt>│∙∙∙</span>∙∙<span class=lt>∙∙</span>∙
<span class=lt>│∙∙∙</span>∙∙∙<span class=lt>∙</span>∙
│<span class=lt>∙∙∙∙</span>∙∙<span class=lt>∙</span>∙
│∙∙<span class=lt>∙∙∙</span>∙<span class=lt>∙</span>∙
│∙∙∙<span class=lt>∙∙∙∙+</span>
<span class=lt>│∙</span>∙∙∙<span class=lt>∙∙+∙</span>
<span class=lt>│∙∙∙∙∙+∙∙</span>
│∙∙∙∙<span class=lt>+∙∙@</span>
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌───</span>─<span class=lt>───</span>─
<span class=lt>│∙∙∙∙∙∙∙</span>∙
<span class=lt>│∙∙∙∙</span>∙<span class=lt>∙∙</span>∙
<span class=lt>│∙∙∙∙∙∙∙</span>∙
│<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙</span>∙
<span class=lt>│∙</span>∙<span class=lt>∙∙∙∙∙+</span>
<span class=lt>│∙∙∙</span>∙<span class=lt>∙∙+∙</span>
<span class=lt>│∙∙∙∙∙+∙∙</span>
│∙∙∙∙<span class=lt>+∙∙@</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
</div> 
<a name=cmprooms></a>
<h4>Rooms</h4>
<p>
<div class=sshotc>
<pre class=sshot> ┌─<span class=lt>──</span>────────┐
 │<span class=lt>∙∙</span>∙∙∙∙∙∙∙∙∙│
┌┘<span class=lt>∙──┬</span>─────┐∙│
┤<span class=lt>∙∙∙∙│</span>     │∙│
<span class=lt>┘∙∙∙∙│</span>     │∙│
<span class=lt>@∙∙∙∙└</span>───┐ │∙│
<span class=lt>┐∙∙∙∙∙∙∙∙└</span>─┘∙│
│<span class=lt>∙∙∙∙┌─┐∙∙∙∙∙│</span>
│∙<span class=lt>∙∙∙│</span> └────<span class=lt>─┘</span>
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot> ┌───────────┐
 │∙∙∙∙∙∙∙∙∙∙∙│
┌┘∙<span class=lt>──┬</span>─────┐∙│
┤∙<span class=lt>∙∙∙│</span>     │∙│
<span class=lt>┘∙∙∙∙│</span>     │∙│
<span class=lt>@∙∙∙∙└</span>───┐ │∙│
<span class=lt>┐∙∙∙∙∙∙∙∙└</span>─┘∙│
│∙<span class=lt>∙∙∙┌─┐∙∙∙∙∙│</span>
│∙∙<span class=lt>∙∙│</span> └─────<span class=lt>┘</span>
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot> ┌<span class=lt>───</span>────────┐
 │<span class=lt>∙∙∙</span>∙∙∙∙∙∙∙∙│
┌<span class=lt>┘∙──┬</span>─────┐∙│
┤<span class=lt>∙∙∙∙│</span>     │∙│
<span class=lt>┘∙∙∙∙│</span>     │∙│
<span class=lt>@∙∙∙∙└</span>───┐ │∙│
<span class=lt>┐∙∙∙∙∙∙∙∙└</span>─┘∙│
│<span class=lt>∙∙∙∙┌─┐∙∙∙∙∙│</span>
│<span class=lt>∙∙∙∙│</span> └────<span class=lt>─┘</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot> ┌<span class=lt>───</span>────────┐
 │<span class=lt>∙∙</span>∙∙∙∙∙∙∙∙∙│
┌┘<span class=lt>∙──┬</span>─────┐∙│
┤<span class=lt>∙∙∙∙│</span>     │∙│
<span class=lt>┘∙∙∙∙│</span>     │∙│
<span class=lt>@∙∙∙∙└</span>───┐ │∙│
<span class=lt>┐∙∙∙∙∙∙∙∙└</span>─┘∙│
│<span class=lt>∙∙∙∙┌─┐∙∙∙∙∙│</span>
│∙<span class=lt>∙∙∙│</span> └────<span class=lt>─┘</span>
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot> ┌<span class=lt>──</span>─────────┐
 │<span class=lt>∙∙</span>∙∙∙∙∙∙∙∙∙│
┌<span class=lt>┘∙──┬</span>─────┐∙│
┤<span class=lt>∙∙∙∙│</span>     │∙│
<span class=lt>┘∙∙∙∙│</span>     │∙│
<span class=lt>@∙∙∙∙└</span>───┐ │∙│
<span class=lt>┐∙∙∙∙∙∙∙∙└</span>─┘∙│
│<span class=lt>∙∙∙∙┌─┐∙∙∙∙∙│</span>
│<span class=lt>∙∙∙∙│</span> └───<span class=lt>──┘</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot>│   ┌─────────<span class=lt>──┐</span>
│   │∙∙∙∙∙∙∙∙∙∙<span class=lt>∙</span>│
│  ┌┘∙──┬─────<span class=lt>┐∙│</span>
└─┬┤∙∙∙∙│     <span class=lt>│∙│</span>
∙∙└┘∙∙∙∙│     <span class=lt>│∙│</span>
<span class=lt>┐∙∙∙∙∙</span>∙∙└───┐ <span class=lt>│∙│</span>
└──<span class=lt>┐∙∙∙∙∙∙∙∙└─┘∙│</span>
   │∙∙∙∙┌─<span class=lt>┐∙∙∙∙@│</span>
   │∙∙∙∙│ <span class=lt>└─────┘</span>
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>│   ┌─────────<span class=lt>──┐</span>
│   │∙∙∙∙∙∙∙∙∙<span class=lt>∙∙│</span>
│  ┌┘∙──┬─────<span class=lt>┐∙│</span>
└─┬┤∙∙∙∙│     <span class=lt>│∙│</span>
∙∙└┘∙∙∙∙│     <span class=lt>│∙│</span>
<span class=lt>┐∙∙∙∙</span>∙∙∙└───┐ <span class=lt>│∙│</span>
└──<span class=lt>┐∙∙∙∙∙∙∙∙└─┘∙│</span>
   │∙∙∙∙┌─<span class=lt>┐∙∙∙∙@│</span>
   │∙∙∙∙│ <span class=lt>└─────┘</span>
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>│   ┌─────────<span class=lt>──┐</span>
│   │∙∙∙∙∙∙∙∙∙<span class=lt>∙∙│</span>
│  ┌┘∙──┬─────<span class=lt>┐∙│</span>
└─┬┤∙∙∙∙│     <span class=lt>│∙│</span>
<span class=lt>∙</span>∙└┘∙∙∙∙│     <span class=lt>│∙│</span>
<span class=lt>┐∙∙∙∙∙∙</span>∙└───┐ <span class=lt>│∙│</span>
└──<span class=lt>┐∙∙∙∙∙∙∙∙└─┘∙│</span>
   │∙∙∙∙┌─<span class=lt>┐∙∙∙∙@│</span>
   │∙∙∙∙│ <span class=lt>└─────┘</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>│   ┌─────────<span class=lt>──┐</span>
│   │∙∙∙∙∙∙∙∙∙∙<span class=lt>∙│</span>
│  ┌┘∙──┬─────<span class=lt>┐∙│</span>
└─┬┤∙∙∙∙│     <span class=lt>│∙│</span>
∙∙└┘∙∙∙∙│     <span class=lt>│∙│</span>
<span class=lt>┐∙∙∙∙</span>∙∙∙└───┐ <span class=lt>│∙│</span>
└──<span class=lt>┐∙∙∙∙∙∙∙</span>∙<span class=lt>└─┘∙│</span>
   │∙∙∙∙┌─<span class=lt>┐∙∙∙∙@│</span>
   │∙∙∙∙│ <span class=lt>└─────┘</span>
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot>│   ┌─────────<span class=lt>──┐</span>
│   │∙∙∙∙∙∙∙∙∙<span class=lt>∙∙│</span>
│  ┌┘∙──┬─────<span class=lt>┐∙│</span>
└─┬┤∙∙∙∙│     <span class=lt>│∙│</span>
<span class=lt>∙∙└┘∙</span>∙∙∙│     <span class=lt>│∙│</span>
<span class=lt>┐∙∙∙∙∙∙∙└</span>───┐ <span class=lt>│∙│</span>
└──<span class=lt>┐∙∙∙∙∙∙∙∙└─┘∙│</span>
   │∙∙∙∙┌─<span class=lt>┐∙∙∙∙@│</span>
   │∙∙∙∙│ <span class=lt>└─────┘</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>──────</span>─<span class=lt>─┬</span>
<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙∙</span>│
<span class=lt>∙∙∙∙</span>∙<span class=lt>∙∙</span>∙│
<span class=lt>∙∙∙+∙│</span>∙∙│
<span class=lt>∙∙∙∙∙│∙∙│</span>
<span class=lt>∙∙∙∙∙∙∙∙└</span>
<span class=lt>@∙∙∙│</span>∙∙∙∙
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>──────</span>──<span class=lt>┬</span>
<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙∙</span>│
<span class=lt>∙∙∙∙</span>∙<span class=lt>∙∙</span>∙│
<span class=lt>∙∙∙+∙│</span>∙∙│
<span class=lt>∙∙∙∙∙│∙∙│</span>
<span class=lt>∙∙∙∙∙∙∙∙└</span>
<span class=lt>@∙∙∙│</span>∙∙∙∙
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>──────</span>─<span class=lt>─┬</span>
<span class=lt>∙∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙∙∙∙∙∙</span>∙│
<span class=lt>∙∙∙+∙│</span>∙∙│
<span class=lt>∙∙∙∙∙│∙∙│</span>
<span class=lt>∙∙∙∙∙∙∙∙└</span>
<span class=lt>@∙∙∙│</span>∙∙∙∙
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>──────</span>─<span class=lt>─┬</span>
<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙∙│</span>
<span class=lt>∙∙∙∙</span>∙<span class=lt>∙∙</span>∙│
<span class=lt>∙∙∙+∙│</span>∙∙│
<span class=lt>∙∙∙∙∙│∙∙│</span>
<span class=lt>∙∙∙∙∙∙∙∙└</span>
<span class=lt>@∙∙∙│</span>∙∙∙∙
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>─────</span>───┬
<span class=lt>∙∙∙∙∙</span>∙∙∙│
<span class=lt>∙∙∙∙</span>∙∙∙∙│
<span class=lt>∙∙∙+∙│</span>∙∙│
<span class=lt>∙∙∙∙∙│∙∙│</span>
<span class=lt>∙∙∙∙∙∙∙∙└</span>
<span class=lt>@∙∙∙│</span>∙∙∙∙
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot>─<span class=lt>───</span>─┬
∙<span class=lt>∙∙</span>∙∙│
∙<span class=lt>∙∙</span>∙∙<span class=lt>│</span>
<span class=lt>+∙│</span>∙<span class=lt>∙│</span>
<span class=lt>∙∙│∙∙</span>│
<span class=lt>∙∙∙</span>∙∙└
<span class=lt>@│</span>∙∙∙∙
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>─<span class=lt>───</span>─┬
∙<span class=lt>∙∙</span>∙∙│
∙<span class=lt>∙∙</span>∙∙│
<span class=lt>+∙│</span>∙∙│
<span class=lt>∙∙│</span>∙∙│
<span class=lt>∙∙</span>∙∙∙└
<span class=lt>@│</span>∙∙∙∙
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>─<span class=lt>───</span>─┬
∙<span class=lt>∙∙∙</span>∙│
∙<span class=lt>∙∙</span>∙∙<span class=lt>│</span>
<span class=lt>+∙│∙∙│</span>
<span class=lt>∙∙│∙∙│</span>
<span class=lt>∙∙∙∙</span>∙└
<span class=lt>@│</span>∙∙∙∙
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>─<span class=lt>───</span>─┬
∙<span class=lt>∙∙</span>∙∙│
∙<span class=lt>∙∙</span>∙∙│
<span class=lt>+∙│</span>∙<span class=lt>∙│</span>
<span class=lt>∙∙│∙∙│</span>
<span class=lt>∙∙∙</span>∙∙└
<span class=lt>@│</span>∙∙∙∙
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot>─<span class=lt>───</span>─┬
∙<span class=lt>∙∙∙</span>∙│
∙<span class=lt>∙∙</span>∙∙│
<span class=lt>+∙│</span>∙∙<span class=lt>│</span>
<span class=lt>∙∙│∙∙│</span>
<span class=lt>∙∙∙∙∙└</span>
<span class=lt>@│</span>∙∙∙∙
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>┌─┐</span>   
<span class=lt>│@└</span>──┐
<span class=lt>│∙∙∙</span>∙│
<span class=lt>└──┐∙│</span>
   │∙<span class=lt>│</span>
   │∙└
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌─┐</span>   
<span class=lt>│@└</span>──┐
<span class=lt>│∙∙</span>∙∙│
<span class=lt>└──┐</span>∙│
   │∙│
   │∙└
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌─┐</span>   
<span class=lt>│@└</span>──┐
<span class=lt>│∙∙∙∙</span>│
<span class=lt>└──┐∙│</span>
   │<span class=lt>∙│</span>
   │∙└
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌─┐</span>   
<span class=lt>│@└</span>──┐
<span class=lt>│∙∙∙</span>∙│
<span class=lt>└──┐∙│</span>
   │∙<span class=lt>│</span>
   │∙└
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌─┐</span>   
<span class=lt>│@└</span>──┐
<span class=lt>│∙∙∙∙│</span>
<span class=lt>└──┐∙│</span>
   │∙│
   │∙└
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>┌─┘∙</span>└┬─┐
<span class=lt>│∙∙∙</span>∙│<span class=lt>∙│</span>
<span class=lt>│∙∙+∙∙∙│</span>
<span class=lt>│∙@∙∙∙∙│</span>
<span class=lt>└─┬+┬──┘</span>
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌─┘∙</span>└┬─┐
<span class=lt>│∙∙∙</span>∙│∙<span class=lt>│</span>
<span class=lt>│∙∙+∙∙∙│</span>
<span class=lt>│∙@∙∙∙∙│</span>
<span class=lt>└─┬+┬──┘</span>
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌─┘∙└</span>┬─<span class=lt>┐</span>
<span class=lt>│∙∙∙</span>∙<span class=lt>│∙│</span>
<span class=lt>│∙∙+∙∙∙│</span>
<span class=lt>│∙@∙∙∙∙│</span>
<span class=lt>└─┬+┬──┘</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌─┘∙└</span>┬─┐
<span class=lt>│∙∙∙</span>∙│<span class=lt>∙│</span>
<span class=lt>│∙∙+∙∙∙│</span>
<span class=lt>│∙@∙∙∙∙│</span>
<span class=lt>└─┬+┬──┘</span>
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌─┘∙└</span>┬─┐
<span class=lt>│∙∙∙</span>∙<span class=lt>│∙│</span>
<span class=lt>│∙∙+∙∙∙│</span>
<span class=lt>│∙@∙∙∙∙│</span>
<span class=lt>└─┬+┬──┘</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot>┌─┘∙└<span class=lt>┬─┐</span>
│∙∙∙∙<span class=lt>│@│</span>
│∙∙+<span class=lt>∙∙∙│</span>
│∙<span class=lt>∙∙∙∙∙│</span>
└<span class=lt>─┬+┬──┘</span>
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>┌─┘∙└<span class=lt>┬─┐</span>
│∙∙∙∙<span class=lt>│@│</span>
│∙∙+∙<span class=lt>∙∙│</span>
│∙∙∙<span class=lt>∙∙∙│</span>
└─┬<span class=lt>+┬──┘</span>
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>┌─┘∙└<span class=lt>┬─┐</span>
│∙∙∙∙<span class=lt>│@│</span>
│∙∙<span class=lt>+∙∙∙│</span>
│<span class=lt>∙∙∙∙∙∙│</span>
<span class=lt>└─┬+┬──┘</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>┌─┘∙└<span class=lt>┬─┐</span>
│∙∙∙∙<span class=lt>│@│</span>
│∙∙+<span class=lt>∙∙∙│</span>
│∙<span class=lt>∙∙∙∙∙│</span>
└<span class=lt>─┬+┬──┘</span>
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot>┌─┘∙└<span class=lt>┬─┐</span>
│∙∙∙∙<span class=lt>│@│</span>
│∙∙<span class=lt>+∙∙∙│</span>
│<span class=lt>∙∙∙∙∙∙│</span>
└<span class=lt>─┬+┬──┘</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>│@└</span>─────────┐
<span class=lt>│∙∙∙</span>∙∙∙∙∙∙∙∙│
<span class=lt>├───∙─</span>──────┤
│∙∙∙∙<span class=lt>∙∙</span>∙∙∙∙∙│
│∙∙∙∙∙<span class=lt>+∙</span>+∙∙∙│
│∙∙∙∙∙∙∙<span class=lt>∙∙</span>∙∙│
│∙∙∙∙∙∙∙∙│<span class=lt>∙┌</span>┤
└────────┴─<span class=lt>┴</span>┘
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>│@└</span>─────────┐
<span class=lt>│∙∙</span>∙∙∙∙∙∙∙∙∙│
<span class=lt>├───</span>∙───────┤
│∙∙∙∙∙∙∙∙∙∙∙│
│∙∙∙∙∙+∙+∙∙∙│
│∙∙∙∙∙∙∙∙∙∙∙│
│∙∙∙∙∙∙∙∙│∙┌┤
└────────┴─┴┘
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>│@└</span>─────────┐
<span class=lt>│∙∙∙∙</span>∙∙∙∙∙∙∙│
<span class=lt>├───∙─</span>──────┤
│∙∙∙<span class=lt>∙∙∙∙</span>∙∙∙∙│
│∙∙∙∙∙<span class=lt>+∙+</span>∙∙∙│
│∙∙∙∙∙∙<span class=lt>∙∙∙∙</span>∙│
│∙∙∙∙∙∙∙∙<span class=lt>│∙┌</span>┤
└────────┴<span class=lt>─┴</span>┘
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>│@└</span>─────────┐
<span class=lt>│∙∙∙</span>∙∙∙∙∙∙∙∙│
<span class=lt>├───∙─</span>──────┤
│∙∙∙∙<span class=lt>∙∙</span>∙∙∙∙∙│
│∙∙∙∙∙<span class=lt>+∙+</span>∙∙∙│
│∙∙∙∙∙∙∙<span class=lt>∙∙</span>∙∙│
│∙∙∙∙∙∙∙∙<span class=lt>│∙┌</span>┤
└────────┴<span class=lt>─┴</span>┘
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>│@└</span>─────────┐
<span class=lt>│∙∙∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>├───∙───────┤</span>
│∙∙∙∙∙∙∙∙∙∙∙│
│∙∙∙∙∙+∙+∙∙∙│
│∙∙∙∙∙∙∙∙∙∙∙│
│∙∙∙∙∙∙∙∙│∙┌┤
└────────┴─┴┘
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot>│∙│          
<span class=lt>│∙└</span>─────────┐
│∙<span class=lt>∙∙</span>∙∙∙∙∙∙∙∙│
├───<span class=lt>∙─</span>─<span class=lt>─────┤</span>
│∙∙∙∙<span class=lt>∙∙</span>∙<span class=lt>∙∙∙∙│</span>
│∙∙∙∙∙<span class=lt>+∙+∙∙∙│</span>
│∙∙∙∙∙∙∙<span class=lt>∙∙∙∙│</span>
│∙∙∙∙∙∙∙∙<span class=lt>│@┌</span>┤
└────────<span class=lt>┴─┴</span>┘
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>│∙│          
│∙└─────────┐
│∙∙∙∙∙∙∙∙∙∙∙│
├───∙──<span class=lt>─────┤</span>
│∙∙∙∙∙∙∙<span class=lt>∙∙∙∙│</span>
│∙∙∙∙∙+∙<span class=lt>+∙∙∙│</span>
│∙∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>│
│∙∙∙∙∙∙∙∙<span class=lt>│@┌</span>┤
└────────<span class=lt>┴─┴</span>┘
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>│∙</span>│          
<span class=lt>│∙└</span>─────────┐
│<span class=lt>∙∙∙∙</span>∙∙∙∙∙∙∙│
├──<span class=lt>─∙─</span>─<span class=lt>─────┤</span>
│∙∙∙<span class=lt>∙∙∙∙∙∙∙∙│</span>
│∙∙∙∙∙<span class=lt>+∙+∙∙∙│</span>
│∙∙∙∙∙∙<span class=lt>∙∙∙∙∙│</span>
│∙∙∙∙∙∙∙∙<span class=lt>│@┌</span>┤
└────────<span class=lt>┴─┴</span>┘
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>│</span>∙│          
<span class=lt>│∙└</span>─────────┐
│∙<span class=lt>∙∙</span>∙∙∙∙∙∙∙∙│
├──<span class=lt>─∙─</span>─<span class=lt>─────┤</span>
│∙∙∙∙<span class=lt>∙∙</span>∙<span class=lt>∙∙∙∙│</span>
│∙∙∙∙∙<span class=lt>+∙+∙∙∙│</span>
│∙∙∙∙∙∙∙<span class=lt>∙∙∙∙│</span>
│∙∙∙∙∙∙∙∙<span class=lt>│@┌</span>┤
└────────<span class=lt>┴─┴</span>┘
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot>│∙│          
│∙└─────────┐
│∙∙∙∙∙∙∙∙∙∙∙│
├───∙───<span class=lt>────┤</span>
<span class=lt>│∙</span>∙∙∙∙∙∙<span class=lt>∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙+∙+∙∙∙│</span>
<span class=lt>│∙∙∙∙∙∙∙∙∙∙∙│</span>
│∙∙∙∙∙∙∙∙<span class=lt>│@┌</span>┤
└────────<span class=lt>┴─┴</span>┘
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot>────────
∙∙∙∙∙∙∙∙
┬<span class=lt>─</span>∙┌┬───
┘∙<span class=lt>∙└</span>┤   
∙∙<span class=lt>│∙└</span>┐  
∙┌┴<span class=lt>┐∙└</span>┐ 
┌┘ └<span class=lt>┐∙└┐</span>
┘   └<span class=lt>┐@│</span>
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>────────
∙∙∙∙∙∙∙∙
┬<span class=lt>─</span>∙┌┬───
┘∙<span class=lt>∙</span>└┤   
∙∙│<span class=lt>∙</span>└┐  
∙┌┴┐<span class=lt>∙</span>└┐ 
┌┘ └┐<span class=lt>∙└┐</span>
┘   └<span class=lt>┐@│</span>
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>─</span>───────
<span class=lt>∙∙</span>∙∙∙∙∙∙
<span class=lt>┬─∙</span>┌┬───
┘<span class=lt>∙∙└</span>┤   
∙∙<span class=lt>│∙└</span>┐  
∙┌┴<span class=lt>┐∙└</span>┐ 
┌┘ └<span class=lt>┐∙└┐</span>
┘   └<span class=lt>┐@│</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>─</span>───────
∙<span class=lt>∙</span>∙∙∙∙∙∙
┬<span class=lt>─∙</span>┌┬───
┘<span class=lt>∙∙└</span>┤   
∙∙<span class=lt>│∙└</span>┐  
∙┌┴<span class=lt>┐∙└</span>┐ 
┌┘ └<span class=lt>┐∙└┐</span>
┘   └<span class=lt>┐@│</span>
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot>────────
∙∙∙∙∙∙∙∙
┬<span class=lt>─</span>∙┌┬───
┘∙<span class=lt>∙</span>└┤   
∙∙│<span class=lt>∙</span>└┐  
∙┌┴┐<span class=lt>∙└</span>┐ 
┌┘ └<span class=lt>┐∙└┐</span>
┘   └<span class=lt>┐@│</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<div id=lhContainer2>
<a name=cmppillar></a>
<h4>Pillars</h4>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙
<span class=lt>∙∙∙∙∙∙∙</span>∙∙∙∙
<span class=lt>∙∙∙∙∙</span>∙∙∙∙∙∙
<span class=lt>∙∙∙</span>∙∙∙∙∙∙∙∙
<span class=lt>@+</span>∙∙∙∙∙∙∙∙∙
<span class=lt>∙∙∙</span>∙∙∙∙∙∙∙∙
<span class=lt>∙∙∙∙∙</span>∙∙∙∙∙∙
<span class=lt>∙∙∙∙∙∙∙</span>∙∙∙∙
<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙</span>∙∙∙∙∙
<span class=lt>∙∙∙∙∙</span>∙∙∙∙∙∙
<span class=lt>∙∙∙∙</span>∙∙∙∙∙∙∙
<span class=lt>∙∙∙</span>∙∙∙∙∙∙∙∙
<span class=lt>∙∙</span>∙∙∙∙∙∙∙∙∙
<span class=lt>@+</span>∙∙∙∙∙∙∙∙∙
<span class=lt>∙∙</span>∙∙∙∙∙∙∙∙∙
<span class=lt>∙∙∙</span>∙∙∙∙∙∙∙∙
<span class=lt>∙∙∙∙</span>∙∙∙∙∙∙∙
<span class=lt>∙∙∙∙∙</span>∙∙∙∙∙∙
<span class=lt>∙∙∙∙∙∙</span>∙∙∙∙∙
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙</span>∙
<span class=lt>∙∙∙∙∙∙∙∙</span>∙∙∙
<span class=lt>∙∙∙∙∙∙</span>∙∙∙∙∙
<span class=lt>∙∙∙∙</span>∙∙∙∙∙∙∙
<span class=lt>@+</span>∙∙∙∙∙∙∙∙∙
<span class=lt>∙∙∙∙</span>∙∙∙∙∙∙∙
<span class=lt>∙∙∙∙∙∙</span>∙∙∙∙∙
<span class=lt>∙∙∙∙∙∙∙∙</span>∙∙∙
<span class=lt>∙∙∙∙∙∙∙∙∙∙</span>∙
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙
<span class=lt>∙∙∙∙∙∙∙</span>∙∙∙∙
<span class=lt>∙∙∙∙∙</span>∙∙∙∙∙∙
<span class=lt>∙∙∙</span>∙∙∙∙∙∙∙∙
<span class=lt>@+</span>∙∙∙∙∙∙∙∙∙
<span class=lt>∙∙∙</span>∙∙∙∙∙∙∙∙
<span class=lt>∙∙∙∙∙</span>∙∙∙∙∙∙
<span class=lt>∙∙∙∙∙∙∙</span>∙∙∙∙
<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>@+</span>∙∙∙∙∙∙∙∙∙
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot>┌────<span class=lt>──────</span>
│∙∙∙∙∙<span class=lt>∙∙∙∙∙</span>
│∙∙∙∙∙<span class=lt>∙∙∙∙∙</span>
│∙∙∙∙∙∙<span class=lt>∙∙∙∙</span>
│∙∙∙∙∙∙<span class=lt>∙∙∙∙</span>
<span class=lt>│</span>∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>
<span class=lt>│∙∙</span>∙∙∙∙∙<span class=lt>∙∙∙</span>
<span class=lt>│∙∙∙∙</span>∙∙∙∙<span class=lt>∙∙</span>
<span class=lt>│∙∙∙∙∙∙</span>∙∙<span class=lt>∙∙</span>
<span class=lt>│∙∙∙∙∙∙∙∙┼∙</span>
<span class=lt>│∙∙∙∙∙∙∙∙∙@</span>
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>┌──────<span class=lt>────</span>
│∙∙∙∙∙∙<span class=lt>∙∙∙∙</span>
│∙∙∙∙∙∙<span class=lt>∙∙∙∙</span>
│∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>
│∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>
│∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>
│∙∙∙∙∙∙∙∙<span class=lt>∙∙</span>
<span class=lt>│∙∙</span>∙∙∙∙∙∙<span class=lt>∙∙</span>
<span class=lt>│∙∙∙∙∙</span>∙∙∙<span class=lt>∙∙</span>
<span class=lt>│∙∙∙∙∙∙∙∙┼∙</span>
<span class=lt>│∙∙∙∙∙∙∙∙∙@</span>
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>┌────<span class=lt>──────</span>
│∙∙∙∙<span class=lt>∙∙∙∙∙∙</span>
│∙∙∙∙∙<span class=lt>∙∙∙∙∙</span>
│∙∙∙∙∙<span class=lt>∙∙∙∙∙</span>
│∙∙∙∙∙∙<span class=lt>∙∙∙∙</span>
<span class=lt>│∙</span>∙∙∙∙∙<span class=lt>∙∙∙∙</span>
<span class=lt>│∙∙∙</span>∙∙∙∙<span class=lt>∙∙∙</span>
<span class=lt>│∙∙∙∙∙</span>∙∙<span class=lt>∙∙∙</span>
<span class=lt>│∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙</span>
<span class=lt>│∙∙∙∙∙∙∙∙┼∙</span>
<span class=lt>│∙∙∙∙∙∙∙∙∙@</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>┌────<span class=lt>──────</span>
│∙∙∙∙∙<span class=lt>∙∙∙∙∙</span>
│∙∙∙∙∙<span class=lt>∙∙∙∙∙</span>
│∙∙∙∙∙∙<span class=lt>∙∙∙∙</span>
│∙∙∙∙∙∙<span class=lt>∙∙∙∙</span>
<span class=lt>│</span>∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>
<span class=lt>│∙∙</span>∙∙∙∙∙<span class=lt>∙∙∙</span>
<span class=lt>│∙∙∙∙</span>∙∙∙∙<span class=lt>∙∙</span>
<span class=lt>│∙∙∙∙∙∙</span>∙∙<span class=lt>∙∙</span>
<span class=lt>│∙∙∙∙∙∙∙∙┼∙</span>
<span class=lt>│∙∙∙∙∙∙∙∙∙@</span>
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot>┌─<span class=lt>─────────</span>
│∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>
<span class=lt>│∙</span>∙<span class=lt>∙∙∙∙∙∙∙∙</span>
<span class=lt>│∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙</span>
<span class=lt>│∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙</span>
<span class=lt>│∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙</span>
<span class=lt>│∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙</span>
<span class=lt>│∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙</span>
<span class=lt>│∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙</span>
<span class=lt>│∙∙∙∙∙∙∙∙┼∙</span>
<span class=lt>│∙∙∙∙∙∙∙∙∙@</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙
<span class=lt>∙∙∙∙∙+</span>∙<span class=lt>∙∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙</span>∙∙∙
<span class=lt>∙∙∙∙∙+∙∙∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙
<span class=lt>∙∙∙∙∙+∙∙∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙</span>∙∙∙
<span class=lt>∙∙∙∙∙+</span>∙∙<span class=lt>∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙</span>∙
<span class=lt>∙∙∙∙∙+∙∙∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>∙
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙</span>∙∙∙<span class=lt>∙</span>
<span class=lt>∙∙∙∙∙∙∙∙+∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>∙∙
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>∙∙∙<span class=lt>∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙+∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>∙
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙+∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>∙∙
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>∙∙∙∙<span class=lt>∙</span>
<span class=lt>∙∙∙∙∙∙∙∙+</span>∙<span class=lt>∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙+∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>┌─</span>───<span class=lt>───────────</span>───<span class=lt>─┐</span>
<span class=lt>│∙∙</span>∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙∙<span class=lt>∙∙│</span>
<span class=lt>│∙∙∙</span>∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙<span class=lt>∙∙∙│</span>
<span class=lt>│∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙│</span>
┤<span class=lt>∙∙∙∙∙∙∙+∙∙∙+∙∙∙∙∙∙∙</span>│
│∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>∙∙∙∙├
┤∙∙∙∙∙∙∙<span class=lt>+∙@∙+</span>∙∙∙∙∙∙∙│
│∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>∙∙∙∙├
│<span class=lt>∙∙∙∙∙∙∙+∙∙∙+∙∙∙∙∙∙∙</span>│
<span class=lt>│∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙│</span>
<span class=lt>│∙∙∙</span>∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙<span class=lt>∙∙∙│</span>
<span class=lt>│∙∙</span>∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙∙<span class=lt>∙∙│</span>
<span class=lt>┴─</span>───<span class=lt>───────────</span>───<span class=lt>─┴</span>
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>┌─────<span class=lt>─────────</span>─────┐
<span class=lt>│∙</span>∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙∙∙<span class=lt>∙│</span>
<span class=lt>│∙∙</span>∙∙∙∙<span class=lt>∙∙∙∙∙∙∙</span>∙∙∙∙<span class=lt>∙∙│</span>
<span class=lt>│∙∙∙∙</span>∙∙<span class=lt>∙∙∙∙∙∙∙</span>∙∙<span class=lt>∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙│</span>
┤∙∙<span class=lt>∙∙∙∙∙+∙∙∙+∙∙∙∙∙</span>∙∙│
│∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙∙∙∙├
┤∙∙∙∙∙∙∙<span class=lt>+∙@∙+</span>∙∙∙∙∙∙∙│
│∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙∙∙∙├
│∙∙<span class=lt>∙∙∙∙∙+∙∙∙+∙∙∙∙∙</span>∙∙│
<span class=lt>│∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙</span>∙∙<span class=lt>∙∙∙∙∙∙∙</span>∙∙<span class=lt>∙∙∙∙│</span>
<span class=lt>│∙∙</span>∙∙∙∙<span class=lt>∙∙∙∙∙∙∙</span>∙∙∙∙<span class=lt>∙∙│</span>
<span class=lt>│∙</span>∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙∙∙<span class=lt>∙│</span>
┴─────<span class=lt>─────────</span>─────┴
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌─</span>───<span class=lt>───────────</span>───<span class=lt>─┐</span>
<span class=lt>│∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙│</span>
<span class=lt>│∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>┤∙∙∙∙∙∙∙+∙∙∙+∙∙∙∙∙∙∙│</span>
│∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙</span>∙∙∙├
┤∙∙∙∙∙∙∙<span class=lt>+∙@∙+</span>∙∙∙∙∙∙∙│
│∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙</span>∙∙∙├
<span class=lt>│∙∙∙∙∙∙∙+∙∙∙+∙∙∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙│</span>
<span class=lt>│∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙│</span>
<span class=lt>┴─</span>───<span class=lt>───────────</span>───<span class=lt>─┴</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌─</span>───<span class=lt>───────────</span>───<span class=lt>─┐</span>
<span class=lt>│∙∙</span>∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙∙<span class=lt>∙∙│</span>
<span class=lt>│∙∙∙</span>∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙<span class=lt>∙∙∙│</span>
<span class=lt>│∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙│</span>
<span class=lt>┤∙∙∙∙∙∙∙+∙∙∙+∙∙∙∙∙∙∙│</span>
│∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>∙∙∙∙├
┤∙∙∙∙∙∙∙<span class=lt>+∙@∙+</span>∙∙∙∙∙∙∙│
│∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>∙∙∙∙├
<span class=lt>│∙∙∙∙∙∙∙+∙∙∙+∙∙∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙│</span>
<span class=lt>│∙∙∙</span>∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙<span class=lt>∙∙∙│</span>
<span class=lt>│∙∙</span>∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙∙<span class=lt>∙∙│</span>
<span class=lt>┴─</span>───<span class=lt>───────────</span>───<span class=lt>─┴</span>
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>┌──</span>──<span class=lt>───────────</span>──<span class=lt>──┐</span>
<span class=lt>│∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙│</span>
<span class=lt>│∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙│</span>
<span class=lt>┤∙∙∙∙∙∙∙+∙∙∙+∙∙∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙├</span>
┤∙∙∙∙∙∙∙<span class=lt>+∙@∙+</span>∙∙∙∙∙∙∙│
<span class=lt>│∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙├</span>
<span class=lt>│∙∙∙∙∙∙∙+∙∙∙+∙∙∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙│</span>
<span class=lt>│∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙∙│</span>
<span class=lt>│∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>∙<span class=lt>∙∙∙│</span>
<span class=lt>┴──</span>──<span class=lt>───────────</span>──<span class=lt>──┴</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot><span class=lt>───</span>───<span class=lt>────</span>────┐
<span class=lt>∙∙</span>∙∙∙<span class=lt>∙∙∙∙</span>∙∙∙∙∙│
<span class=lt>∙∙+</span>∙<span class=lt>∙∙∙</span>∙∙∙∙∙∙∙│
<span class=lt>∙∙∙∙∙∙</span>∙∙∙∙∙∙∙∙│
<span class=lt>∙∙+∙∙</span>∙∙∙∙∙∙<span class=lt>∙∙∙│</span>
<span class=lt>∙∙∙∙</span>∙∙∙<span class=lt>∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙+∙∙∙∙∙∙∙∙∙∙∙├</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙∙∙∙+</span>
<span class=lt>∙∙+∙∙∙∙∙∙∙∙∙∙∙├</span>
<span class=lt>∙∙∙∙</span>∙∙∙<span class=lt>∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙+∙∙</span>∙∙∙∙∙∙<span class=lt>∙∙∙│</span>
<span class=lt>∙∙∙∙∙∙</span>∙∙∙∙∙∙∙∙│
<span class=lt>∙∙+</span>∙<span class=lt>∙∙∙∙</span>∙∙∙∙∙∙│
<span class=lt>∙∙∙</span>∙∙<span class=lt>∙∙∙∙</span>∙∙∙∙∙│
<span class=lt>───</span>───<span class=lt>────</span>────┤
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>───</span>────<span class=lt>─</span>──────┐
<span class=lt>∙∙∙</span>∙∙∙<span class=lt>∙</span>∙∙∙∙∙∙∙│
<span class=lt>∙∙+</span>∙∙<span class=lt>∙</span>∙∙∙∙∙∙∙∙│
<span class=lt>∙∙∙</span>∙<span class=lt>∙</span>∙∙∙∙∙∙∙∙∙│
<span class=lt>∙∙+∙</span>∙∙∙∙∙∙∙∙∙<span class=lt>∙│</span>
<span class=lt>∙∙∙</span>∙∙∙∙∙<span class=lt>∙∙∙∙∙∙│</span>
<span class=lt>∙∙+∙∙∙∙∙∙∙∙∙∙∙├</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙∙∙∙+</span>
<span class=lt>∙∙+∙∙∙∙∙∙∙∙∙∙∙├</span>
<span class=lt>∙∙∙</span>∙∙∙∙∙<span class=lt>∙∙∙∙∙∙│</span>
<span class=lt>∙∙+∙</span>∙∙∙∙∙∙∙∙∙<span class=lt>∙│</span>
<span class=lt>∙∙∙</span>∙<span class=lt>∙</span>∙∙∙∙∙∙∙∙∙│
<span class=lt>∙∙+</span>∙∙<span class=lt>∙</span>∙∙∙∙∙∙∙∙│
<span class=lt>∙∙∙</span>∙∙∙<span class=lt>∙</span>∙∙∙∙∙∙∙│
<span class=lt>───</span>────<span class=lt>─</span>──────┤
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>───────────</span>───┐
<span class=lt>∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙</span>∙∙∙∙│
<span class=lt>∙∙+∙∙∙∙∙</span>∙∙∙∙∙∙│
<span class=lt>∙∙∙∙∙∙∙</span>∙∙∙∙∙∙∙<span class=lt>│</span>
<span class=lt>∙∙+∙∙∙</span>∙∙∙∙<span class=lt>∙∙∙∙│</span>
<span class=lt>∙∙∙∙</span>∙∙<span class=lt>∙∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙+∙∙∙∙∙∙∙∙∙∙∙├</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙∙∙∙+</span>
<span class=lt>∙∙+∙∙∙∙∙∙∙∙∙∙∙├</span>
<span class=lt>∙∙∙∙</span>∙∙<span class=lt>∙∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙+∙∙∙</span>∙∙∙∙<span class=lt>∙∙∙∙│</span>
<span class=lt>∙∙∙∙∙∙∙</span>∙∙∙∙∙∙∙<span class=lt>│</span>
<span class=lt>∙∙+∙∙∙∙∙</span>∙∙∙∙∙∙│
<span class=lt>∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙</span>∙∙∙∙│
<span class=lt>───────────</span>───┤
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>───</span>──<span class=lt>─────</span>────┐
<span class=lt>∙∙∙</span>∙∙<span class=lt>∙∙∙∙</span>∙∙∙∙∙│
<span class=lt>∙∙+</span>∙<span class=lt>∙∙∙∙</span>∙∙∙∙∙∙│
<span class=lt>∙∙∙∙∙∙</span>∙∙∙∙∙∙∙∙│
<span class=lt>∙∙+∙∙</span>∙∙∙∙∙∙<span class=lt>∙∙∙│</span>
<span class=lt>∙∙∙∙</span>∙∙∙<span class=lt>∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙+∙∙∙∙∙∙∙∙∙∙∙├</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙∙∙∙+</span>
<span class=lt>∙∙+∙∙∙∙∙∙∙∙∙∙∙├</span>
<span class=lt>∙∙∙∙</span>∙∙∙<span class=lt>∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙+∙∙</span>∙∙∙∙∙∙<span class=lt>∙∙∙│</span>
<span class=lt>∙∙∙∙∙∙</span>∙∙∙∙∙∙∙∙│
<span class=lt>∙∙+</span>∙<span class=lt>∙∙∙∙</span>∙∙∙∙∙∙│
<span class=lt>∙∙∙</span>∙∙<span class=lt>∙∙∙∙</span>∙∙∙∙∙│
<span class=lt>───</span>──<span class=lt>─────</span>────┤
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>───</span>────<span class=lt>─────</span>──┐
<span class=lt>∙∙∙</span>∙∙∙<span class=lt>∙∙∙∙∙∙</span>∙<span class=lt>∙│</span>
<span class=lt>∙∙+</span>∙∙<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙∙∙│</span>
<span class=lt>∙∙∙</span>∙<span class=lt>∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙│</span>
<span class=lt>∙∙+∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙+∙∙∙∙∙∙∙∙∙∙∙├</span>
<span class=lt>@∙∙∙∙∙∙∙∙∙∙∙∙∙+</span>
<span class=lt>∙∙+∙∙∙∙∙∙∙∙∙∙∙├</span>
<span class=lt>∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙+∙∙∙</span>∙<span class=lt>∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙∙</span>∙<span class=lt>∙∙∙∙</span>∙<span class=lt>∙∙∙∙∙│</span>
<span class=lt>∙∙+</span>∙∙<span class=lt>∙∙∙∙∙</span>∙<span class=lt>∙∙∙│</span>
<span class=lt>∙∙∙</span>∙∙∙<span class=lt>∙∙∙∙∙∙</span>∙<span class=lt>∙│</span>
<span class=lt>───</span>────<span class=lt>─────</span>──┤
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot>+∙∙∙<span class=lt>+∙+</span>∙∙∙+
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
∙∙+∙+<span class=lt>∙</span>+∙+∙∙
∙∙∙∙∙<span class=lt>∙</span>∙∙∙∙∙
+∙∙∙<span class=lt>+∙+</span>∙∙∙+
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
<span class=lt>+∙+∙+∙+∙+∙+</span>
<span class=lt>∙∙∙∙∙@∙∙∙∙∙</span>
<span class=lt>+∙+∙+∙+∙+∙+</span>
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
+∙∙∙<span class=lt>+∙+</span>∙∙∙+
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
∙∙+∙<span class=lt>+∙+</span>∙+∙∙
∙∙∙∙∙<span class=lt>∙</span>∙∙∙∙∙
+∙∙∙+<span class=lt>∙</span>+∙∙∙+
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>+∙∙∙<span class=lt>+∙+</span>∙∙∙+
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
∙∙+∙<span class=lt>+∙+</span>∙+∙∙
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
+∙∙∙<span class=lt>+∙+</span>∙∙∙+
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
<span class=lt>+∙+∙+∙+∙+∙+</span>
<span class=lt>∙∙∙∙∙@∙∙∙∙∙</span>
<span class=lt>+∙+∙+∙+∙+∙+</span>
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
+∙∙∙<span class=lt>+∙+</span>∙∙∙+
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
∙∙+∙<span class=lt>+∙+</span>∙+∙∙
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
+∙∙∙<span class=lt>+∙+</span>∙∙∙+
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>+<span class=lt>∙∙</span>∙<span class=lt>+∙+</span>∙<span class=lt>∙∙</span>+
∙∙<span class=lt>∙</span>∙<span class=lt>∙∙∙</span>∙<span class=lt>∙</span>∙∙
∙∙<span class=lt>+∙+∙+∙+</span>∙∙
∙∙∙<span class=lt>∙∙∙∙∙</span>∙∙∙
<span class=lt>+</span>∙∙<span class=lt>∙+∙+∙</span>∙∙<span class=lt>+</span>
<span class=lt>∙∙∙</span>∙<span class=lt>∙∙∙</span>∙<span class=lt>∙∙∙</span>
<span class=lt>+∙+∙+∙+∙+∙+</span>
<span class=lt>∙∙∙∙∙@∙∙∙∙∙</span>
<span class=lt>+∙+∙+∙+∙+∙+</span>
<span class=lt>∙∙∙</span>∙<span class=lt>∙∙∙</span>∙<span class=lt>∙∙∙</span>
<span class=lt>+</span>∙∙<span class=lt>∙+∙+∙</span>∙∙<span class=lt>+</span>
∙∙∙<span class=lt>∙∙∙∙∙</span>∙∙∙
∙∙<span class=lt>+∙+∙+∙+</span>∙∙
∙∙<span class=lt>∙</span>∙<span class=lt>∙∙∙</span>∙<span class=lt>∙</span>∙∙
+<span class=lt>∙∙</span>∙<span class=lt>+∙+</span>∙<span class=lt>∙∙</span>+
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>+∙∙∙<span class=lt>+∙+</span>∙∙∙+
∙∙∙∙∙<span class=lt>∙</span>∙∙∙∙∙
∙∙+∙<span class=lt>+∙+</span>∙+∙∙
∙∙∙∙∙<span class=lt>∙</span>∙∙∙∙∙
+∙∙∙<span class=lt>+∙+</span>∙∙∙+
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
<span class=lt>+</span>∙<span class=lt>+∙+∙+∙+</span>∙<span class=lt>+</span>
<span class=lt>∙∙∙∙∙@∙∙∙∙∙</span>
<span class=lt>+</span>∙<span class=lt>+∙+∙+∙+</span>∙<span class=lt>+</span>
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
+∙∙∙<span class=lt>+∙+</span>∙∙∙+
∙∙∙∙∙<span class=lt>∙</span>∙∙∙∙∙
∙∙+∙<span class=lt>+∙+</span>∙+∙∙
∙∙∙∙∙<span class=lt>∙</span>∙∙∙∙∙
+∙∙∙<span class=lt>+∙+</span>∙∙∙+
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot>+∙∙∙<span class=lt>+∙+</span>∙∙∙+
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
∙∙+∙<span class=lt>+∙+</span>∙+∙∙
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
+∙∙∙<span class=lt>+∙+</span>∙∙∙+
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
<span class=lt>+∙+∙+∙+∙+∙+</span>
<span class=lt>∙∙∙∙∙@∙∙∙∙∙</span>
<span class=lt>+∙+∙+∙+∙+∙+</span>
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
+∙∙∙<span class=lt>+∙+</span>∙∙∙+
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
∙∙+∙<span class=lt>+∙+</span>∙+∙∙
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
+∙∙∙<span class=lt>+∙+</span>∙∙∙+
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot>∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙+∙+∙+∙+</span>∙
<span class=lt>∙+∙+∙+∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙@∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙+∙+∙+∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙+∙+∙+∙+</span>∙
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙+∙+∙+∙+∙</span>
<span class=lt>∙+∙+∙+∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙@∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙+∙+∙+∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙+∙+∙+∙+∙</span>
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙+∙+∙+∙+∙</span>
<span class=lt>∙+∙+∙+∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙@∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙+∙+∙+∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙+∙+∙+∙+∙</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙+∙+∙+</span>∙<span class=lt>+</span>∙
∙<span class=lt>+</span>∙<span class=lt>+</span>∙<span class=lt>+∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙@∙∙∙∙∙∙∙∙∙∙∙</span>
∙<span class=lt>+</span>∙<span class=lt>+</span>∙<span class=lt>+∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙+∙+∙+</span>∙<span class=lt>+</span>∙
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot>∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙+∙+∙+∙+∙</span>
<span class=lt>∙+∙+∙+∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙∙∙∙∙∙∙∙∙@∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>∙+∙+∙+∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙+∙+∙+∙+∙</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot>∙∙∙<span class=lt>+∙+</span>∙∙∙<span class=lt>+∙+</span>∙∙∙<span class=lt>+∙+</span>∙∙∙
∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙<span class=lt>∙</span>∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
∙∙∙∙∙+<span class=lt>∙+</span>∙<span class=lt>+∙+</span>∙<span class=lt>+∙</span>+∙∙∙∙∙
∙∙∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙</span>∙∙∙∙∙∙∙
∙+∙+∙+∙<span class=lt>+∙+∙+∙+</span>∙+∙+∙+∙
∙∙∙∙∙∙∙∙<span class=lt>∙∙∙∙∙</span>∙∙∙∙∙∙∙∙
∙∙∙∙∙∙∙∙∙<span class=lt>+@+</span>∙∙∙∙∙∙∙∙∙
∙∙∙∙∙∙∙∙<span class=lt>∙∙∙∙∙</span>∙∙∙∙∙∙∙∙
∙+∙+∙+∙<span class=lt>+∙+∙+∙+</span>∙+∙+∙+∙
∙∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙∙∙∙∙
∙∙∙∙∙<span class=lt>+∙+</span>∙<span class=lt>+∙+</span>∙<span class=lt>+∙+</span>∙∙∙∙∙
∙∙∙∙<span class=lt>∙∙∙</span>∙∙<span class=lt>∙∙∙</span>∙∙∙<span class=lt>∙</span>∙∙∙∙∙
∙∙∙<span class=lt>+∙+</span>∙∙∙<span class=lt>+∙+</span>∙∙∙<span class=lt>+∙</span>+∙∙∙
</pre>
<div class=caption>Ray casting</div>
</div>
<div class=sshotc>
<pre class=sshot>∙∙∙+<span class=lt>∙</span>+∙∙∙<span class=lt>+∙+</span>∙∙∙+<span class=lt>∙</span>+∙∙∙
∙∙∙∙∙<span class=lt>∙</span>∙∙∙<span class=lt>∙∙∙</span>∙∙∙<span class=lt>∙</span>∙∙∙∙∙
∙∙∙∙∙+<span class=lt>∙</span>+∙<span class=lt>+∙+</span>∙+<span class=lt>∙</span>+∙∙∙∙∙
∙∙∙∙∙∙∙<span class=lt>∙</span>∙<span class=lt>∙∙∙</span>∙<span class=lt>∙</span>∙∙∙∙∙∙∙
∙+∙+∙+∙+<span class=lt>∙+∙+∙</span>+∙+∙+∙+∙
∙∙∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙∙∙∙∙∙
∙∙∙∙∙∙∙∙∙<span class=lt>+@+</span>∙∙∙∙∙∙∙∙∙
∙∙∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙∙∙∙∙∙
∙+∙+∙+∙+<span class=lt>∙+∙+∙</span>+∙+∙+∙+∙
∙∙∙∙∙∙∙<span class=lt>∙</span>∙<span class=lt>∙∙∙</span>∙<span class=lt>∙</span>∙∙∙∙∙∙∙
∙∙∙∙∙+<span class=lt>∙</span>+∙<span class=lt>+∙+</span>∙+<span class=lt>∙</span>+∙∙∙∙∙
∙∙∙∙∙<span class=lt>∙</span>∙∙∙<span class=lt>∙∙∙</span>∙∙∙<span class=lt>∙</span>∙∙∙∙∙
∙∙∙+<span class=lt>∙</span>+∙∙∙<span class=lt>+∙+</span>∙∙∙+<span class=lt>∙</span>+∙∙∙
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>∙</span>∙∙∙<span class=lt>+∙+</span>∙∙∙<span class=lt>+∙+</span>∙∙∙<span class=lt>+∙+</span>∙∙∙<span class=lt>│</span>
<span class=lt>∙∙∙</span>∙∙<span class=lt>∙∙∙</span>∙∙<span class=lt>∙∙∙</span>∙∙<span class=lt>∙∙∙</span>∙∙<span class=lt>∙∙│</span>
∙∙<span class=lt>∙∙∙</span>∙<span class=lt>+∙+</span>∙<span class=lt>+∙+</span>∙<span class=lt>+∙+</span>∙<span class=lt>∙∙∙</span>∙│
∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>∙∙∙│
∙∙+∙+∙<span class=lt>+∙+∙+∙+∙+∙+</span>∙+∙+∙│
∙∙∙∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙</span>∙∙∙∙∙∙∙│
∙∙∙∙∙∙∙∙∙∙<span class=lt>+@+</span>∙∙∙∙∙∙∙∙∙│
∙∙∙∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙</span>∙∙∙∙∙∙∙│
∙∙+∙+∙<span class=lt>+∙+∙+∙+∙+∙+</span>∙+∙+∙│
∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>∙∙∙│
∙∙<span class=lt>∙∙∙</span>∙<span class=lt>+∙+</span>∙<span class=lt>+∙+</span>∙<span class=lt>+∙+</span>∙<span class=lt>∙∙∙</span>∙│
<span class=lt>∙∙∙</span>∙∙<span class=lt>∙∙∙</span>∙∙<span class=lt>∙∙∙</span>∙∙<span class=lt>∙∙∙</span>∙∙<span class=lt>∙∙│</span>
<span class=lt>∙</span>∙∙∙<span class=lt>+∙+</span>∙∙∙<span class=lt>+∙+</span>∙∙∙<span class=lt>+∙+</span>∙∙∙<span class=lt>│</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>∙∙∙∙<span class=lt>+∙+</span>∙∙∙<span class=lt>+∙+</span>∙∙∙<span class=lt>+∙+</span>∙∙∙│
∙∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙<span class=lt>∙</span>∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙│
∙∙∙∙∙∙<span class=lt>+∙+</span>∙<span class=lt>+∙+</span>∙<span class=lt>+∙+</span>∙∙∙∙∙│
∙∙∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙∙∙∙∙│
∙∙+∙+∙+∙<span class=lt>+∙+∙+∙+</span>∙+∙+∙+∙│
∙∙∙∙∙∙∙∙∙<span class=lt>∙∙∙∙∙</span>∙∙∙∙∙∙∙∙│
∙∙∙∙∙∙∙∙∙∙<span class=lt>+@+</span>∙∙∙∙∙∙∙∙∙│
∙∙∙∙∙∙∙∙∙<span class=lt>∙∙∙∙∙</span>∙∙∙∙∙∙∙∙│
∙∙+∙+∙+∙<span class=lt>+∙+∙+∙+</span>∙+∙+∙+∙│
∙∙∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>∙∙∙∙∙∙│
∙∙∙∙∙∙<span class=lt>+∙+</span>∙<span class=lt>+∙+</span>∙<span class=lt>+∙+</span>∙∙∙∙∙│
∙∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙<span class=lt>∙</span>∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙│
∙∙∙∙<span class=lt>+∙+</span>∙∙∙<span class=lt>+∙+</span>∙∙∙<span class=lt>+∙+</span>∙∙∙│
</pre>
<div class=caption>My algorithm</div>
</div>
<div class=sshotc>
<pre class=sshot>∙∙∙∙+<span class=lt>∙</span>+∙∙∙<span class=lt>+∙+</span>∙∙∙+<span class=lt>∙</span>+∙∙∙│
∙∙∙∙∙∙<span class=lt>∙</span>∙∙∙<span class=lt>∙∙∙</span>∙∙∙<span class=lt>∙</span>∙∙∙∙∙│
∙∙∙∙∙∙+<span class=lt>∙</span>+∙<span class=lt>+∙+</span>∙+<span class=lt>∙</span>+∙∙∙∙∙│
∙∙∙∙∙∙∙∙<span class=lt>∙</span>∙<span class=lt>∙∙∙</span>∙<span class=lt>∙</span>∙∙∙∙∙∙∙│
<span class=lt>∙∙+∙+∙+∙+∙+∙+∙+∙+∙+∙+∙│</span>
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙│</span>
∙∙∙∙∙∙∙∙∙∙<span class=lt>+@+</span>∙∙∙∙∙∙∙∙∙│
<span class=lt>∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙│</span>
<span class=lt>∙∙+∙+∙+∙+∙+∙+∙+∙+∙+∙+∙│</span>
∙∙∙∙∙∙∙∙<span class=lt>∙</span>∙<span class=lt>∙∙∙</span>∙<span class=lt>∙</span>∙∙∙∙∙∙∙│
∙∙∙∙∙∙+<span class=lt>∙</span>+∙<span class=lt>+∙+</span>∙+<span class=lt>∙</span>+∙∙∙∙∙│
∙∙∙∙∙∙<span class=lt>∙</span>∙∙∙<span class=lt>∙∙∙</span>∙∙∙<span class=lt>∙</span>∙∙∙∙∙│
∙∙∙∙+<span class=lt>∙</span>+∙∙∙<span class=lt>+∙+</span>∙∙∙+<span class=lt>∙</span>+∙∙∙│
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
</div> 
<a name=cmpsymmetry></a>
<h4>Symmetrical versions</h4>
This is a comparison between the symmetrical versions of the algorithms. Ray casting is not included because it cannot
be made symmetrical with reasonable efficiency. My algorithm has two symmetrical versions: one that's fully symmetrical
and another that's symmetrical except for some walls (i.e. that's symmetrical between monsters except for some passwall
monsters).
<p>
<div class=sshotc>
<pre class=sshot>│∙└───────<span class=lt>───</span>─────────┤
<span class=lt>│∙∙∙∙∙∙∙∙∙∙@∙∙∙∙∙∙∙∙∙∙+</span>
└───────┬┬<span class=lt>─∙┌</span>┬────────┤
        ├┘∙<span class=lt>∙</span>└┤        │
       ┌┘∙<span class=lt>∙│</span>∙└┐       │
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>│∙└──────<span class=lt>─────</span>────────┤
<span class=lt>│∙∙∙∙∙∙∙∙∙∙@∙∙∙∙∙∙∙∙∙∙+</span>
└───────┬<span class=lt>┬─∙┌┬</span>────────┤
        ├┘<span class=lt>∙∙└</span>┤        │
       ┌┘∙<span class=lt>∙│</span>∙└┐       │
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>│∙└──────<span class=lt>─────</span>────────┤
<span class=lt>│∙∙∙∙∙∙∙∙∙∙@∙∙∙∙∙∙∙∙∙∙+</span>
└───────┬<span class=lt>┬─∙┌┬</span>────────┤
        ├┘<span class=lt>∙∙└</span>┤        │
       ┌┘∙<span class=lt>∙│</span>∙└┐       │
</pre>
<div class=caption>My algorithm (full symmetry)</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>│</span>∙<span class=lt>└───────────────────┤</span>
<span class=lt>│∙∙∙∙∙∙∙∙∙∙@∙∙∙∙∙∙∙∙∙∙+</span>
<span class=lt>└───────┬┬─∙┌┬────────┤</span>
        ├┘<span class=lt>∙∙└</span>┤        │
       ┌┘∙<span class=lt>∙│</span>∙└┐       │
</pre>
<div class=caption>My algorithm (partial symmetry)</div>
</div>
<div class=sshotc>
<pre class=sshot><span class=lt>│∙└───────────────────┤</span>
<span class=lt>│∙∙∙∙∙∙∙∙∙∙@∙∙∙∙∙∙∙∙∙∙+</span>
<span class=lt>└───────┬┬─∙┌┬────────┤</span>
        ├┘<span class=lt>∙∙└</span>┤        │
       ┌┘<span class=lt>∙∙│∙</span>└┐       │
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot>   │∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙
   │∙∙∙∙∙∙∙∙∙∙<span class=lt>∙</span>∙∙∙∙
<span class=lt>──</span>─┤∙∙∙<span class=lt>∙∙∙∙┼</span>∙∙∙┼∙∙∙
<span class=lt>@∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>──</span>─┤∙∙∙<span class=lt>∙∙∙∙┼</span>∙∙∙┼∙∙∙
   │∙∙∙∙∙∙∙∙∙∙<span class=lt>∙</span>∙∙∙∙
   │∙∙∙∙∙∙∙┼∙∙∙┼∙∙∙
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>   │∙∙∙∙∙∙∙∙∙∙∙∙∙∙<span class=lt>∙</span>
   │∙∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
<span class=lt>───</span>┤∙∙<span class=lt>∙∙∙∙∙┼</span>∙∙∙┼∙∙∙
<span class=lt>@∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───</span>┤∙∙<span class=lt>∙∙∙∙∙┼</span>∙∙∙┼∙∙∙
   │∙∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
   │∙∙∙∙∙∙∙┼∙∙∙┼∙∙<span class=lt>∙</span>
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>   │∙∙∙∙∙∙∙∙∙∙∙∙∙∙<span class=lt>∙</span>
   │∙∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
<span class=lt>───</span>┤∙∙<span class=lt>∙∙∙∙∙┼</span>∙∙∙┼∙∙∙
<span class=lt>@∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───</span>┤∙∙<span class=lt>∙∙∙∙∙┼</span>∙∙∙┼∙∙∙
   │∙∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
   │∙∙∙∙∙∙∙┼∙∙∙┼∙∙<span class=lt>∙</span>
</pre>
<div class=caption>My algorithm (full symmetry)</div>
</div>
<div class=sshotc>
<pre class=sshot>   │∙∙∙∙∙∙∙∙∙∙∙∙∙∙<span class=lt>∙</span>
   │∙∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
<span class=lt>───┤</span>∙∙<span class=lt>∙∙∙∙∙┼</span>∙∙∙<span class=lt>┼</span>∙∙∙
<span class=lt>@∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───┤</span>∙∙<span class=lt>∙∙∙∙∙┼</span>∙∙∙<span class=lt>┼</span>∙∙∙
   │∙∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>∙∙∙∙
   │∙∙∙∙∙∙∙┼∙∙∙┼∙∙<span class=lt>∙</span>
</pre>
<div class=caption>My algorithm (partial symmetry)</div>
</div>
<div class=sshotc>
<pre class=sshot>   │∙∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙</span>
   │∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>∙
<span class=lt>───┤∙∙∙∙∙∙∙┼∙∙∙┼∙∙∙</span>
<span class=lt>@∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───┤∙∙∙∙∙∙∙┼∙∙∙┼∙∙∙</span>
   │∙∙∙<span class=lt>∙∙∙∙∙∙∙∙∙∙∙</span>∙
   │∙∙∙∙∙∙<span class=lt>∙┼∙∙∙┼∙∙∙</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot>     │∙∙∙∙∙∙∙∙∙∙∙∙∙
     │∙∙∙∙∙∙∙∙∙∙∙∙∙
<span class=lt>──</span>───┤∙∙∙∙∙<span class=lt>∙∙┼</span>∙∙∙┼∙
<span class=lt>@∙∙∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>──</span>───┤∙∙∙∙∙<span class=lt>∙∙┼</span>∙∙∙┼∙
     │∙∙∙∙∙∙∙∙∙∙∙∙∙
     │∙∙∙∙∙∙∙┼∙∙∙┼∙
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>     │∙∙∙∙∙∙∙∙∙∙∙∙∙
     │∙∙∙∙∙∙∙∙∙∙∙∙∙
<span class=lt>───</span>──┤∙∙∙∙<span class=lt>∙∙∙┼</span>∙∙∙┼∙
<span class=lt>@∙∙∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───</span>──┤∙∙∙∙<span class=lt>∙∙∙┼</span>∙∙∙┼∙
     │∙∙∙∙∙∙∙∙∙∙∙∙∙
     │∙∙∙∙∙∙∙┼∙∙∙┼∙
</pre>
<div class=caption>Diamond walls</div>
</div>
<div class=sshotc>
<pre class=sshot>     │∙∙∙∙∙∙∙∙∙∙∙∙∙
     │∙∙∙∙∙∙∙∙∙∙∙∙∙
<span class=lt>───</span>──┤∙∙∙∙<span class=lt>∙∙∙┼</span>∙∙∙┼∙
<span class=lt>@∙∙∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>───</span>──┤∙∙∙∙<span class=lt>∙∙∙┼</span>∙∙∙┼∙
     │∙∙∙∙∙∙∙∙∙∙∙∙∙
     │∙∙∙∙∙∙∙┼∙∙∙┼∙
</pre>
<div class=caption>My algorithm (full symmetry)</div>
</div>
<div class=sshotc>
<pre class=sshot>     │∙∙∙∙∙∙∙∙∙∙∙∙∙
     │∙∙∙∙∙∙∙∙∙∙∙∙∙
<span class=lt>─────┤</span>∙∙∙∙<span class=lt>∙∙∙┼</span>∙∙∙<span class=lt>┼</span>∙
<span class=lt>@∙∙∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>─────┤</span>∙∙∙∙<span class=lt>∙∙∙┼</span>∙∙∙<span class=lt>┼</span>∙
     │∙∙∙∙∙∙∙∙∙∙∙∙∙
     │∙∙∙∙∙∙∙┼∙∙∙┼∙
</pre>
<div class=caption>My algorithm (partial symmetry)</div>
</div>
<div class=sshotc>
<pre class=sshot>     │∙∙∙∙∙∙∙∙∙∙<span class=lt>∙∙∙</span>
     │∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙</span>
<span class=lt>─────┤∙∙∙∙∙∙∙┼∙∙∙┼∙</span>
<span class=lt>@∙∙∙∙■∙∙∙∙∙∙∙∙∙∙∙∙∙</span>
<span class=lt>─────┤∙∙∙∙∙∙∙┼∙∙∙┼∙</span>
     │∙∙∙∙∙<span class=lt>∙∙∙∙∙∙∙∙</span>
     │∙∙∙∙∙∙∙┼∙∙<span class=lt>∙┼∙</span>
</pre>
<div class=caption>Permissive FOV</div>
</div>
<p></p>
<p>
<div class=sshotc>
<pre class=sshot>│   ┌──────────<span class=lt>─</span>┐
│   │∙∙∙∙∙∙∙∙∙∙<span class=lt>∙</span>│
│  ┌┘∙──┬─────┐<span class=lt>∙</span>│
└─┬┤∙∙∙∙│     │<span class=lt>∙</span>│
∙∙└┘∙∙∙∙│     │<span class=lt>∙</span>│
<span class=lt>┐∙</span>∙∙∙∙∙∙└───┐ │<span class=lt>∙</span>│
└──┐∙∙<span class=lt>∙∙∙</span>∙∙∙└─<span class=lt>┘∙│</span>
   │∙∙∙∙┌─<span class=lt>┐∙∙∙∙@│</span>
   │∙∙∙∙│ └───<span class=lt>──┘</span>
</pre>
<div class=caption>Shadow casting</div>
</div>
<div class=sshotc>
<pre class=sshot>│   ┌──────────<span class=lt>─</span>┐
│   │∙∙∙∙∙∙∙∙∙∙<span class=lt>∙</span>│
│  ┌┘∙──┬─────┐<span class=lt>∙</span>│
└─┬┤∙∙∙∙│     │<span class=lt>∙</span>│
∙∙└┘∙∙∙∙│     │<span class=lt>∙</span>│
<span class=lt>┐∙∙∙</span>∙∙∙∙└───┐ <span class=lt>│∙│</span>
└──┐∙<span class=lt>∙∙∙∙∙</span>∙∙└<span class=lt>─┘∙│</span>