Instructions
- There is a single file called Rover.cs containing a very simple, but untested solution;
- You need to refactor it to a more maintainable and testable code;
- The program should be written using test driven development, following the red, green, refactor steps;
- Please use one or more design patterns when developing your solution. This is your opportunity to show your skills, use it well;
- Don't sacrifice tests to complete the solution, this will result in a fail;
- We don't mind if the test is incomplete, we are only interested in seeing your approach;
- We are looking for the solution to be well factored and to adhere to the SOLID principles.
Github
- Fork the project on github.
- Commit after every refactor cycle at least.
- Don't use branches.
- Your solution should be compatible with VS 2015.
- If you want to share some thoughts with us feel free to do it on this file.
- Try to not spend more than 3 hours to finish the tech test.
Tech Test
A rover has been developed to map out the landscape of Mars. The rover is a robot which can move on a 5x5 grid controlled by simple commands. Write a program which controls the movement of the Mars rover.
The application should be a console app which prompts the controller for the instruction.
Rotate Left : L
Rotate Right: R
Forward: F
The current rover position should be output in the console.
0,0 | 0,1 | 0,2 | 0,3
1,0 | 1,1 | 1,2 | 1,3
2,0 | 2,1 | 2,2 | 2,3
3,0 | 3,1 | 3,2 | 3,3
Requirements
As a controller user I want the rover to be able to rotate left
- Given the rover is facing North, when the river rotates Left, Then the rover is facing West.
- Given the rover is facing West, when the river rotates Left, Then the rover is facing South.
- Given the rover is facing South, when the river rotates Left, Then the rover is facing East.
- Given the rover is facing East, when the river rotates Left, Then the rover is facing North.
As a controller user I want the rover to be able to rotate right
- Given the rover is facing North, when the rover rotates right, Then the rover is facing East.
- Given the rover is facing East, when the rover rotates right, Then the rover is facing South.
- Given the rover is facing South, when the rover rotates right, Then the rover is facing West.
- Given the rover is facing West, when the rover rotates right, Then the rover is facing North.
As a controller user I want the rover to be able to move forward
- Given the Is at position 1.1 and the rover is facing North, when the rover moves forward, the rover is in position 0,1.
As a controller I want to be able to see the rover’s position once it has moved
- When the user moves the rover to (1,1), the rover’s position is displayed in the format(1,1)
As a controller I don’t want the rover to be able to move outside the confines of the grid
- Given the Rover is facing West and is at position (0,0), when the user tries to move forward, the rovers position does not change
Code
using System;
namespace TechTest
{
public class Rover
{
public enum RoverFacing
{
North,
East,
South,
West
}
public static void Main()
{
var roverPositionX = 0;
var roverPositionY = 0;
var roverFacing = RoverFacing.North;
while (true)
{
var command = Console.ReadLine();
if (command != "L" && command != "R" && command != "F")
throw new Exception("invalid command");
switch (command)
{
case "L":
roverFacing = roverFacing == RoverFacing.North ? RoverFacing.West : (RoverFacing)((int)roverFacing - 1);
Console.WriteLine($"Rover is now at {roverPositionX}, {roverPositionY} - facing {roverFacing}");
break;
case "R":
roverFacing = roverFacing == RoverFacing.West ? RoverFacing.North : (RoverFacing)((int)roverFacing + 1);
Console.WriteLine($"Rover is now at {roverPositionX}, {roverPositionY} - facing {roverFacing}");
break;
case "F":
switch (roverFacing)
{
case RoverFacing.North:
roverPositionX++;
break;
case RoverFacing.East:
roverPositionY++;
break;
case RoverFacing.South:
roverPositionX--;
break;
case RoverFacing.West:
roverPositionY--;
break;
}
Console.WriteLine($"Rover is now at {roverPositionX}, {roverPositionY} - facing {roverFacing}");
break;
default:
throw new Exception("invalid command");
}
}
}
}
}