Commit 27836d6
Changed files (22)
build
product
project
build/rakefile.rb
@@ -30,3 +30,6 @@ task :deploy => :compile do
end
end
+task :run => :deploy do
+ sh "#{deploy_dir}/mars.rover.exe"
+end
product/project/CallbackCommand.cs
@@ -0,0 +1,6 @@
+namespace mars.rover
+{
+ public interface CallbackCommand<T> : ParameterizedCommand<T>
+ {
+ }
+}
\ No newline at end of file
product/project/CaptureUserInstructionsConsoleView.cs
@@ -0,0 +1,33 @@
+using System.IO;
+
+namespace mars.rover
+{
+ public class CaptureUserInstructionsConsoleView : CaptureUserInstructionsView
+ {
+ readonly TextReader reader;
+ readonly TextWriter writer;
+
+ public CaptureUserInstructionsConsoleView(TextReader reader, TextWriter writer)
+ {
+ this.reader = reader;
+ this.writer = writer;
+ }
+
+ public void attach_to(CaptureUserInstructionsPresenter presenter)
+ {
+ writer.WriteLine("Enter upper right coordinates:");
+ presenter.provide_upper_right_coordinates(reader.ReadLine());
+
+ writer.WriteLine("enter coordinates to deploy a rover to:");
+ presenter.deploy_rover_to(reader.ReadLine());
+
+ writer.WriteLine("enter commands to navigate rover:");
+ presenter.navigate_rover_using(reader.ReadLine());
+ }
+
+ public void display(uint x, uint y, string heading)
+ {
+ writer.WriteLine("{0} {1} {2}", x, y, heading);
+ }
+ }
+}
\ No newline at end of file
product/project/CaptureUserInstructionsPresenter.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace mars.rover
+{
+ public class CaptureUserInstructionsPresenter : Presenter
+ {
+ readonly CaptureUserInstructionsView view;
+ IList<HeadingFactory> factories;
+ IList<Navigation> navigations;
+ NASA nasa;
+ Mars plateau;
+ Rover rover;
+
+ public CaptureUserInstructionsPresenter(CaptureUserInstructionsView view)
+ {
+ this.view = view;
+ factories = new List<HeadingFactory>
+ {
+ new DefaultHeadingFactory("N", x => new North(x)),
+ new DefaultHeadingFactory("E", x => new East(x)),
+ new DefaultHeadingFactory("W", x => new West(x)),
+ new DefaultHeadingFactory("S", x => new South(x)),
+ };
+ navigations = new List<Navigation>
+ {
+ new Navigation('L', x => x.turn_left()),
+ new Navigation('R', x => x.turn_right()),
+ new Navigation('M', x => x.move_forward()),
+ };
+ }
+
+ public virtual void run()
+ {
+ view.attach_to(this);
+ }
+
+ public virtual void provide_upper_right_coordinates(string line)
+ {
+ var coordinates = line.Split(new[] {' '});
+ plateau = new Mars(Convert.ToUInt32(coordinates[0]), Convert.ToUInt32(coordinates[1]));
+ nasa = new NASA(plateau);
+ }
+
+ public virtual void deploy_rover_to(string line)
+ {
+ var coordinates = line.Split(new[] {' '});
+ rover = nasa.deploy_rover_to(Convert.ToUInt32(coordinates[0]), Convert.ToUInt32(coordinates[1]),
+ find_heading_for(coordinates[2]));
+ }
+
+ public virtual void navigate_rover_using(string line)
+ {
+ foreach (var command in line)
+ navigations.Single(x => x.is_satisfied_by(command)).navigate(rover);
+
+ view.display(rover.x, rover.y, rover.heading.ToString());
+ }
+
+ Heading find_heading_for(string heading)
+ {
+ return factories.Single(x => x.is_satisfied_by(heading)).create(plateau);
+ }
+ }
+
+ public interface HeadingFactory : Specification<string>
+ {
+ Heading create(Plateau plateau);
+ }
+
+ public class Navigation : Specification<char>
+ {
+ readonly char command_text;
+ readonly Action<Rover> navigation;
+
+ public Navigation(char command_text, Action<Rover> navigation)
+ {
+ this.command_text = command_text;
+ this.navigation = navigation;
+ }
+
+ public virtual void navigate(Rover rover)
+ {
+ navigation(rover);
+ }
+
+ public virtual bool is_satisfied_by(char item)
+ {
+ return char.ToUpperInvariant(command_text).Equals(char.ToUpperInvariant(item));
+ }
+ }
+
+ public class DefaultHeadingFactory : HeadingFactory
+ {
+ string code;
+ Func<Plateau, Heading> factory;
+
+ public DefaultHeadingFactory(string code, Func<Plateau, Heading> factory)
+ {
+ this.code = code;
+ this.factory = factory;
+ }
+
+ public bool is_satisfied_by(string item)
+ {
+ return string.Equals(code, item, StringComparison.OrdinalIgnoreCase);
+ }
+
+ public Heading create(Plateau plateau)
+ {
+ return factory(plateau);
+ }
+ }
+
+ public interface Specification<T>
+ {
+ bool is_satisfied_by(T item);
+ }
+}
\ No newline at end of file
product/project/CaptureUserInstructionsView.cs
@@ -0,0 +1,8 @@
+namespace mars.rover
+{
+ public interface CaptureUserInstructionsView
+ {
+ void attach_to(CaptureUserInstructionsPresenter presenter);
+ void display(uint coordinate, uint coordinate1, string heading);
+ }
+}
\ No newline at end of file
product/project/CommandProcessor.cs
@@ -0,0 +1,7 @@
+namespace mars.rover
+{
+ public interface CommandProcessor : Command
+ {
+ void add(Command command);
+ }
+}
\ No newline at end of file
product/project/Coordinate.cs
@@ -37,6 +37,11 @@ namespace mars.rover
return new Coordinate(coordinate);
}
+ static public implicit operator uint(Coordinate coordinate)
+ {
+ return coordinate.coordinate;
+ }
+
public int CompareTo(Coordinate other)
{
return coordinate.CompareTo(other.coordinate);
product/project/Headings.cs
@@ -8,7 +8,7 @@ namespace mars.rover
static public Heading South = new South(new DefaultPlateau());
}
- public class DefaultPlateau : Plateau
+ public class DefaultPlateau : Mars
{
public DefaultPlateau() : base(5, 5)
{
product/project/Mars.cs
@@ -0,0 +1,24 @@
+namespace mars.rover
+{
+ public class Mars : Plateau
+ {
+ readonly Coordinate top_x_coordinate;
+ readonly Coordinate top_y_coordinate;
+
+ public Mars(uint top_x_coordinate, uint top_y_coordinate)
+ {
+ this.top_x_coordinate = top_x_coordinate;
+ this.top_y_coordinate = top_y_coordinate;
+ }
+
+ public virtual bool within_x_axis(Coordinate x)
+ {
+ return top_x_coordinate.CompareTo(x) >= 0;
+ }
+
+ public virtual bool within_y_axis(Coordinate y)
+ {
+ return top_y_coordinate.CompareTo(y) >= 0;
+ }
+ }
+}
\ No newline at end of file
product/project/NASA.cs
@@ -2,8 +2,11 @@ namespace mars.rover
{
public class NASA
{
- public virtual void report_top_left_coordinates_to(SpecifyTopLeftCoordinates callback)
+ Plateau plateau;
+
+ public NASA(Plateau plateau)
{
+ this.plateau = plateau;
}
public virtual Rover deploy_rover_to(uint x_coordinate, uint y_coordinate, Heading heading)
product/project/NASAPresenter.cs
@@ -1,32 +0,0 @@
-using System;
-
-namespace mars.rover
-{
- public class NASAPresenter : Presenter, SpecifyTopLeftCoordinates
- {
- readonly NASA nasa;
-
- public NASAPresenter(NASA nasa)
- {
- this.nasa = nasa;
- }
-
- public virtual void run()
- {
- nasa.report_top_left_coordinates_to(this);
- }
-
- public void run_with(Coordinate item)
- {
- throw new NotImplementedException();
- }
- }
-
- public interface SpecifyTopLeftCoordinates : CallbackCommand<Coordinate>
- {
- }
-
- public interface CallbackCommand<T> : ParameterizedCommand<T>
- {
- }
-}
\ No newline at end of file
product/project/Plateau.cs
@@ -1,24 +1,8 @@
namespace mars.rover
{
- public class Plateau
+ public interface Plateau
{
- readonly Coordinate top_x_coordinate;
- readonly Coordinate top_y_coordinate;
-
- public Plateau(uint top_x_coordinate, uint top_y_coordinate)
- {
- this.top_x_coordinate = top_x_coordinate;
- this.top_y_coordinate = top_y_coordinate;
- }
-
- public virtual bool within_x_axis(Coordinate x)
- {
- return top_x_coordinate.CompareTo(x) >= 0;
- }
-
- public virtual bool within_y_axis(Coordinate y)
- {
- return top_y_coordinate.CompareTo(y) >= 0;
- }
+ bool within_x_axis(Coordinate x);
+ bool within_y_axis(Coordinate y);
}
}
\ No newline at end of file
product/project/Program.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
namespace mars.rover
@@ -19,7 +20,8 @@ namespace mars.rover
static void Main(string[] args)
{
- new Program(new NASAPresenter(null)).run_with(args.Select(x => (CommandLineArgument) x));
+ new Program(new CaptureUserInstructionsPresenter(new CaptureUserInstructionsConsoleView(Console.In,Console.Out)))
+ .run_with( args.Select(x => (CommandLineArgument) x));
}
}
}
\ No newline at end of file
product/project/project.csproj
@@ -45,8 +45,12 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="CallbackCommand.cs" />
+ <Compile Include="CaptureUserInstructionsConsoleView.cs" />
+ <Compile Include="CaptureUserInstructionsView.cs" />
<Compile Include="Command.cs" />
<Compile Include="CommandLineArgument.cs" />
+ <Compile Include="CommandProcessor.cs" />
<Compile Include="Coordinate.cs" />
<Compile Include="East.cs" />
<Compile Include="Heading.cs" />
@@ -54,10 +58,11 @@
<Compile Include="NASA.cs" />
<Compile Include="North.cs" />
<Compile Include="ParameterizedCommand.cs" />
+ <Compile Include="Mars.cs" />
<Compile Include="Plateau.cs" />
<Compile Include="Position.cs" />
<Compile Include="Presenter.cs" />
- <Compile Include="NASAPresenter.cs" />
+ <Compile Include="CaptureUserInstructionsPresenter.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Rover.cs" />
product/project.specifications/CaptureUserInstructionsPresenterSpecs.cs
@@ -0,0 +1,22 @@
+using developwithpassion.bdd;
+using developwithpassion.bdd.contexts;
+using developwithpassion.bdd.mbunit.standard.observations;
+using mars.rover;
+
+namespace specifications
+{
+ public class CaptureUserInstructionsPresenterSpecs
+ {
+ }
+
+ public class when_initialized : observations_for_a_sut_without_a_contract<CaptureUserInstructionsPresenter>
+ {
+ it should_wait_for_instructions_from_nasa = () => view.was_told_to(x => x.attach_to(sut));
+
+ context c = () => { view = the_dependency<CaptureUserInstructionsView>(); };
+
+ because b = () => sut.run();
+
+ static CaptureUserInstructionsView view;
+ }
+}
\ No newline at end of file
product/project.specifications/EastSpecs.cs
@@ -28,7 +28,7 @@ namespace specifications
public override Heading create_sut()
{
- return new East(new Plateau(5, 5));
+ return new East(new Mars(5, 5));
}
static Coordinate y;
product/project.specifications/PlateauSpecs.cs → product/project.specifications/MarsSpecs.cs
@@ -5,61 +5,61 @@ using mars.rover;
namespace specifications
{
- public class PlateauSpecs
+ public class MarsSpecs
{
}
- public class when_within_the_x_boundary : observations_for_a_sut_without_a_contract<Plateau>
+ public class when_within_the_x_boundary : observations_for_a_sut_without_a_contract<Mars>
{
it should_return_true = () => result.should_be_true();
because b = () => { result = sut.within_x_axis(3); };
- public override Plateau create_sut()
+ public override Mars create_sut()
{
- return new Plateau(3, 3);
+ return new Mars(3, 3);
}
static bool result;
}
- public class when_within_the_y_boundary : observations_for_a_sut_without_a_contract<Plateau>
+ public class when_within_the_y_boundary : observations_for_a_sut_without_a_contract<Mars>
{
it should_return_true = () => result.should_be_true();
because b = () => { result = sut.within_y_axis(3); };
- public override Plateau create_sut()
+ public override Mars create_sut()
{
- return new Plateau(3, 3);
+ return new Mars(3, 3);
}
static bool result;
}
- public class when_outside_the_y_boundary : observations_for_a_sut_without_a_contract<Plateau>
+ public class when_outside_the_y_boundary : observations_for_a_sut_without_a_contract<Mars>
{
it should_return_false = () => result.should_be_false();
because b = () => { result = sut.within_y_axis(4); };
- public override Plateau create_sut()
+ public override Mars create_sut()
{
- return new Plateau(3, 3);
+ return new Mars(3, 3);
}
static bool result;
}
- public class when_outside_the_x_boundary : observations_for_a_sut_without_a_contract<Plateau>
+ public class when_outside_the_x_boundary : observations_for_a_sut_without_a_contract<Mars>
{
it should_return_false = () => result.should_be_false();
because b = () => { result = sut.within_x_axis(4); };
- public override Plateau create_sut()
+ public override Mars create_sut()
{
- return new Plateau(3, 3);
+ return new Mars(3, 3);
}
static bool result;
product/project.specifications/NASAPresenterSpecs.cs
@@ -1,23 +0,0 @@
-using developwithpassion.bdd;
-using developwithpassion.bdd.contexts;
-using developwithpassion.bdd.mbunit.standard.observations;
-using mars.rover;
-
-namespace specifications
-{
- public class NASAPresenterSpecs
- {
- }
-
- public class when_initialized : observations_for_a_sut_without_a_contract<NASAPresenter>
- {
- it should_wait_for_nasa_to_report_the_top_left_coordinates_of_the_plateau =
- () => nasa.received(x => x.report_top_left_coordinates_to(sut));
-
- context c = () => { nasa = the_dependency<NASA>(); };
-
- because b = () => sut.run();
-
- static NASA nasa;
- }
-}
\ No newline at end of file
product/project.specifications/NorthSpecs.cs
@@ -28,7 +28,7 @@ namespace specifications
public override Heading create_sut()
{
- return new North(new Plateau(5, 5));
+ return new North(new Mars(5, 5));
}
static Coordinate y;
product/project.specifications/project.specifications.csproj
@@ -68,9 +68,9 @@
<Compile Include="CoordinateSpecs.cs" />
<Compile Include="EastSpecs.cs" />
<Compile Include="NorthSpecs.cs" />
- <Compile Include="PlateauSpecs.cs" />
+ <Compile Include="MarsSpecs.cs" />
<Compile Include="Class1.cs" />
- <Compile Include="NASAPresenterSpecs.cs" />
+ <Compile Include="CaptureUserInstructionsPresenterSpecs.cs" />
<Compile Include="NASASpecs.cs" />
<Compile Include="PositionSpecs.cs" />
<Compile Include="ProgramSpecs.cs" />
product/project.specifications/SouthSpecs.cs
@@ -28,7 +28,7 @@ namespace specifications
public override Heading create_sut()
{
- return new South(new Plateau(5, 5));
+ return new South(new Mars(5, 5));
}
static Coordinate y;
product/project.specifications/WestSpecs.cs
@@ -28,7 +28,7 @@ namespace specifications
public override Heading create_sut()
{
- return new West(new Plateau(5, 5));
+ return new West(new Mars(5, 5));
}
static Coordinate y;