public enum Direction {
N(0, -1, -1),
NE(1, 0, -1),
SE(1, 1, 0),
S(0, 1, 1),
SW(-1, 1, 0),
NW(-1, 0, -1),
C(0, 0, 0);
private final int incColumn;
private final int incRowEven;
private final int incRowOdd;
private Direction(final int incI, final int incJEven, final int incJOdd) {
this.incColumn = incI;
this.incRowEven = incJEven;
this.incRowOdd = incJOdd;
}
public int getIncColumn() {
return incColumn;
}
public int getIncRowEven() {
return incRowEven;
}
public int getIncRowOdd() {
return incRowOdd;
}
public Point getNeighborCoordinates(Point coordinates) {
int column = coordinates.x + getIncColumn();
int row = coordinates.y + (Util.isEven(coordinates.x) ? getIncRowEven() : getIncRowOdd());
return new Point(column, row);
}
public static int getBitmask(Set<Direction> directions) {
int mask = 0;
for (Direction dir : directions) {
int bit = 1 << dir.ordinal();
mask |= bit;
}
return mask;
}
public static Set<Direction> getDirections(int bitmask) {
Set<Direction> directions = EnumSet.noneOf(Direction.class);
for (int bit = 0; bit < ALL_DIRECTIONS.length; bit++) {
if (testBitFlag(bitmask, bit)) {
directions.add(ALL_DIRECTIONS[bit]);
}
}
return directions;
}
private static boolean testBitFlag(int bitmask, int bit) {
int flag = 1 << bit;
return (bitmask & flag) != 0;
}
}