Search code examples
javaenumsdirection

The easiest way to achieve a responsive orientation enum? java


I will quickly display what I want to achieve in the "clearest" way:

public enum Orientation {
    NORTH, WEST, SOUTH, EAST }

public enum Turn {
    LEFT, RIGHT }

So what I want those two enums to do is secure and efficiently look up the changed orientation according to the move:

Orientation orient = Orientation.NORTH;
// orient points to NORTH now
orient = orient.turn(Turn.LEFT);
// orient points to WEST now

The first way I tried to achieve this was through creating a map:

 EnumMap<Orientation, EnumMap<Turn, Orientation>>

And map all the directions statically but that is a huge chunk of map.get.put.get.... and is probably a bit too overdosed, altough resulting in this desired effect:

directionMap.get(NORTH).get(LEFT)
// the value would then be WEST

The next way I went was through a Compass class that links all orientations into a circle.. Working like a LinkedCircuitList ...<->NORTH<->EAST<->SOUTH<->WEST<->NORTH<->... So Compass could have a static function that calls any Member of that linked list and step to the left or to the right, resulting in the correct change of direction. But the code did not really work out the way I wanted it.

So my question in the end, does anybody has experience on that kind of code, or has an idea how to achieve the desired result in a nice enumerish way?


Solution

  • I see nothing wrong with the Map solution. If you want something more consise:

    public enum Orientation {
        NORTH, EAST, SOUTH, WEST;
    
        private static Orientation[] vals = values();
    
        Orientation turnTo(Turn t) {
            return vals[(4 + this.ordinal() + (t == Turn.RIGHT ? 1 : -1)) % 4];
        }
    }
    

    This, however, is less clean and maintainable (it would break if someone changes the order of the enums).

    A little cleaner (but less consise) :

    public enum Orientation {
        NORTH(0), EAST(1), SOUTH(2), WEST(3);
    
        private final int p;
    
        Orientation(int p) {
            this.p = p;
        }
    
        private static Orientation[] vals = new Orientation[4];
        static {
            for( Orientation o : Orientation.values() )
                vals[o.p] = o;
        }
    
        Orientation turnTo(Turn t) {
            return vals[(4 + this.p + (t == Turn.RIGHT ? 1 : -1)) % 4];
        }
    }