the structure of my robocode implementation

There has been a lot of code on this blog for my robocode series and I thought I would illustrate the current structure of the codebase to provide some clarity to those following my growing implementation.

Here's the structure of my code so far:

model

The "Adapter" namespace is where my robot resides and this is the only area that knows about the robocode library and its types. This keeps a clean separation between my own model and the robocode library and acts as an anti corruption layer.

The "Battles" namespace is where all my battle code lives for parsing battle results and running acceptance tests - I covered the creation of these in earlier blog posts.

The "Decision" namespace is my new bounded context for decision making. I have a DecisionContextTranslator that knows how to convert the world state into decision state and from there the code is pretty much isolated (although at present it uses the statistics manager directly and I plan to change this in the future if statistics writing requirements grow).

The "Manipulation" namespace is where my robot engine lives and the robot interface that the adapter robot implements so I can speak to it in my model's terms.  I plan on having a context translator here that will know how to issue instructions to the ImARobot interface, through the robot engine.

The "Service" namespace is where I keep my service locator that abstracts from the underlying IOC container. I need this because the robot is created by robocode itself and I need a hook into service resolution to get the robot engine and the resulting dependency tree.

The "Statistics" namespace contains the classes for writing statistics out to assist with acceptance testing requirements.

Finally, the "World" namespace separates out the world state as this transcends into the context translators in each bounded context and resides as an instance in the robot engine. Pulling it out seemed a logical thing to do.

From my original design when thinking about bounded contexts I expect to have a new calculation context introduced soon that will deal with calculations based on the decisions made by the decision context.

