'A toy is controlled remotely over some grid like terrain. Along with its positional coordinates, the toy also maintains its facing (North, South, East, West) so that when remotecontrol commands 'move' - it moves in its facing direction. On turnLeft command, if facing North it would face West. On turnRight command, facing East then would be South. And so on .. '
Well smarty pants, I, declared an enum type.
public enum Facing {North, South, East, West;}
Writing a function to turn things right seemed simple enough!
public void turnRight() {
switch (this.currentFacing) {
case East : this.currentFacing = Facing.South; break;
case West : this.currentFacing = Facing.North; break;
case North: this.currentFacing = Facing.East; break;
case South: this.currentFacing = Facing.West; break;
default: break;
}
}
the similar way to implement the turnLeft() method!!! Now, this didn't seem to tough, eh? Ehrrrrrr! too many conditional statements? If say a new facing (NorthEast) is added, then for things to work, existing code would have to be broken and modified?
Now, Java 5 came with linguistic support for enumerated types enum. All enums implicitly extend java.lang.Enum and allow you to add typical class constructs. 'enum' is also Comparable and Serializable. Now, I could write some complicated program to solve the conditional expressions above. But hey all java enum return an array of declared enums through enum.values(). Voila!
So I wrote:
public enum Facing {North, East, South, West;} //change in order!
public Facing getFace(Facing refFace, int factor) {
int currentIdx = 0;
Facing[] faces = Facing.values();
for (int i=0; i < faces.length; i++) {
Facing face = faces[i];
if (face.equals(refFace)) {
currentIdx = i;
break;
}
}
currentIdx = currentIdx + factor;//the next facing index
if (currentIdx < 0) {
while (currentIdx < 0)
currentIdx = currentIdx + faces.length;
} else if (currentIdx >= faces.length) {
currentIdx = currentIdx - faces.length;
}
return faces[currentIdx];
}
if I consider turning left/anticlockwise as negative ..
getFace(Facing.North, -1); //=>Facing.West
getFace(Facing.North, +5); //=>Facing.East
So in the end, my turnRight() and turnLeft() turned to
public void turnRight() {
this.currentFacing = getFace(1, this.currentFacing);
}
public void turnLeft() {
this.currentFacing = getFace(-1, this.currentFacing);
}
Even if I go and change the Facing declaration to something like
public enum Facing {North, NorthEast, East, SouthEast, South, SouthWest, West, NorthWest;}things would still work as expected if you want to turn left from say North Facing 1 step to NorthWest, 2 steps to West or even turn 720 deg! :)
Think about implementing the same for Days of week, or Months and do similar mathematics on them.
day = add(Day.Monday,4);
day = add(Day.Monday,-3);
month = add(Month.January,-3);
You can further generalize things further using
day.getClass().getEnumConstants()
enum is Tiger introduced. Prior to that java, standard way was like declaring a public static final constant usually in an interface/abstract class! For example, how do you add days, month or years to a calendar object?
calendarInstance.add(Calendar.DATE, 2);
Notice the similarity of definition but the differentiation? Declared in Calendar class
public static final int DATE = 5;
if only java had operator overloading instead of the exotic darker beans and means for the riches! :((
No comments:
Post a Comment