Michael
Michael

Reputation: 61

Changing the direction of a point

I was to create a code where I mimic the functions of a robot. Turning and moving and such. I feel as if I'm approaching this in all the wrong ways... When I was writing this I thought I understood the gist of it, if the direction in the constructor is this then if it turn the new direction is this. I tested this and of course I ended up with some real incorrect results. I'm absolutely sure that I don't actually use any of these functions for my object. Can I get a tip about how to work this kind of code?

import java.awt.Point;
public class Robot
{
private int x;
private int y;
private int d;
private int p;
public static final int NORTH = 0;
public static final int SOUTH = 1;
public static final int EAST = 2;
public static final int WEST = 3;

/**
 * Constructor for objects of class Robot
 * @param theX the x coordinate
 * @param theY the y coordinate
 * @param theDirection the direction the robot is facing
 */
public Robot(int theX, int theY, int theDirection)
{
    x = theX;
    y = theY;
    d = theDirection;
}

public void turnLeft()
{
    if(d == NORTH) {
        d = WEST;
    }
    if(d == WEST) {
        d = SOUTH;
    }
    if(d == SOUTH) {
        d = EAST;
    }
    if(d == EAST) {
        d = NORTH;
    }
}



public String getDirection()
{
    if(d == NORTH) {
        return "N";
    }
    if(d == SOUTH) {
        return "S";
    }
    if(d == WEST) {
        return "W";
    }
    if(d == EAST) {
        return "E";
    }   
    return "";
}
}

Testing

Robot rob = new Robot(20, 20, Robot.SOUTH);
rob.turnLeft;
System.out.println(rob.getDirection);

this return S when I think it should actually return E.

Upvotes: 0

Views: 6771

Answers (6)

rgrebski
rgrebski

Reputation: 2584

In case someone ever neeeded, here is a solution for turning either way:

public enum Direction {
    UP,
    LEFT,
    DOWN,
    RIGHT;

    Direction turnLeft() {
        int turnLeft = 1;
        return getDirectionByOrdinalMovingClockwise(turnLeft);
    }

    Direction turnRight() {
        int turnRight = -1;
        return getDirectionByOrdinalMovingClockwise(turnRight);
    }

    Direction turnAround() {
        int turnAround = 2;
        return getDirectionByOrdinalMovingClockwise(turnAround);
    }

    private Direction getDirectionByOrdinalMovingClockwise(int moveBy) {
        var thisDirectionOrdinal = ordinal();
        int newDirectionOrdinal = (thisDirectionOrdinal + moveBy) % enumElementsCount();
        if (newDirectionOrdinal < 0) {
            newDirectionOrdinal = enumElementsCount() + newDirectionOrdinal;
        }
        return values()[newDirectionOrdinal];
    }

    private int enumElementsCount() {
        return values().length;
    }

}

Upvotes: 0

Menno
Menno

Reputation: 12621

Enum

public enum Direction {
    private String name;
    private String indicator;

    public Direction(String name, String indicator) {
        this.name = name;
        this.indicator= indicator;
    }

    // getters

    NORTH("North", "N"),
    EAST("East", "E"),
    SOUTH("South", "S"),
    WEST("West", "W");
}

Next you can easily do this:

turnLeft() {
   switch (d) {
        case Direction.NORTH: return Direction.WEST;
        case Direction.WEST:  return Direction.SOUTH;
        case Direction.SOUTH: return Direction.EAST;
        case Direction.EAST:  return Direction.NORTH;
    }
}

getDirection() {
    return d.getIndicator();
}

This way you can get rid of the four static int (NORTH, WEST, EAST, SOUTH) and change int d into Direction d. I would really recommend using an enum for this. Just to be typesafe.

Upvotes: 1

Marco Forberg
Marco Forberg

Reputation: 2644

1st) you should really clean up your p and d stuff ;) i suggest to call d "direction"

2nd) you should rearrange your int constants for directions in clockwise order. so you could reduce your turnLeft() method to a single line of code. You could order them this way:

public static final int NORTH = 0;
public static final int EAST = 1;
public static final int SOUTH = 2;
public static final int WEST = 3;

3rd) for testing you should use JUnit:

@Test
public void turnLeft() {
    Robot rob = new Robot(20, 20, Robot.SOUTH);
    rob.turnLeft;
    assertEquals("E", rob.getDirection);
    rob.turnLeft;
    assertEquals("N", rob.getDirection);
    rob.turnLeft;
    assertEquals("W", rob.getDirection);
    rob.turnLeft;
    assertEquals("S", rob.getDirection);
}

Upvotes: 0

Alexander Citrahadi
Alexander Citrahadi

Reputation: 61

Your turnLeft method is not quite right.
Here's the code by using if:

public void turnLeft() {
  if (d == NORTH) {
      d = WEST;
  } else if (d == WEST) {
      d = SOUTH;
  } else if (d == SOUTH) {
      d = EAST;
  } else if (d == EAST) {
      d = NORTH;
  }
}

Here's the code by using switch..case

public void turnLeft() {

  switch (d) {
    case NORTH: d = WEST; break;
    case WEST: d = SOUTH; break;
    case SOUTH: d = EAST; break;
    case EAST: d = NORTH; break;
  }
}

Upvotes: 1

mitch
mitch

Reputation: 282

You need else if. When you turn left you assign a new value to d which is matching the condition of the following if statements.

Upvotes: 1

StepTNT
StepTNT

Reputation: 3967

What's the p var that you're using? Your current direction is stored in d

...
d = theDirection;
...

You should try with this one:

public void turnLeft()
{
    if(d == NORTH) {
        d = WEST;
    }
    if(d == WEST) {
        d = SOUTH;
    }
    if(d == SOUTH) {
        d = EAST;
    }
    if(d == EAST) {
        d = NORTH;
    }
}

EDIT: Just to clarify.

You wrote something like

if(p == SOUTH) {
        d = EAST;
    }

So you're checking if p is SOUTH and not d.

You're not using p anywhere so it will never be SOUTH, that's why your turnLeft() method does absolutely nothing!

Upvotes: 0

Related Questions