Problem Statement
Consider a rover and a plateau of size nxn. The rover takes three type of instructions L,R and M. 'L' and 'R' rotate the rover in the left and right direction. 'M' moves the rover one step forward in the direction it faces.
Input: Plateau size, Initial direction, Initial position and Instructions. Output: Final position and direction the rover faces.
Eg. Input: Plateau Size :5 Initial Direction : N Initial Position : 0,0 Instructions: RMML
Output: 2,0 N.
I have written a program that does this. I would like a review on it. Also I have used a grid coordinate system to refer the plateau here. Is there a better way to do it ??
MarsRover.java
/**
* Created by Leo on 18-07-2015.
Completed on 23-07-2015
*/
import java.util.Scanner;
public class MarsRover {
private String inst_set;
private Plateau p;
private Cell currentLocation;
public enum Direction{N,S,E,W}
Direction dir;
public MarsRover(Plateau p1, int x, int y, Direction dir, String instSet) {
p=p1;
inst_set=instSet;
this.dir=dir;
currentLocation=new Cell(x, y);
}
public MarsRover(){}
private void executeInst() {
int i = 0;
while (i < inst_set.length()) {
char inst = inst_set.charAt(i++); //get each inst separately as a character
if (inst == 'M') {
Cell nextCell = p.getNeighbour(dir, currentLocation);
if (nextCell != null)
currentLocation = nextCell;
else
System.out.println("This move is not possible. Going to next Instruction");
}
if (inst == 'L' || inst == 'R') {
dir = setDirection(dir, inst);
}
}
}
public void showCurrentLocation(){
System.out.println("Current Cell is:");
System.out.print(currentLocation.x);
System.out.print("\t"+currentLocation.y);
System.out.print("\t"+dir+"\n");
}
public Direction setDirection(Direction dir, char inst) {
if(inst=='L') {
switch (dir) {
case N:
dir = Direction.W;
break;
case W:
dir = Direction.S;
break;
case S:
dir = Direction.E;
break;
case E:
dir = Direction.N;
break;
}
}
else if(inst=='R'){
switch (dir) {
case N:
dir = Direction.E;
break;
case W:
dir = Direction.N;
break;
case S:
dir = Direction.W;
break;
case E:
dir = Direction.S;
break;
}
}
return dir;
}
public static void main(String... a){
Plateau p1=new Plateau();
Scanner in = new Scanner(System.in);
int x,y;
String instSet;
String dir;
System.out.println("Enter the direction the rover is Headed");
dir=in.nextLine();
System.out.println("Enter the Initial XLocation:");
x=in.nextInt();
in.nextLine();
System.out.println("Enter the Initial YLocation:");
y=in.nextInt();
in.nextLine();
System.out.println("Enter the Instructions\t");
instSet=in.nextLine();
MarsRover mr1=new MarsRover(p1,x,y,Direction.valueOf(dir),instSet);
mr1.executeInst();
mr1.showCurrentLocation();
}
}
Plateau.java
import java.util.Scanner;
/**
* Created by Leo on 28-07-2015.
*/
class Plateau {
private int size;
public Plateau() {
Scanner in = new Scanner(System.in);
System.out.println("Enter the Size of the plateau");
size=in.nextInt();
in.nextLine();
}
public Plateau(int sz){
size=sz;
}
public Cell getNeighbour(MarsRover.Direction dir,Cell c){
Cell neighbour = null;
switch (dir) {
case N:
neighbour=new Cell(c.x,c.y+1);
break;
case W:
neighbour=new Cell(c.x-1,c.y);
break;
case S:
neighbour=new Cell(c.x,c.y-1);
break;
case E:
neighbour=new Cell(c.x+1,c.y);
break;
}
if((neighbour.x>=0)&&(neighbour.y>=0)&&(neighbour.x<size)&&(neighbour.y<size))
return neighbour;
return null;
}
}
Cell.java
/**
* Created by Leo on 28-07-2015.
*/
class Cell{
int x;
int y;
public Cell(int PosX, int PosY) {
x=PosX;
y=PosY;
}
}
MarsRoverTest.java
/**
* Created by Leo on 24-07-2015.
*/
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MarsRoverTest {
MarsRover.Direction DirIp;
Plateau p = new Plateau(5);
MarsRover m = new MarsRover();
@Test
public void testRotation() {
//Assertion For LeftRotation.
DirIp= MarsRover.Direction.N;
assertEquals(MarsRover.Direction.W, m.setDirection(DirIp, 'L'));
DirIp= MarsRover.Direction.W;
assertEquals(MarsRover.Direction.S, m.setDirection(DirIp, 'L'));
DirIp= MarsRover.Direction.S;
assertEquals(MarsRover.Direction.E, m.setDirection(DirIp, 'L'));
DirIp= MarsRover.Direction.E;
assertEquals(MarsRover.Direction.N, m.setDirection(DirIp, 'L'));
//Assertion for RightRotation
DirIp= MarsRover.Direction.N;
assertEquals(MarsRover.Direction.E, m.setDirection(DirIp, 'R'));
DirIp= MarsRover.Direction.W;
assertEquals(MarsRover.Direction.N, m.setDirection(DirIp, 'R'));
DirIp= MarsRover.Direction.S;
assertEquals(MarsRover.Direction.W, m.setDirection(DirIp, 'R'));
DirIp= MarsRover.Direction.E;
assertEquals(MarsRover.Direction.S, m.setDirection(DirIp, 'R'));
}
@Test
public void testCheckMovement(){
//Impossible Moves
for(int i=0;i<5;i++) {
DirIp = MarsRover.Direction.W;
assertEquals(null,p.getNeighbour(DirIp, new Cell(0,i)));
DirIp=MarsRover.Direction.S;
assertEquals(null,p.getNeighbour(DirIp,new Cell(i,0)));
}
for(int i=0;i<5;i++){
DirIp=MarsRover.Direction.N;
assertEquals(null,p.getNeighbour(DirIp,new Cell(i,4)));
DirIp=MarsRover.Direction.E;
assertEquals(null,p.getNeighbour(DirIp,new Cell(4,i)));
}
//Take a cell from the center and check its moves
Cell centerCell= new Cell(2,3);
DirIp=MarsRover.Direction.E;
Cell next=p.getNeighbour(DirIp,centerCell);
assertEquals(3,next.x);
assertEquals(3,next.y);
DirIp=MarsRover.Direction.N;
next=p.getNeighbour(DirIp,centerCell);
assertEquals(2,next.x);
assertEquals(4,next.y);
DirIp=MarsRover.Direction.W;
next=p.getNeighbour(DirIp,centerCell);
assertEquals(1,next.x);
assertEquals(3,next.y);
DirIp=MarsRover.Direction.S;
next=p.getNeighbour(DirIp,centerCell);
assertEquals(2,next.x);
assertEquals(2,next.y);
}
}