There we have it, the "Slayer" robocode implementation so far.
So much code to do so very little! (as my robot doesn't even move, scan or fire yet)
Regardless of battle achievements it has been a really valuable exercise in context specification, test driving something new, acceptance test first development, using domain driven design concepts and experimenting with the new RX framework.

I just hope I can now build on this foundation and get the robot to do some interesting things!

Posted at at 6:42 AM on Monday, September 27, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under:

acceptance, more debugging and head scratching

In my last few posts in my robocode series I've developed a bounded context for decision making and it is ready to try out. I have some acceptance tests written that ensure I meet some conditions and the definitive one to check things are working is the test that ensures I reach turn 50, thus asserting that the robot is not disabled at the start of the battle.

When I run the acceptance test it fails which indicates there is something wrong and the robot is being disabled. The error from the acceptance test is actually that the statistics file is old (and not because it doesn't reach turn 50).
This means that the robot's Run() method hasn't been called correctly and the robot engine is not initialised.

Sure enough, when I manually run the robocode GUI and watch my robot it is immediately disabled at the start of the battle.
So what could be going wrong?
After much head scratching and rechecking the code and the specifications I can't see anything wrong - the execution paths look like they should be doing what I've specified so I need to do some debugging.

I insert some debugging statements into the code of the Slayer Robot as the first line of the following two methods:

        public void Run(bool shouldContinueToLoop)
        {
            DebugProperty["run is called"] = "true";

            robotEngine = ServiceLocator.ProvideRobotEngine();
            robotEngine.Initialise(this);

            Scan();

            bool shouldLoop = true;

            while(shouldLoop)
            {
                robotEngine.EnsureTheWorldStateIsUpToDate();

                shouldLoop = shouldContinueToLoop;
            }
        }

        public override void OnStatus(StatusEvent e)
        {
            DebugProperty["on status called"] = "true";

            robotEngine.PublishToTheWorldState(w =>
               {
                   w.CurrentTurnNumber = e.Status.Time;
                   w.GunTemperature = e.Status.GunHeat;
               });
        }

Now when I observe a battle through the GUI and bring up the turn snapshot from the battle log I observe that on the very first turn, turn 0, the following debug properties are available:

debugStatus

It appears that the status method is being called, but the run is not and would suggest that there is a sequencing issue with my code.

I write a specification for this potential bug:

    public class when_robocode_updates_the_turn_status_on_a_robot_and_run_has_not_occurred
    {
        Establish context = () =>
                                    {
                                        robotStatus = RobocodeSpy.CreateARobotStatus(0, 0);
                                        statusEvent = new StatusEvent(robotStatus);

                                        robot = new SlayerRobot();
                                    };

        Because of = () => caughtException = Catch.Exception(() => robot.OnStatus(statusEvent));

        It should_not_fail_because_the_robot_engine_is_not_available = 
                                               () => caughtException.ShouldBeNull();

        static SlayerRobot robot;
        static RobotStatus robotStatus;
        static StatusEvent statusEvent;
        static Exception caughtException;
    }

When I run this specification it fails because a null reference exception is returned due to the missing robot engine instance.
I can fix this quickly with the following code:

        public override void OnStatus(StatusEvent e)
        {
            if (robotEngine == null)
                return;

            robotEngine.PublishToTheWorldState(w =>
               {
                   w.CurrentTurnNumber = e.Status.Time;
                   w.GunTemperature = e.Status.GunHeat;
               });
        }

Although this fixes this particular issue, if I want to keep this same code structure I've been developing then I have to accept that I will never get a status update on turn 0, the first turn, right at the start of the battle - I decide that this is acceptable, at least at this very early stage of development.

When I run the acceptance test once again, it now passes:

passingAcceptance

The important takeaway from this lesson in head scratching is what I can learn from this error. I had a huge assumption that robocode would call my Run() method before the status would update for turn zero. On reflection it makes sense that before commands are accepted from a robot, the status at the beginning of the battle is published, so I'm not really sure where that came from.
I also think that if this was a professional codebase at a client and this was, for example, and email class deriving from a template patterned base class, I would have coded for every eventuality of calls being made out of sequence.
So lesson learned - no assumptions in my personal projects and cover every possibility with specifications, just like I normally would at work.

Posted at at 7:15 AM on Thursday, September 23, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: ,

integrating translators to the robocode engine

In my latest robocode series I've been exploring a decision making bounded context and have fused together many elements to make this happen. Here's what I've done so far:

  • written acceptance testing and statistics writing for assertions
  • introduced IObservable<IEvent<T>> into my robocode design
  • recognised that I have multiple contexts that I hope can have their own dialect
  • introduced a world state
  • created a decision making bounded context with a state keeper and updater
  • created observer(s) to watch this decision state
  • created a context translator to push world state updates into the decision dialect

It has been quite a lot of code in a few posts (but that's what my blog is mostly about - the finer details of development and shaping code).

I'm now ready to hook the whole thing up and I need my robot engine to activate the context translators when a world state update occurs.
As usual I start with specifications for this class and I'm going to add two new ones into an existing specification:

    public class when_told_to_ensure_the_world_state_is_up_to_date : with_a_robot_engine
    {
        Establish context = () =>
        {
            robotEngine.Initialise(robot);
            expectedGunTemperature = 222;
            worldStateUpdate = w => w.GunTemperature = expectedGunTemperature;
            robotEngine.PublishToTheWorldState(worldStateUpdate);
        };

        Because of = () => robotEngine.EnsureTheWorldStateIsUpToDate();

        It should_update_the_world_state_accordingly = () =>
            worldState.GunTemperature.ShouldEqual(expectedGunTemperature);

        It should_have_no_pending_world_state_updates_left = () =>
            robotEngine.PendingWorldStateUpdates.Count.ShouldEqual(0);

-->     It should_inform_the_first_translator_of_the_world_state_change = () =>
            firstContextTranslator.AssertWasCalled(x => x.PublishAStateChange(worldState));

-->     It should_inform_the_second_translator_of_the_world_state_change = () =>
            secondContextTranslator.AssertWasCalled(x => x.PublishAStateChange(worldState));

        static Action<IWorldState> worldStateUpdate;
        static int expectedGunTemperature;
    }

I've now introduced two new context translators into the specification and when the world state is to be updated I want them informed of this world state change.
The change in the constructor of the robocode engine in my specification is as follows:

        firstContextTranslator = MockRepository.GenerateStub<IContextTranslator>();
        secondContextTranslator = MockRepository.GenerateStub<IContextTranslator>();
        var contextTranslators = new List<IContextTranslator> {firstContextTranslator, 
                                                        secondContextTranslator};
        robotEngine = new RobotEngine(worldState, contextTranslators, statisticsManager);

To implement this there is a new loop in this method in the robot engine:

        public void EnsureTheWorldStateIsUpToDate()
        {
            foreach(var makeAnUpdateTo in pendingWorldStateUpdates)
            {
                makeAnUpdateTo(worldState);
            }
            pendingWorldStateUpdates.RemoveAll(a => true);

            foreach (var contextTranslator in contextTranslators)
            {
                contextTranslator.PublishAStateChange(worldState);
            }
        }

I'm happy with the code so far, but this method above doesn't necessarily scan right and I think this needs addressing.

I'm a huge fan of the Clean Code book by Bob Martin and I'm a proud wearer of the green wristband, (seeking "craftsmanship over crap"!) and at every opportunity I look to make my code intuitive and readable. So with a few simple method extractions I think the above can be made simpler so that when I read it back at a later date, the code is intention revealing.
As you can see I believe this applies as much to experimentation and personal projects as it does to professional code bases in every day work

Here's the end result:

        public void EnsureTheWorldStateIsUpToDate()
        {
            ConsumePendingUpdatesByUpdatingTheWorldState();

            PublishTheWorldStateToTheContextTranslators();
        }

        void ConsumePendingUpdatesByUpdatingTheWorldState()
        {
            foreach(var makeAnUpdateTo in pendingWorldStateUpdates)
            {
                makeAnUpdateTo(worldState);
            }
            pendingWorldStateUpdates.RemoveAll(a => true);
        }

        void PublishTheWorldStateToTheContextTranslators()
        {
            foreach (var contextTranslator in contextTranslators)
            {
                contextTranslator.PublishAStateChange(worldState);
            }
        }

So I'm now ready to run my acceptance tests which will run some battles and ensure that my implementation does what I think it should. The next post will cover this acceptance and debugging exercise.

Posted at at 7:40 AM on Tuesday, September 21, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: , ,

the decision context translator for robocode

I have been implementing a bounded context for decision making for my robocode robot and continue in this post with the decision context translator - this will be responsible for converting data from the world state to the decision state dialect.

My specification starts with a new translator type and a new interface to interact with, the decision state updater:

    [Subject(typeof(DecisionContextTranslator))]
    public class when_publishing_a_state_change
    {
        Establish context = () =>
        {
            decisionStateUpdater = MockRepository.GenerateStub<IUpdateDecisionState>();
            decisionContextTranslator = new DecisionContextTranslator(decisionStateUpdater);

            worldState = MockRepository.GenerateStub<IWorldState>();
        };

        Because of = () => decisionContextTranslator.PublishAStateChange(worldState);

        It should_update_state_via_the_decision_state_updater = () =>
            decisionStateUpdater.AssertWasCalled(d => 
                                    d.UpdateState(Arg<Action<DecisionState>>.Is.NotNull));

        static IContextTranslator decisionContextTranslator;
        static IWorldState worldState;
        static IUpdateDecisionState decisionStateUpdater;
    }

I'm ensuring that the translator will provide an Action delegate to modify a decision state and the implementation of this class is very easy so far:

    public class DecisionContextTranslator : IContextTranslator
    {
        IUpdateDecisionState decisionStateUpdater;

        public DecisionContextTranslator(IUpdateDecisionState decisionStateUpdater)
        {
            this.decisionStateUpdater = decisionStateUpdater;
        }

        public void PublishAStateChange(IWorldState worldState)
        {
            decisionStateUpdater.UpdateState(d => { } );
        }
    }

I now need to flesh out the delegate with the requirements from the decision context - at present this is a mapping between turn numbers. In the future the dialects will hopefully be different enough to warrant this separate context.

The specification is changed significantly to introduce this:

    [Subject(typeof(DecisionContextTranslator))]
    public class when_publishing_a_state_change
    {
        Establish context = () =>
        {
            decisionStateUpdater = MockRepository.GenerateStub<IUpdateDecisionState>();
            decisionStateUpdater.Stub(d => d.UpdateState(null))
                                .IgnoreArguments()
                                .Do(RecordTheDecisionStateUpdate);

            decisionContextTranslator = new DecisionContextTranslator(decisionStateUpdater);

            turnNumber = 98235;
            worldState = MockRepository.GenerateStub<IWorldState>();
            worldState.CurrentTurnNumber = turnNumber;
        };

        Because of = () => decisionContextTranslator.PublishAStateChange(worldState);

        It should_update_state_via_the_decision_state_updater = () =>
            decisionStateUpdater.AssertWasCalled(d => 
                                      d.UpdateState(Arg<Action<DecisionState>>.Is.NotNull));

        It should_map_the_turn_number_from_world_state_to_decision_state = () =>
            TheDecisionStateHavingHadTheUpdateApplied().TheNumberOfTurnsSoFar
                                          .ShouldEqual(Convert.ToInt32(turnNumber));

        static DecisionState TheDecisionStateHavingHadTheUpdateApplied()
        {
            var decisionState = new DecisionState();
            if(decisionStateUpdate!=null)
                decisionStateUpdate(decisionState);

            return decisionState;
        }

        static Action<Action<DecisionState>> RecordTheDecisionStateUpdate = 
                                                      a => decisionStateUpdate = a;

        static IContextTranslator decisionContextTranslator;
        static long turnNumber;
        static IWorldState worldState;
        static IUpdateDecisionState decisionStateUpdater;
        static Action<DecisionState> decisionStateUpdate;
    }

First, the decision updater stub is set up to record the action that goes into the update call and I have a static Action member at the bottom that will record this in a member variable "decisionStateUpdate".
I also define a turn number on the world state that I can then observe against in my specification.

In my observation I apply any changes to a newly created decision state and I can then check if the turn number was updated.

Here is the implementation of this:

    public class DecisionContextTranslator : IContextTranslator
    {
        IUpdateDecisionState decisionStateUpdater;

        public DecisionContextTranslator(IUpdateDecisionState decisionStateUpdater)
        {
            this.decisionStateUpdater = decisionStateUpdater;
        }

        public void PublishAStateChange(IWorldState worldState)
        {
            decisionStateUpdater.UpdateState(d => d.TheNumberOfTurnsSoFar = 
                                                     (int)worldState.CurrentTurnNumber );
        }
    }

This is all the context translator has to do for the time being and I now need to move onto the decision state updater. I've chosen to implement this interface with the decision state keeper, so I need a new specification for that class:

    [Subject(typeof(DecisionStateKeeper))]
    public class when_provided_with_a_state_update
    {
        Establish context = () =>
        {
            decisionMakingObserver = MockRepository.GenerateStub<IObserveToMakeDecisions>();
            decisionObservers = new List<IObserveToMakeDecisions> { decisionMakingObserver };
            decisionStateKeeper = new DecisionStateKeeper(decisionObservers);

            decisionStateKeeper.Situation.Subscribe(s =>
                {
                    observedDecisionState = s.EventArgs;
                });

            theExpectedNumberOfTurns = 5918;
            decisionStateUpdate = d => d.TheNumberOfTurnsSoFar = theExpectedNumberOfTurns;
        };

        Because of = () => decisionStateKeeper.UpdateState(decisionStateUpdate);

        It should_update_the_situation_observable = () => 
observedDecisionState.ShouldNotBeNull(); It should_have_the_correct_decision_state_after_the_update = () => observedDecisionState.TheNumberOfTurnsSoFar.ShouldEqual(theExpectedNumberOfTurns); static DecisionStateKeeper decisionStateKeeper; static IEnumerable<IObserveToMakeDecisions> decisionObservers; static Action<DecisionState> decisionStateUpdate; static DecisionState observedDecisionState; static int theExpectedNumberOfTurns; static IObserveToMakeDecisions decisionMakingObserver; }

In this specification I'm creating a new decision state keeper and am subscribing to the situation observable so I can obtain the decision state when the observable is activated.
I can then assert that this decision state is available and that the number of turns so far is equal that provided in the proposed state update.

This changes the decision state keeper to the following:

    public class DecisionStateKeeper : IKeepDecisionState, IUpdateDecisionState
    {
        DecisionState internalDecisionState;

        public DecisionStateKeeper(IEnumerable<IObserveToMakeDecisions> decisionMakingObservers)
        {
            CreateObservableForDecisionState();

            foreach(var observer in decisionMakingObservers)
            {
                observer.Observe(this);
            }
        }

        public IObservable<IEvent<DecisionState>> Situation { get; private set; }

        event EventHandler<DecisionState> DecisionStateHasUpdated;

        void CreateObservableForDecisionState()
        {
            Situation = Observable.FromEvent<DecisionState>(
                ev => this.DecisionStateHasUpdated += ev,
                ev => this.DecisionStateHasUpdated -= ev);
        }

        public void UpdateState(Action<DecisionState> decisionStateUpdate)
        {
            decisionStateUpdate(InternalDecisionState);
            DecisionStateHasUpdated(this, InternalDecisionState);
        }

        protected DecisionState InternalDecisionState
        {
            get 
            {
                return internalDecisionState ?? (internalDecisionState = new DecisionState());
            }
        }
    }

I'm now almost ready and my next post will cover the final piece to introduce this new context and I'll be ready to run my acceptance tests once again.

Posted at at 7:52 AM on Thursday, September 16, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: , ,

updating the robocode contexts when the world state updates

In my previous posts I have moved to a position where my robot and robot engine are capable of updating the world state. Now I want to start mapping this state to other bounded contexts and I've already created the first parts of my decision making context . If I now provide the robot engine with a collection of translators, I want it to publish the world state to each context via these translators:

    public class when_told_to_publish_to_the_world_state : with_a_robot_engine
    {
        Establish context = () =>
        {
            worldState = MockRepository.GenerateStub<IWorldState>();

            firstContextTranslator = MockRepository.GenerateStub<IContextTranslator>();
            secondContextTranslator = MockRepository.GenerateStub<IContextTranslator>();
            var contextTranslators = new List<IContextTranslator> {firstContextTranslator, 
                                secondContextTranslator};

            robotEngine = new RobotEngine(worldState, contextTranslators);

            robotEngine.Initialise(robot);
            expectedGunTemperature = 891;
            worldStateUpdate = w => w.GunTemperature = expectedGunTemperature;
        };

        Because of = () => robotEngine.PublishToTheWorldState(worldStateUpdate);

        It should_update_the_world_state_accordingly = () =>
            worldState.GunTemperature.ShouldEqual(expectedGunTemperature);

        It should_have_no_pending_world_state_updates_left = () => 
            robotEngine.PendingWorldStateUpdates.Count.ShouldEqual(0);

        It should_inform_the_first_translator_of_the_world_state_change = () =>
            firstContextTranslator.AssertWasCalled(x => x.PublishAStateChange(worldState));

        It should_inform_the_second_translator_of_the_world_state_change = () =>
            secondContextTranslator.AssertWasCalled(x => x.PublishAStateChange(worldState));

        static Action<IWorldState> worldStateUpdate;
        static int expectedGunTemperature;
    }

Pretty simple stuff - a few stubs in a collection are injected into the robot engine constructor and I assert that the state change is published on each one.
The robot engine code in full with this change:

    public class RobotEngine : ImARobotEngine
    {
        readonly IManageStatistics statisticsManager;
        readonly IWorldState worldState;
        readonly IEnumerable<IContextTranslator> contextTranslators;
        ImARobot robot;

        List<Action<IWorldState>> pendingWorldStateUpdates = new List<Action<IWorldState>>();

        public RobotEngine(IWorldState worldState, 
                           IEnumerable<IContextTranslator> contextTranslators,
                           IManageStatistics statisticsManager)
        {
            this.statisticsManager = statisticsManager;
            this.worldState = worldState;
            this.contextTranslators = contextTranslators;
        }

        public ReadOnlyCollection<Action<IWorldState>> PendingWorldStateUpdates
        {
            get { return pendingWorldStateUpdates.AsReadOnly(); }
        }

        public void Initialise(ImARobot robot)
        {
            this.robot = robot;
            statisticsManager.EnsureWeStartWithCleanStatistics();
        }

        public void PublishToTheWorldState(Action<IWorldState> worldStateUpdate)
        {
            pendingWorldStateUpdates.Add(worldStateUpdate);
        }

        public void EnsureTheWorldStateIsUpToDate()
        {
            foreach(var makeAnUpdateTo in pendingWorldStateUpdates)
            {
                makeAnUpdateTo(worldState);
            }
            pendingWorldStateUpdates.RemoveAll(a => true);

            foreach (var contextTranslator in contextTranslators)
            {
                contextTranslator.PublishAStateChange(worldState);
            }
        }
    }

I'm pretty happy with this code so far - I don't yet have a mechanism for the context to push back some state changes or instructions prior to the next translator being told to publish a state change, but I'm sure that will take shape in time as I drive that with new specifications as the need arises.

The next step is to implement the context translator for the decision making context and my next post will cover this in detail.

Posted at at 7:19 AM on Monday, September 13, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: , ,

the robocode decision context

In my robocode series I've been exploring separation of concerns and domain driven design I'm ready to write the first of my bounded contexts that I described in an earlier post. This context will be responsible for making decisions about enemies on the battlefield and as such the dialect will hopefully reflect this.

I'm going to start with the decision state keeper in the decision namespace and context:

    [Subject(typeof(DecisionStateKeeper))]
    public class when_the_decision_state_keeper_is_created
    {
        Because of = () => decisionStateKeeper = new DecisionStateKeeper();

        It should_ensure_that_we_have_something_to_observe_for_decision_making = () =>
            decisionStateKeeper.Situation.ShouldNotBeNull();

        static IKeepDecisionState decisionStateKeeper;
    }

I want to ensure that an observable is ready for use once the class is constructed:

    public class DecisionStateKeeper : IKeepDecisionState
    {
        public DecisionStateKeeper()
        {
            CreateObservableForDecisionState();
        }

        public IObservable<IEvent<DecisionState>> Situation { get; private set; }

        event EventHandler<DecisionState> DecisionStateHasUpdated;

        void CreateObservableForDecisionState()
        {
            Situation = Observable.FromEvent<DecisionState>(
                                             ev => this.DecisionStateHasUpdated += ev,
                                             ev => this.DecisionStateHasUpdated -= ev);
        }
    }

Next, I want any observers to subscribe to the observable when it has been created:

    [Subject(typeof(DecisionStateKeeper))]
    public class when_the_decision_state_keeper_is_created
    {
        Establish context = () =>
        {
          firstDecisionMakingObserver = MockRepository.GenerateStub<IObserveToMakeDecisions>();
          secondDecisionMakingObserver = MockRepository.GenerateStub<IObserveToMakeDecisions>();
          decisionObservers = new List<IObserveToMakeDecisions>
                                    {firstDecisionMakingObserver, secondDecisionMakingObserver};
        };

        Because of = () => decisionStateKeeper = new DecisionStateKeeper(decisionObservers);

        It should_ensure_that_we_have_something_to_observe_for_decision_making = () =>
            decisionStateKeeper.Situation.ShouldNotBeNull();

        It should_tell_the_first_observer_to_make_its_observations = () =>
            firstDecisionMakingObserver.AssertWasCalled(o => o.Observe(decisionStateKeeper));

        It should_tell_the_second_observer_to_make_its_observations = () =>
            secondDecisionMakingObserver.AssertWasCalled(o => o.Observe(decisionStateKeeper));

        static IKeepDecisionState decisionStateKeeper;
        static IEnumerable<IObserveToMakeDecisions> decisionObservers;
        static IObserveToMakeDecisions firstDecisionMakingObserver;
        static IObserveToMakeDecisions secondDecisionMakingObserver;
    }

The implementation is:

    public class DecisionStateKeeper : IKeepDecisionState
    {
        public DecisionStateKeeper(IEnumerable<IObserveToMakeDecisions> decisionMakingObservers)
        {
            CreateObservableForDecisionState();

            foreach(var observer in decisionMakingObservers)
            {
                observer.Observe(this);
            }
        }

        public IObservable<IEvent<DecisionState>> Situation { get; private set; }

        event EventHandler<DecisionState> DecisionStateHasUpdated;

        void CreateObservableForDecisionState()
        {
            Situation = Observable.FromEvent<DecisionState>(
                                             ev => this.DecisionStateHasUpdated += ev,
                                             ev => this.DecisionStateHasUpdated -= ev);
        }
    }

I'm now ready to implement my original observer I had that wrote statistics out when turn 50 was reached. So I rework that original set of specifications (the originals can be seen in iobservable<t> with robocode):

    [Subject(typeof(BattleReachedAReasonableTurnObserver))]
    public class when_at_the_start_of_turn_fifty : with_an_observer
    {
        Establish context = () => WithADecisionStateAtTurnNumber(50);

        It should_subscribe_to_the_observable_and_recognise_turn_fifty = () =>
            observer.ReachedTurnFifty.ShouldBeTrue();

        It should_ask_the_statistics_manager_to_write_the_statistics = () =>
            statisticsManager.AssertWasCalled(m => m.WriteStatistics(true));
    }

    [Subject(typeof(BattleReachedAReasonableTurnObserver))]
    public class when_at_the_start_of_turn_fourty_nine : with_an_observer
    {
        Establish context = () => WithADecisionStateAtTurnNumber(49);

        It should_subscribe_to_the_observable_but_not_have_recognised_turn_fifty = () =>
            observer.ReachedTurnFifty.ShouldBeFalse();
    }

    [Subject(typeof(BattleReachedAReasonableTurnObserver))]
    public class when_starting_at_turn_fifty_one_and_fifty_never_happened : with_an_observer
    {
        Establish context = () => WithADecisionStateAtTurnNumber(51);

        It should_subscribe_to_the_observable_and_not_have_recognised_turn_fifty = () =>
            observer.ReachedTurnFifty.ShouldBeFalse();
    }

    public abstract class with_an_observer
    {
        Establish context = () =>
        {
            decisionStateEvent = MockRepository.GenerateStub<IEvent<DecisionState>>();
            decisionStateKeeper = MockRepository.GenerateStub<IKeepDecisionState>();
            statisticsManager = MockRepository.GenerateStub<IManageStatistics>();
            observer = new BattleReachedAReasonableTurnObserver(statisticsManager);
        };

        Because of = () => observer.Observe(decisionStateKeeper);

        protected static IEvent<DecisionState> decisionStateEvent;
        protected static IObservable<IEvent<DecisionState>> decisionStateObservable;
        protected static IKeepDecisionState decisionStateKeeper;
        protected static BattleReachedAReasonableTurnObserver observer;
        protected static IManageStatistics statisticsManager;
        protected static DecisionState decisionState;

        protected static void WithADecisionStateAtTurnNumber(int turnNumber)
        {
            decisionState = new DecisionState() { TheNumberOfTurnsSoFar = turnNumber };
            decisionStateEvent.Stub(s => s.EventArgs).Return(decisionState);
            situation = Observable.Return(decisionStateEvent);
            decisionStateKeeper.Stub(d => d.Situation)
                               .Return(situation);
        }
    }

I've cleaned the specification up a bit, but the main changes are simply moving from the old observable to to the new one in the new context. The observer now implements the new interface and thus I can pass in the decision state keeper.
Here is the revised implementation:

    public class BattleReachedAReasonableTurnObserver : IObserveToMakeDecisions
    {
        readonly IManageStatistics statisticsManager;

        public BattleReachedAReasonableTurnObserver(IManageStatistics statisticsManager)
        {
            this.statisticsManager = statisticsManager;
        }

        public void Observe(IKeepDecisionState decisionStateKeeper)
        {
            decisionStateKeeper.Situation
                               .Where(d => d.EventArgs.TheNumberOfTurnsSoFar == 50)
                               .Subscribe(s =>
                               {
                                   ReachedTurnFifty = true;
                                   statisticsManager.WriteStatistics(ReachedTurnFifty);
                               });
        }

        public bool ReachedTurnFifty { get; private set; }
    }

This will ensure I pass my original acceptance test that the robot should not be disabled at the start of a battle - once I hook up the translator to this, it should all be ready to go.

I also have a StartOfTheBattleObserver which detects the first turn number and issues instructions to the robot to begin scanning. Issuing instructions is outside the responsibilities of this context, so I'm not going to port that across to the context just yet and will review this in good time.

The next post will cover the context translator that will hopefully pull it all together to pass my acceptance test once again.

Posted at at 7:48 AM on Thursday, September 9, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: , ,

publishing the world state

In my last post I had my robot making one of the first updates to a world state and now I need to ensure that my robot engine does indeed update the world state. This is a complete change to my robot as described in the last few posts, so for the time being I'll be losing the observables I had previously set up, but they will return when I map to my different contexts.

I need the update to occur in my main robot loop and because these updates will often happen in an event, I would like the world state update stored and then executed in the main loop.

First, I start with a new specification for this state update:

    public class when_told_to_publish_to_the_world_state : with_a_robot_engine
    {
        Establish context = () =>
        {
            robotEngine.Initialise(robot);            
            worldStateUpdate = w => { };
        };

        Because of = () => robotEngine.PublishToTheWorldState(worldStateUpdate);

        It should_have_a_pending_world_state_update = () =>
            robotEngine.PendingWorldStateUpdates.ShouldContain(worldStateUpdate);

        static Action<IWorldState> worldStateUpdate;        
    }

I'm creating an action to update the world state - any instance of a delegate will do for this purpose - and am publishing to the world state.
It should then have stored this pending update in the robot engine.

The implementation: (only relevant parts of code shown)

    public class RobotEngine : ImARobotEngine
    {
        List<Action<IWorldState>> pendingWorldStateUpdates = new List<Action<IWorldState>>();

        public ReadOnlyCollection<Action<IWorldState>> PendingWorldStateUpdates
        {
            get { return pendingWorldStateUpdates.AsReadOnly(); }
        }

        public void PublishToTheWorldState(Action<IWorldState> worldStateUpdate)
        {
            pendingWorldStateUpdates.Add(worldStateUpdate);
        }
    }

Next stage is to add a method in for ensuring that the pending world states get activated:

    public class when_told_to_ensure_the_world_state_is_up_to_date : with_a_robot_engine
    {
        Establish context = () =>
        {
            robotEngine.Initialise(robot);
            expectedGunTemperature = 222;
            worldStateUpdate = w => w.GunTemperature = expectedGunTemperature;
            robotEngine.PublishToTheWorldState(worldStateUpdate);
        };

        Because of = () => robotEngine.EnsureTheWorldStateIsUpToDate();

        It should_update_the_world_state_accordingly = () =>
            worldState.GunTemperature.ShouldEqual(expectedGunTemperature);

        It should_have_no_pending_world_state_updates_left = () =>
            robotEngine.PendingWorldStateUpdates.Count.ShouldEqual(0);

        static Action<IWorldState> worldStateUpdate;
        static int expectedGunTemperature;
    }

The implementation of this is:

        public void EnsureTheWorldStateIsUpToDate()
        {
            foreach(var makeAnUpdateTo in pendingWorldStateUpdates)
            {
                makeAnUpdateTo(worldState);
            }
            pendingWorldStateUpdates.RemoveAll(a => true);
        }

I now need to integrate this into my robot - I'll not be able to test an infinite loop which is usually required in the Run() method of a robot so I'm going to put some conditions in that loop in for testing.

I've added an observation into an existing specification:

    public class when_the_slayer_robot_is_run : with_robot_set_up
    {
        Establish context = () => 
        {
            robot.ServiceLocator = serviceLocator;

            robotEngine = MockRepository.GenerateStub<ImARobotEngine>();
            serviceLocator.Stub(x => x.ProvideRobotEngine()).Return(robotEngine);
        };

        Because of = () => robot.Run(false);

        It should_ask_the_service_locator_for_a_robot_engine = () =>
            serviceLocator.AssertWasCalled(x => x.ProvideRobotEngine());

        It should_ask_the_robot_engine_to_initialise_with_itself = () =>
            robotEngine.AssertWasCalled(x => x.Initialise(robot));

        It should_ensure_that_the_world_state_is_updated = () =>
            robotEngine.AssertWasCalled(r => r.EnsureTheWorldStateIsUpToDate());

        static ImARobotEngine robotEngine;
    }

The third observation here ensures that when run is called that the world state is made up to date. By providing false in the overloaded Run() method I'm declaring that I don't want an infinite loop.

Here is my reworked robot implementation:

    public class SlayerRobot : Robot, ImARobot
    {
        ImARobotEngine robotEngine;

        public override void Run()
        {
            Run(true);
        }

        public void Run(bool shouldContinueToLoop)
        {
            robotEngine = ServiceLocator.ProvideRobotEngine();
            robotEngine.Initialise(this);

            bool shouldLoop = true;

            while(shouldLoop)
            {
                robotEngine.EnsureTheWorldStateIsUpToDate();

                shouldLoop = shouldContinueToLoop;
            }
        }

        public override void OnStatus(StatusEvent e)
        {
            robotEngine.PublishToTheWorldState(w =>
               {
                   w.CurrentTurnNumber = e.Status.Time;
                   w.GunTemperature = e.Status.GunHeat;
               });
        }
    }

I now have the first of the world state updates hooked into my robot - my run method will perform an infinite loop of ensuring that world state updates occur (should there be any). The OnStatus event will publish to the world state and this will be recorded by the robot engine, ready for update in the main loop.

Here's the reworked robot engine that accompanies it:

    public class RobotEngine : ImARobotEngine
    {
        readonly IManageStatistics statisticsManager;
        readonly IWorldState worldState;
        ImARobot robot;

        List<Action<IWorldState>> pendingWorldStateUpdates = new List<Action<IWorldState>>();

        public RobotEngine(IWorldState worldState, IManageStatistics statisticsManager)
        {
            this.statisticsManager = statisticsManager;
            this.worldState = worldState;
        }

        public ReadOnlyCollection<Action<IWorldState>> PendingWorldStateUpdates
        {
            get { return pendingWorldStateUpdates.AsReadOnly(); }
        }

        public void Initialise(ImARobot robot)
        {
            this.robot = robot;
            statisticsManager.EnsureWeStartWithCleanStatistics();
        }

        public void PublishToTheWorldState(Action<IWorldState> worldStateUpdate)
        {
            pendingWorldStateUpdates.Add(worldStateUpdate);
        }

        public void EnsureTheWorldStateIsUpToDate()
        {
            foreach(var makeAnUpdateTo in pendingWorldStateUpdates)
            {
                makeAnUpdateTo(worldState);
            }
            pendingWorldStateUpdates.RemoveAll(a => true);
        }
    }

The world state now gets updated but there is nothing "listening" to these updates at present.
My next post will move to updating each context every time the world state gets updated.

Posted at at 7:43 AM on Monday, September 6, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: ,

moving to a robocode world state

I've been sharing my experiences in driving my robocode implementation through specification and in my last few posts showed how my thinking has evolved and how I wanted to have some bounded contexts between decision making, calculation and manipulation.

I've got my robot to a stage where it scans once, then does not fire and to make it do more things I need to publish some more state to observables. My existing code needs a refactor to any new shape I derive but I have acceptance tests that assert against that development so I'm free to change it with some degree of confidence.

So I go back to an older specification for the SlayerRobot itself - when the turn status is updated and mark this to be removed at some stage. Here's what it currently looks like:

    public class when_robocode_updates_the_turn_status_on_a_robot_TO_BE_REMOVED 
                                                                      : with_robot_set_up
    {
        Establish context = () =>                   
        {
            robot.StartOfEveryTurn += (s, e) =>  statusAtStartOfTheTurn = e;

            turnNumber = 34;
            robotStatus = RobocodeSpy.CreateARobotStatus(turnNumber);
            statusEvent = new StatusEvent(robotStatus);
        };

        Because of = () => robot.OnStatus(statusEvent);

        It should_update_the_start_of_every_turn_event_with_the_turn_number = () =>
            statusAtStartOfTheTurn.TurnNumber.ShouldEqual(turnNumber);

        static StatusEvent statusEvent;
        static RobotStatus robotStatus;
        static long turnNumber;
        static StatusAtTheStartOfATurn statusAtStartOfTheTurn;
    }

I want a new way of updating the state, so create a new specification:

    public class when_robocode_updates_the_turn_status_on_a_robot : with_robot_set_up
    {
        Establish context = () =>
        {            
            robotStatus = RobocodeSpy.CreateARobotStatus(0, 2.3);
            statusEvent = new StatusEvent(robotStatus);

            robotEngine = MockRepository.GenerateStub<ImARobotEngine>();

            serviceLocator.Stub(x => x.ProvideRobotEngine()).Return(robotEngine);
            robot.Run();
        };

        Because of = () => robot.OnStatus(statusEvent);

        It should_tell_the_robot_engine_to_publish_to_the_world_state = () =>
            robotEngine.AssertWasCalled(x => 
                      x.PublishToTheWorldState(Arg<Action<IWorldState>>.Is.NotNull));

        static StatusEvent statusEvent;
        static RobotStatus robotStatus;
        static ImARobotEngine robotEngine;
    }

I've first expanded my RobocodeSpy class to allow the gun heat to be injected when creating a RobotStatus - here I'm setting it to 2.3. I then provide a stubbed RobotEngine by using the service locator and run the robot to begin that initialisation.

When the event is called, I now want the robot to publish to the world state through the robot engine - it can provide an Action<IWorldState> that the robot engine will take care of.
The specification fails, so I implement like this (only relevant part of the robot code is shown):

    public class SlayerRobot : Robot, ImARobot
    {
        public override void OnStatus(StatusEvent e)
        {
            _robotEngine.PublishToTheWorldState(w => { });
        }
     }

I'm publishing to the world state and my specification passes. I now want to verify that the turn number and the gun heat are updated on the world state so I add some more assertions:

    public class when_robocode_updates_the_turn_status_on_a_robot : with_robot_set_up
    {
        Establish context = () =>
        {
            expectedTurnNumber = 32;
            expectedGunHeat = 2.3;
            robotStatus = RobocodeSpy.CreateARobotStatus(expectedTurnNumber, expectedGunHeat);
            statusEvent = new StatusEvent(robotStatus);

            robotEngine = MockRepository.GenerateStub<ImARobotEngine>();
            robotEngine.Stub(x => x.PublishToTheWorldState(null))
                       .IgnoreArguments().Do(RecordPublicationToTheWorldState);

            serviceLocator.Stub(x => x.ProvideRobotEngine()).Return(robotEngine);
            robot.ServiceLocator = serviceLocator;
            robot.Run();
        };

        Because of = () => robot.OnStatus(statusEvent);

        It should_tell_the_robot_engine_to_publish_to_the_world_state = () =>
            robotEngine.AssertWasCalled(x => 
                     x.PublishToTheWorldState(Arg<Action<IWorldState>>.Is.NotNull));

        It should_affect_the_turn_number_on_the_world_state = () =>
            TheWorldState.CurrentTurnNumber.ShouldEqual(expectedTurnNumber);

        It should_affect_the_gun_temperature_on_the_world_state = () =>
            TheWorldState.GunTemperature.ShouldEqual(expectedGunHeat);

        static Action<Action<IWorldState>> RecordPublicationToTheWorldState = 
                                                      a => updateTheWorldState = a;

        protected static IWorldState TheWorldState
        {
            get
            {
                var worldState = MockRepository.GenerateStub<IWorldState>();
                updateTheWorldState(worldState);
                return worldState;
            }
        }

        static StatusEvent statusEvent;
        static RobotStatus robotStatus;
        static ImARobotEngine robotEngine;
        static Action<IWorldState> updateTheWorldState;
        static long expectedTurnNumber;
        static double expectedGunHeat;
    }

There are quite a few changes here - first I'm stubbing the robot engine publishing to world state method and am recording the action that is sent in with my RecordPublicationToTheWorldState static field.
I have two new observations that check the world state - each time the property is accessed I create a new stub and apply the recorded action's changes to it and return it.
I can then assert that the robot is indeed suggesting an update to the right areas of the world state.

Here's the implementation to make this pass:

    public class SlayerRobot : Robot, ImARobot
    {
        public override void OnStatus(StatusEvent e)
        {
            _robotEngine.PublishToTheWorldState(w =>
                        {
                            w.CurrentTurnNumber = e.Status.Time;
                            w.GunTemperature = e.Status.GunHeat;
                        });
        }
    }

In the next robocode post I'll move onto the robot engine and ensuring the world state updates occur.

Posted at at 7:40 AM on Thursday, September 2, 2010 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: , ,