<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Master Baboon &#187; Game development</title>
	<atom:link href="http://www.masterbaboon.com/category/game-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.masterbaboon.com</link>
	<description>The sea of the simulation</description>
	<lastBuildDate>Mon, 14 Nov 2011 08:27:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>Planet Wars &#8211; Google AI Challenge</title>
		<link>http://www.masterbaboon.com/2010/09/planet-wars-google-ai-challenge/</link>
		<comments>http://www.masterbaboon.com/2010/09/planet-wars-google-ai-challenge/#comments</comments>
		<pubDate>Tue, 14 Sep 2010 21:09:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Game development]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[Planet Wars]]></category>

		<guid isPermaLink="false">http://www.masterbaboon.com/?p=340</guid>
		<description><![CDATA[The Computer Science of the University of Waterloo is organizing its second Google AI Challenge. The challenge is a competition between computer programs that control the artificial intelligence of the players in a video game. This time, the game is set in space, and features a symmetric configuration of planets, each containing a fleet of [...]]]></description>
			<content:encoded><![CDATA[<p>The Computer Science of the University of Waterloo is organizing its second <a href="http://ai-contest.com/index.php">Google AI Challenge</a>. The challenge is a competition between computer programs that control the artificial intelligence of the players in a video game.</p>
<p>This time, the game is set in space, and features a symmetric configuration of planets, each containing a fleet of defending spaceships. Each turn, new ships are created, with larger planets creating more ships. At the beginning of the game, each player controls one of the planets and a hundred ships; the AIs issue orders to the ships to send them to conquer planets by outnumbering the local defense. The goal of the game is, of course, to eliminate all of the enemy forces.</p>
<p>This video shows an example game between my first AI (green) playing against DualBot (red), one of the bots included in the starter package; the number floating around represent the fleets commanded by the AIs:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/A0ATZoeWV48?fs=1&amp;hl=en_US" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="480" height="385" src="http://www.youtube.com/v/A0ATZoeWV48?fs=1&amp;hl=en_US" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>The competition is open to everybody, and it is possible to write the AI in basically any programming language. If you plan to use Python, I recommend not using the official starter package, which is un-pythonic and not very sophisticate, but rather <a href="http://github.com/ulope/planetwars-python-kit">this un-official client</a>. The alternative client offers in particular the possibility to log debug information to a local file.</p>
<p>Also, it can be quite frustrating to wait for the official server to match you with some other program, which can take up to an hour. There is an <a href="http://www.benzedrine.cx/planetwars/">alternative server</a> that lets you play with another opponent straight away.</p>
<p>The submission period ends November 27, good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.masterbaboon.com/2010/09/planet-wars-google-ai-challenge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tracking down the enemy</title>
		<link>http://www.masterbaboon.com/2010/09/tracking-down-the-enemy/</link>
		<comments>http://www.masterbaboon.com/2010/09/tracking-down-the-enemy/#comments</comments>
		<pubDate>Sat, 11 Sep 2010 03:13:17 +0000</pubDate>
		<dc:creator>pietro</dc:creator>
				<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Game development]]></category>
		<category><![CDATA[PacMan capture-the-flag]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[PacMan]]></category>

		<guid isPermaLink="false">http://www.masterbaboon.com/?p=300</guid>
		<description><![CDATA[As another scientific Python course is approaching, I&#8217;ve been brushing up my PacMan skills. I decided to give a try to a strategy I had been thinking on, which relies upon having a good estimate of the enemy&#8217;s position. I should remind the reader that in the PacMan capture-the-flag game, one team does not know [...]]]></description>
			<content:encoded><![CDATA[<p>As another <a href="https://portal.g-node.org/python-autumnschool/">scientific Python course</a> is approaching, I&#8217;ve been brushing up my<a href="http://www.masterbaboon.com/2009/09/pacman-capture-the-flag-a-fun-game-for-artificial-intelligence-development-and-education/"> PacMan skills</a>. I decided to give a try to a strategy I had been thinking on, which relies upon having a good estimate of the enemy&#8217;s position. I should remind the reader that in the <a href="http://www.masterbaboon.com/2009/09/pacman-capture-the-flag-a-fun-game-for-artificial-intelligence-development-and-education/">PacMan capture-the-flag game</a>, one team does not know the exact position of the other agents unless they are within 5 squares of one&#8217;s own agents. The game does, however, return a rough estimate of the opponent&#8217;s distance. Our agents-tracker will thus have to blindly make its best guess, and keep a probability distribution over possible positions.</p>
<p>To estimate the position of the opponent agents we need to apply some probability theory:</p>
<p>P(x(t)) = sum_{x(t-1)}  P( x(t-1) ) P( x(t) | x(t-1) )</p>
<p>or, in other words, the probability that the agent is at position x(t) at time t is equal to the sum of the probability of it being at x(t-1) at time t-1, times the probability of transitioning from x(t-1) to x(t). The first term is given simply by the previous estimate, while the second term is our model of the behavior of our opponent (*).</p>
<p>For example, a very conservative model could assume that the opponent could take any legal move at random:</p>
<p>P( x(t) | x(t-1) ) = 1/N</p>
<p>if x(t-1)-&gt;x(t) is a legal move, where N is the total number of legal moves from x(t-1), and</p>
<p>P( x(t) | x(t-1) ) = 0</p>
<p>otherwise. This video shows how such a model performs when the opponent behaves exactly as assumed; the red agent, in the bottom left corner, is estimating the position of the blue agent in the opposite corner; the area of the red squares is proportional to the probability P(x(t)):</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="544" height="327" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/393puqZt6OM?fs=1&amp;hl=en_US" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="544" height="327" src="http://www.youtube.com/v/393puqZt6OM?fs=1&amp;hl=en_US" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>The tracker is doing a good job in this case, but fails miserably for a more realistic opponent:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="544" height="327" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/1EyIRp7xe-8?fs=1&amp;hl=en_US" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="544" height="327" src="http://www.youtube.com/v/1EyIRp7xe-8?fs=1&amp;hl=en_US" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>We clearly need to improve the opponent&#8217;s model&#8230; luckily another simple model results in a large improvement: we can safely assume that the opponent tends to explore new parts of the maze in search of food. We can formalize this as</p>
<p>P( x(t) | x(t-1) ) = 1/Z exp(-beta * v(x(t))</p>
<p>if x(t-1)-&gt;x(t) is a legal move, and 0 otherwise. v(x) is the number of times the agent visited x in the past, and beta is a constant that controls the how exploratory the opponent is. When beta=0, the model is equivalent to the previous random model. Z is a normalizing constant such that P( x(t) | x(t-1) ) sums to 1.</p>
<p>Let&#8217;s see how this model does in practice (in the video, beta = 10):<br />
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="544" height="327" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/ni827laFLw8?fs=1&amp;hl=en_US" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="544" height="327" src="http://www.youtube.com/v/ni827laFLw8?fs=1&amp;hl=en_US" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>Much better, isn&#8217;t it? We can do even better by using two other sources of information: first, the game gives us a noisy estimation of the distance of the opponent (actual distance +/- 6); second, we know that if the opponent is not visible, it must be at least 5 squares away. We can take this information into account by setting P(x(t)) to 0 for squares that lie outside the noisy distance range, and for those inside the visibility range.</p>
<p>The last video shows the complete tracker at work. The blue lines show the area in which the agent might be according to the noisy distance, and the green line shows the visibility range:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="544" height="327" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/EsfQ_54MTxk?fs=1&amp;hl=en_US" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="544" height="327" src="http://www.youtube.com/v/EsfQ_54MTxk?fs=1&amp;hl=en_US" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>The biggest area for improvement here is the agent&#8217;s model P(x(t)|x(t-1)). One possibility could be to simulate several common strategies, and to use the transition statistics for the simulated agents to estimate that probability&#8230;</p>
<p>Now, can we use the estimated position to program better AI agents? I&#8217;ll give it a try, and report back soon!</p>
<p><span style="color: #888888;">(*) Strictly speaking, we are doing &#8220;filtering&#8221; here, i.e., we&#8217;re estimating the current position assuming the past inferences are fixed. The alternative is to do &#8220;smoothing&#8221;, where the full joint probability P(x(t), &#8230;, x(1)) is estimated at each step. The information coming from the new observation is propagated back and forth at each to improve the past inferences. For example, knowing that the agent is at a given position at time t might exclude another position at time t-2 because of too large a distance, which in turn could improve the estimate at time t.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.masterbaboon.com/2010/09/tracking-down-the-enemy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spatial database for collision detection</title>
		<link>http://www.masterbaboon.com/2009/02/spatial-database-for-collision-detection/</link>
		<comments>http://www.masterbaboon.com/2009/02/spatial-database-for-collision-detection/#comments</comments>
		<pubDate>Sat, 07 Feb 2009 20:20:04 +0000</pubDate>
		<dc:creator>pietro</dc:creator>
				<category><![CDATA[ActionScript 3]]></category>
		<category><![CDATA[Game development]]></category>
		<category><![CDATA[collision detection]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[games]]></category>

		<guid isPermaLink="false">http://www.masterbaboon.com/?p=37</guid>
		<description><![CDATA[In games and other graphical applications one has to keep track multiple sprites and detect collisions between them. A naif approach would loop over all sprites and check for collision with *every other sprite*. This is, of course, terribly inefficient and can be very slow even for a small number of sprites. One way out [...]]]></description>
			<content:encoded><![CDATA[<p>In games and other graphical applications one has to keep track multiple sprites and detect collisions between them. A naif approach would loop over all sprites and check for collision with *every other sprite*. This is, of course, terribly inefficient and can be very slow even for a small number of sprites.</p>
<p>One way out of this nightmare  is to register the sprites in a <em>spatial database</em> that stores them according to their position, and is able to determine which of them is close to a given point. As a result, one only needs to check for collision between neighboring sprites. There are many implementations of spatial databases, some of which are quite sophisticated. In this post I&#8217;m going to describe an ActionScript 3 implementation of a grid-based spatial database, that can be used for simple flash games.</p>
<h4>Grid: 2D Array with neighborhood</h4>
<p>A <em>Grid </em>is a two-dimensional array with a concept of <em>neighborhood</em>.  In addition to be able to store and retrieve information on the 2D grid, one can request neighboring elements of a given array element.</p>
<p>For example, let&#8217;s create a simple 4&#215;4 grid, and store at each point an increasing number:</p>
<pre>
<div class="codecolorer-container actionscript3 default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="actionscript3 codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #6699cc; font-weight: bold;">var</span> grid<span style="color: #000066; font-weight: bold;">:</span>Grid = <span style="color: #0033ff; font-weight: bold;">new</span> Grid<span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">4</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">4</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<span style="color: #6699cc; font-weight: bold;">var</span> k<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">int</span> = <span style="color: #000000; font-weight:bold;">1</span><span style="color: #000066; font-weight: bold;">;</span><br />
<span style="color: #0033ff; font-weight: bold;">for</span> <span style="color: #000000;">&#40;</span><span style="color: #6699cc; font-weight: bold;">var</span> i<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">int</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span> i <span style="color: #000066; font-weight: bold;">&amp;</span>lt<span style="color: #000066; font-weight: bold;">;</span> <span style="color: #000000; font-weight:bold;">4</span><span style="color: #000066; font-weight: bold;">;</span> i<span style="color: #000066; font-weight: bold;">++</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">for</span> <span style="color: #000000;">&#40;</span><span style="color: #6699cc; font-weight: bold;">var</span> j<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">int</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span> j <span style="color: #000066; font-weight: bold;">&amp;</span>lt<span style="color: #000066; font-weight: bold;">;</span> <span style="color: #000000; font-weight:bold;">4</span><span style="color: #000066; font-weight: bold;">;</span> j<span style="color: #000066; font-weight: bold;">++</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; grid<span style="color: #000066; font-weight: bold;">.</span><span style="color: #0033ff; font-weight: bold;">set</span><span style="color: #000000;">&#40;</span>i<span style="color: #000066; font-weight: bold;">,</span> j<span style="color: #000066; font-weight: bold;">,</span> k<span style="color: #000066; font-weight: bold;">++</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<span style="color: #000000;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>This image shows the resulting grid, with small numbers indicating grid coordinates and large, bold ones the stored values:</p>
<p><img class="aligncenter size-thumbnail wp-image-114" title="grid11" src="http://www.masterbaboon.com/wp-content/uploads/2009/02/grid11-150x150.png" alt="grid11" width="150" height="150" /></p>
<p>We can now query the grid to get neighbors of a given position: For example, the following code</p>
<pre>
<div class="codecolorer-container actionscript3 default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="actionscript3 codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #6699cc; font-weight: bold;">var</span> neighbors<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Array</span> = grid<span style="color: #000066; font-weight: bold;">.</span>getNeighbors<span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">1</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">1</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<span style="color: #004993;">trace</span><span style="color: #000000;">&#40;</span>neighbors<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
neighbors = grid<span style="color: #000066; font-weight: bold;">.</span>getNeighbors<span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">1</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">3</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<span style="color: #004993;">trace</span><span style="color: #000000;">&#40;</span>neighbors<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></div></td></tr></tbody></table></div>
</pre>
<p>displays <em>1, 2, 3, 5, 7, 9, 10, 11</em> and <em>3, 4, 7, 11, 12</em>, respectively, as shown here:</p>
<p><img class="aligncenter size-medium wp-image-115" title="grids2and3" src="http://www.masterbaboon.com/wp-content/uploads/2009/02/grids2and3-300x147.png" alt="grids2and3" width="300" height="147" /></p>
<p>Note that, by default, the neighbors stop at the border. It is possible to work on a &#8220;toroidal&#8221; grid, meaning that the opposite borders of the grid are connected:</p>
<p><img class="aligncenter size-thumbnail wp-image-116" title="grid4" src="http://www.masterbaboon.com/wp-content/uploads/2009/02/grid4-150x150.png" alt="grid4" width="150" height="150" /></p>
<pre>
<div class="codecolorer-container actionscript3 default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="actionscript3 codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">grid<span style="color: #000066; font-weight: bold;">.</span>setToroidal<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">true</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
neighbors = grid<span style="color: #000066; font-weight: bold;">.</span>getNeighbors<span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">1</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">3</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<span style="color: #004993;">trace</span><span style="color: #000000;">&#40;</span>neighbors<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></div></td></tr></tbody></table></div>
</pre>
<p>which prints <em>3,4,1,7,5,11,12,9</em> .</p>
<p>I added two functions that simplify working with neighbors. The first, <em>mapOnNeighbors(x, y, fct)</em>, applies a function <em>fct</em> to all neighbors of <em>(x,y)</em>. Let&#8217;s  see which of the neighbors of (1,3), are even numbers, just for fun:</p>
<pre>
<div class="codecolorer-container actionscript3 default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="actionscript3 codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339966; font-weight: bold;">function</span> isEven<span style="color: #000000;">&#40;</span><span style="color: #004993;">x</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">int</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Boolean</span> <span style="color: #000000;">&#123;</span> <span style="color: #0033ff; font-weight: bold;">return</span> <span style="color: #000000;">&#40;</span><span style="color: #004993;">x</span> <span style="color: #000066; font-weight: bold;">%</span> <span style="color: #000000; font-weight:bold;">2</span> == <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span> <span style="color: #000000;">&#125;</span><br />
<span style="color: #6699cc; font-weight: bold;">var</span> neighborsAreEven<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Array</span> = grid<span style="color: #000066; font-weight: bold;">.</span>mapOnNeighbors<span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">1</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">3</span><span style="color: #000066; font-weight: bold;">,</span> isEven<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<span style="color: #004993;">trace</span><span style="color: #000000;">&#40;</span>neighborsAreEven<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></div></td></tr></tbody></table></div>
</pre>
<p>This gives <em>false,true,false,false,false,false,true,false</em>. There are several interesting uses of this method: collecting information from elements in a region of the grid, activating neighboring elements, &#8230;</p>
<p>The second function,<em> reduceOnNeighbors(x, y, fct)</em>, is a bit more difficult to explain, but equally useful: it returns a single value constructed by iterating over the neighbors of <em>(x,y)</em> and calling <em>fct(a, b)</em> on the first two items of the sequence, then on the result and the next item, and so on. We can use this function to compute the sum of all neighbors:</p>
<pre>
<div class="codecolorer-container actionscript3 default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="actionscript3 codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339966; font-weight: bold;">function</span> sum<span style="color: #000000;">&#40;</span><span style="color: #004993;">x</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> <span style="color: #000000;">&#123;</span> <span style="color: #0033ff; font-weight: bold;">return</span> <span style="color: #004993;">x</span> <span style="color: #000066; font-weight: bold;">+</span> <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">;</span> <span style="color: #000000;">&#125;</span><br />
<span style="color: #6699cc; font-weight: bold;">var</span> sumOfNeighbors<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = grid<span style="color: #000066; font-weight: bold;">.</span>reduceOnNeighbors<span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">1</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">1</span><span style="color: #000066; font-weight: bold;">,</span> sum<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<span style="color: #004993;">trace</span><span style="color: #000000;">&#40;</span>sumOfNeighbors<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></div></td></tr></tbody></table></div>
</pre>
<p>prints <em>48</em> = 1+2+3+5+7+9+10+11 . This function could have been used for example in the <a href="http://www.masterbaboon.com/2009/02/2d-cellular-automata/" target="_self">previous post</a> in the Cellular Automaton code, to compute the number of alive neighbors for every cell of the CA.</p>
<h4>SpatialDatabase</h4>
<p>The <em>SpatialDatabase </em>class registers sprites in a Grid with coarser resolution. For example, a <em>Shape </em>at position <em>(31, 23) </em>on the stage would be stored in element <em>(3,2)</em> if the resolution of the grid is 10 pixels.</p>
<p>That&#8217;s basically all there is to it! For collision detection, we can query the spatial database for sprites registered at neighboring elements in the grid:</p>
<pre>
<div class="codecolorer-container actionscript3 default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="actionscript3 codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900; font-style: italic;">// Check collision with shape:Shape</span><br />
<span style="color: #009900; font-style: italic;">// 1. get neighbors</span><br />
<span style="color: #6699cc; font-weight: bold;">var</span> neighbors<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Array</span> = spatialDatabase<span style="color: #000066; font-weight: bold;">.</span>getAllNeighbors<span style="color: #000000;">&#40;</span>shape<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">x</span><span style="color: #000066; font-weight: bold;">,</span> shape<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">y</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<span style="color: #009900; font-style: italic;">// 2. loop over all neighbors and check collision</span><br />
<span style="color: #0033ff; font-weight: bold;">for</span> <span style="color: #0033ff; font-weight: bold;">each</span> <span style="color: #000000;">&#40;</span><span style="color: #6699cc; font-weight: bold;">var</span> s<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Shape</span> <span style="color: #0033ff; font-weight: bold;">in</span> neighbors<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #009900; font-style: italic;">// check collision</span><br />
&nbsp; &nbsp; <span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span>checkCollision<span style="color: #000000;">&#40;</span>shape<span style="color: #000066; font-weight: bold;">,</span> s<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900; font-style: italic;">// do something (bounce, explode, ...)</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<span style="color: #000000;">&#125;</span></div></td></tr></tbody></table></div>
</pre>
<p>A higher resolution gives an optimal performance. Just keep in mind that the grid size should be larger than the size of the largest sprite, otherwise some collisions may go undetected.</p>
<p>There exist much more sophisticated methods to improve the efficiency of collision detection (see for example <a href="http://www.gskinner.com/blog/archives/2008/01/proximitymanage.html" target="_blank">this post</a> and the excellent <a href="http://www.harveycartel.org/metanet/tutorials.html" target="_blank">tutorial at metanet software</a>). However, this simple grid-based approach can be *very* efficient for many applications!</p>
<p>You can grab the code for the <a href="http://www.masterbaboon.com/flashes/grid_demo.zip">Grid and SpatialData`base classes here</a> (including AsUnit tests for the Grid class). I have a nice example of this class at work, but this post is already long enough, have a look at the next one!</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-5929969675637192";
google_ad_slot = "7572213318";
google_ad_width = 468;
google_ad_height = 15;
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.masterbaboon.com/2009/02/spatial-database-for-collision-detection/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

