<?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>SquaredRoot &#187; patterns</title>
	<atom:link href="http://www.squaredroot.com/tag/patterns/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.squaredroot.com</link>
	<description>.Net Development in DC</description>
	<lastBuildDate>Sun, 16 Aug 2009 01:30:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Spearmen, Javelin Throwers, and the State Pattern. Oh My!</title>
		<link>http://www.squaredroot.com/2009/08/15/spearmen-javelin-throwers-and-the-state-pattern-oh-my/</link>
		<comments>http://www.squaredroot.com/2009/08/15/spearmen-javelin-throwers-and-the-state-pattern-oh-my/#comments</comments>
		<pubDate>Sun, 16 Aug 2009 01:30:15 +0000</pubDate>
		<dc:creator>Troy Goode</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[patterns]]></category>

		<guid isPermaLink="false">http://www.squaredroot.com/?p=556</guid>
		<description><![CDATA[Jamie Farser &#038; Ayende Rahein recently had a conversation about using the State Pattern for units in a game Jamie is building. I've been following along trying to figure my way through the state pattern as well, and decided to take a stab at my own solution to Jamie's problem.]]></description>
			<content:encoded><![CDATA[<p>Last week one of Ayende/Oren&#8217;s posts caught my eye: <a href="http://ayende.com/Blog/archive/2009/08/05/let-the-fighting-commence.aspx">Let the fighting commence!</a> In it he discussed <a href="http://www.thecodespring.com/2009/08/interface-overload.html">a blog post seen on Jamie Farser&#8217;s blog</a>, where Jamie discusses some design difficulties he has run into while designing a turn-based game similar to Axis &amp; Allies named <a href="http://code.google.com/p/everland/"><em>Everland</em></a>. Since then I&#8217;ve been following Jamie&#8217;s progress (<a href="http://www.thecodespring.com/2009/08/state-pattern.html">first try</a>, <a href="http://www.thecodespring.com/2009/08/state-pattern-part-15.html">further exploration</a>, <a href="http://www.thecodespring.com/2009/08/state-pattern-part-2-of.html">second try</a>, <a href="http://www.thecodespring.com/2009/08/state-pattern-part-3.html">third try</a>, <a href="http://www.thecodespring.com/2009/08/state-pattern-transitions.html">even further exploration</a>) as he tries to take some of Ayende&#8217;s advice and implement the state pattern. Like Jamie, I am fairly new to the state pattern &#8211; sure I&#8217;ve read about it plenty (starting in <a href="http://www.amazon.com/First-Design-Patterns-Elisabeth-Freeman/dp/0596007124">Head First Design Patterns</a> &#8211; a must have!), but I honestly have just never implement it &#8220;for reals.&#8221; In my back &amp; forth with Jamie I realized that it was time to put up or shut up &#8211; if I&#8217;m going to offer criticism I should also offer up an alternative solution.</p>
<h2>The Problem</h2>
<p>Let&#8217;s say we have a game where the board is made up of six-side polygons (&#8220;hexes&#8221;, if you will) and each hex can contain a unit like a spearman or a javelin thrower. Each unit on the board belongs to a player who can take turns moving his units, telling his units to attack other player&#8217;s units, etc. Some units have different capabilities than other units &#8211; a spearman must be within 1 hex of another unit to attack that unit, whereas a javelin thrower can be 2 units away. How do we design the application in such a way that:</p>
<ul>
<li>The game engine doesn&#8217;t need to know specifics about each unit (such as range of attack).</li>
<li>A unit&#8217;s capabilities may change during the course of gameplay (such as a spearman being upgraded to a javelin thrower).</li>
</ul>
<h2>My Solution</h2>
<p>Before we look at the code, lets run through what is going to happen in-game.</p>
<ol>
<li>The user selects one of their units, then selects an opposing unit somewhere else on the gameboard, then clicks an &#8220;Attack&#8221; button.</li>
<li>The game engine creates a context (deriving from <strong>ITurnContext</strong>) that describes what the user has asked to do. In our case, an <strong>AttackContext </strong>is created containing references to the attacking unit and the defending unit.</li>
<li>That context is then passed into the <em>ExecuteTurn </em>method of the attacking <strong>Unit</strong>, which then passes it along into the <em>Handle </em>method of its <em>CurrentState </em>property (which is an object deriving from <strong>UnitState</strong>). Our attacker&#8217;s <em>CurrentState </em>property is currently <strong>Spearman</strong>, but could just as easily be <strong>JavelinThrower</strong>. Changing a unit from melee to ranged is as simple as changing the state of that unit.</li>
<li>Our <strong>Spearman </strong>state derives from <strong>UnitState</strong>, and the <strong>UnitState </strong>base class&#8217; <em>Handle </em>method uses <a href="http://en.wikipedia.org/wiki/Double_dispatch">double dispatch</a> to forward the <em>Handle </em>request on to the appropriate method of our subclass. In our case that would be the <em>Handle</em>(<em>AttackContext</em>) method of the <em>Spearman </em>class.</li>
<li>Our <strong>Spearman </strong>class&#8217; <em>Handle </em>method then checks to see if the unit is within range to attack the defending unit &#8211; if it is, an <strong>AttackCommand </strong>is returned denoting who the attacker and the defender are; if it isn&#8217;t, a <strong>MovementCommand </strong>is returned denoting which hex to move to.</li>
<li>The <strong>Unit </strong>class then calls <em>Execute </em>on the returned command, causing the movement or attack operation to be, well, executed.</li>
</ol>
<p>Let&#8217;s go through each of the above steps and take a look at the code involved one by one. Skipping the first step (the UI), we&#8217;ll move on to where the game engine is creating an <strong>AttackContext </strong>and passing it into the attacking <strong>Unit</strong>:</p>
<pre class="brush: csharp; toolbar: false;">Attacker.ExecuteTurn(new AttackContext {Attacker = Attacker, Defender = Defender});</pre>
<p>Okay, easy enough. Moving on we can see the <strong>Unit </strong>class&#8217; <em>ExecuteTurn </em>method pass the context to its <em>CurrentState </em>property&#8217;s <em>Handle </em>method:</p>
<pre class="brush: csharp;">public class Unit
{
	public Hex Location { get; set; }
	public int Health { get; set; }
	public UnitState CurrentState { get; set; }

	public void ExecuteTurn(ITurnContext context)
	{
		CurrentState.Handle(context).Execute();
	}
}</pre>
<p>Our attacking unit&#8217;s <em>CurrentState </em>property is currently set to an instance of <strong>Spearman</strong>, but before we take a look at that class we&#8217;ll take a look at its base class (<strong>UnitState </strong>- which is doing double dispatch to the <strong>Spearman</strong>&#8216;s <em>Handle </em>method):</p>
<pre class="brush: csharp;">public abstract class UnitState
{
	private static readonly Dictionary Dispatch = new Dictionary();

	static UnitState()
	{
		foreach (var t in Assembly.GetCallingAssembly().GetTypes().Where(t =&gt; t.IsSubclassOf(typeof (UnitState))))
			foreach (var mi in t.GetMethods().Where(mi =&gt; mi.Name == "Handle" &amp;&amp; mi.GetParameters().Length &gt; 0))
				Dispatch.Add(((Int64) t.GetHashCode() &lt;&lt; 32) + mi.GetParameters()[0].ParameterType.GetHashCode(), mi);
	}

	public IUnitCommand Handle(ITurnContext context)
	{
		var hash = ((Int64) GetType().GetHashCode() &lt;&lt; 32) + context.GetType().GetHashCode();
		return Dispatch.ContainsKey(hash)
		       	? Dispatch[hash].Invoke(this, new[] {context}) as IUnitCommand
		       	: new NullCommand();
	}
}</pre>
<p>The Spearman class&#8217; Handle method is then invoked:</p>
<pre class="brush: csharp;">public class Spearman : UnitState
{
	public IUnitCommand Handle(AttackContext context)
	{
		if (context.Attacker.Location.DistanceTo(context.Defender.Location) == 1)
			return new AttackCommand(context);
		return new MovementCommand(new MovementContext
		                           	{
		                           		UnitToMove = context.Attacker,
		                           		HexToMoveTo =
		                           			context.Attacker.Location .FindClosestSurroundingHexTo( context.Defender.Location)
		                           	});
	}
}</pre>
<p>Notice that the only concern <strong>Spearman </strong>currently has when handling an attack context is ensuring that it gets within range and then attacks the target. We&#8217;ll see an example of a<strong> JavelinThrower </strong>later. Finally we&#8217;ll peek at what the <strong>MovementCommand </strong>and <strong>AttackCommand </strong>actually do:</p>
<pre class="brush: csharp;">public class MovementCommand : IUnitCommand
{
	private readonly MovementContext _movementContext;

	public MovementCommand(MovementContext movementContext)
	{
		_movementContext = movementContext;
	}

	#region IUnitCommand Members

	public void Execute()
	{
		_movementContext.UnitToMove.Location = _movementContext.HexToMoveTo;
	}

	#endregion
}

public class AttackCommand : IUnitCommand
{
	private readonly AttackContext _attackContext;

	public AttackCommand(AttackContext attackContext)
	{
		_attackContext = attackContext;
	}

	#region IUnitCommand Members

	public void Execute()
	{
		_attackContext.Defender.Health -= 10;
	}

	#endregion
}</pre>
<p>Before we move on, here is the promised <strong>JavelinThrower </strong>class:</p>
<pre class="brush:csharp;">public IUnitCommand Handle(AttackContext context)
{
	if (context.Attacker.Location.DistanceTo(context.Defender.Location) &lt;= 2)
		return new AttackCommand(context);
	return new MovementCommand(new MovementContext
	                           	{
	                           		UnitToMove = context.Attacker,
	                           		HexToMoveTo =
	                           			context.Attacker.Location .FindClosestSurroundingHexTo( context.Defender.Location)
	                           	});
}</pre>
<p>Obviously <strong>JavelinThrower </strong>&amp; <strong>Spearman </strong>currently only differ in the range at which they can attack (&lt;=2 and &lt;= 1, respectively), so the code in their <em>Handle </em>methods could be abstracted out using the <a href="http://en.wikipedia.org/wiki/Strategy_pattern">Strategy Pattern</a>.</p>
<h2>Prove It!</h2>
<p>So now that we&#8217;ve had a chance to see the code involved the question comes down to: does it actually work? Here are our unit tests:</p>
<pre class="brush: csharp;">[Fact]
public void JavelinThrower_moves_to_two_hexes_away_and_attacks()
{
	//starting point
	Assert.Equal(4, Attacker.Location.DistanceTo(Defender.Location));
	Assert.Equal(100, Defender.Health);

	//turn one - moves closer
	Attacker.ExecuteTurn(new AttackContext { Attacker = Attacker, Defender = Defender });
	Assert.Equal(3, Attacker.Location.DistanceTo(Defender.Location));
	Assert.Equal(100, Defender.Health);

	//turn two - moves closer
	Attacker.ExecuteTurn(new AttackContext { Attacker = Attacker, Defender = Defender });
	Assert.Equal(2, Attacker.Location.DistanceTo(Defender.Location));
	Assert.Equal(100, Defender.Health);

	//turn three - attacks
	Attacker.ExecuteTurn(new AttackContext { Attacker = Attacker, Defender = Defender });
	Assert.Equal(2, Attacker.Location.DistanceTo(Defender.Location));
	Assert.Equal(90, Defender.Health);
}

[Fact]
public void Spearman_moves_to_one_hex_away_and_attacks()
{
	//starting point
	Assert.Equal(4, Attacker.Location.DistanceTo(Defender.Location));
	Assert.Equal(100, Defender.Health);

	//turn one - moves closer
	Attacker.ExecuteTurn(new AttackContext {Attacker = Attacker, Defender = Defender});
	Assert.Equal(3, Attacker.Location.DistanceTo(Defender.Location));
	Assert.Equal(100, Defender.Health);

	//turn two - moves closer
	Attacker.ExecuteTurn(new AttackContext {Attacker = Attacker, Defender = Defender});
	Assert.Equal(2, Attacker.Location.DistanceTo(Defender.Location));
	Assert.Equal(100, Defender.Health);

	//turn three - moves closer
	Attacker.ExecuteTurn(new AttackContext {Attacker = Attacker, Defender = Defender});
	Assert.Equal(1, Attacker.Location.DistanceTo(Defender.Location));
	Assert.Equal(100, Defender.Health);

	//turn four - attacks
	Attacker.ExecuteTurn(new AttackContext {Attacker = Attacker, Defender = Defender});
	Assert.Equal(1, Attacker.Location.DistanceTo(Defender.Location));
	Assert.Equal(90, Defender.Health);
}</pre>
<p>And the results&#8230;</p>
<p><a href="http://www.squaredroot.com/wp-content/uploads/2009/08/Spearman-JavelinThrower-Tests-Passed.PNG" rel="wp-prettyPhoto[g556]"><img class="alignnone size-full wp-image-568" title="Spearman &amp; Javelin Thrower Tests Passed!" src="http://www.squaredroot.com/wp-content/uploads/2009/08/Spearman-JavelinThrower-Tests-Passed.PNG" alt="Spearman &amp; Javelin Thrower Tests Passed!" width="426" height="129" /></a></p>
<p>Yay!</p>
<p>So that is the road I went down, but what I really want to know is how would <em>you </em>solve this problem? If you&#8217;d like to take a deeper look at my code, download it and give it a try yourself:</p>
<p><a href="http://www.squaredroot.com/wp-content/uploads/2009/08/EverlandStatePattern.zip">EverlandStatePattern.zip</a> </p>
<div style="text-align: center;"><a href="http://www.dotnetkicks.com/kick/?url=http://www.squaredroot.com/2009/08/15/spearmen-javelin-throwers-and-the-state-pattern-oh-my/" style="border:0; position: relative; top: -2px;"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.squaredroot.com/2009/08/15/spearmen-javelin-throwers-and-the-state-pattern-oh-my/" style="border:0;" alt="Kick It on DotNetKicks.com" /></a><a href="http://dotnetshoutout.com/Submit?url=http://www.squaredroot.com/2009/08/15/spearmen-javelin-throwers-and-the-state-pattern-oh-my/" style="border: 0;"><img src="http://dotnetshoutout.com/image.axd?url=http://www.squaredroot.com/2009/08/15/spearmen-javelin-throwers-and-the-state-pattern-oh-my/" style="border:0px" alt="Shout It on DotNetShoutOuts.com" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://www.squaredroot.com/2009/08/15/spearmen-javelin-throwers-and-the-state-pattern-oh-my/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
