How can I connect Enum with its opposite value, as in the main directions (North-South, East-West, etc.)?

I'm still working on my Cell class for my maze game I'm trying to make. After helping in another thread, it was suggested that I use EnumMap for my Walls / Neighbors, and this works fine so far.

Here is what I still have:

enum Dir { NORTH, SOUTH, EAST, WEST } class Cell { public Map<Dir, Cell> neighbors = Collections .synchronizedMap(new EnumMap<Dir, Cell>(Dir.class)); public Map<Dir, Boolean> walls = Collections .synchronizedMap(new EnumMap<Dir, Boolean>(Dir.class)); public boolean Visited; public Cell() { Visited = false; for (Dir direction : Dir.values()) { walls.put(direction, true); } } // Randomly select an unvisited neighbor and tear down the walls // between this cell and that neighbor. public Cell removeRandomWall() { List<Dir> unvisitedDirections = new ArrayList<Dir>(); for (Dir direction : neighbors.keySet()) { if (!neighbors.get(direction).Visited) unvisitedDirections.add(direction); } Random randGen = new Random(); Dir randDir = unvisitedDirections.get(randGen .nextInt(unvisitedDirections.size())); Cell randomNeighbor = neighbors.get(randDir); // Tear down wall in this cell walls.put(randDir, false); // Tear down opposite wall in neighbor cell randomNeighbor.walls.put(randDir, false); // <--- instead of randDir, it needs to be it opposite. return randomNeighbor; } } 

If you look at this last comment, I will first tear down, say, a NORTH wall in my current cell. Then I take my northern neighbor, and now I have to tear down my southern wall, so the walls between the two cells have been removed.

What will be a simple way to expand my enumeration so that I can give him direction, and he returns me the opposite?

+4
source share
4 answers

The easiest way, I think, is to simply add a method to it. Please note that this only works if the number of transition constants does not change over time.

 enum Dir { NORTH, SOUTH, EAST, WEST; public Dir opposite() { switch(this) { case NORTH: return Dir.SOUTH; case SOUTH: return Dir.NORTH; case EAST: return Dir.WEST; case WEST: return Dir.EAST; default: throw new IllegalStateException("This should never happen: " + this + " has no opposite."); } } } 

Then in your code you can do this:

 randomNeighbor.walls.put(randDir.opposite(), false); 
+10
source

another way without switching / case or having a storage state:

 public enum Dir { NORTH { @Override public Dir opposite() { return SOUTH; }}, EAST { @Override public Dir opposite() { return WEST; }}, SOUTH { @Override public Dir opposite() { return NORTH; }}, WEST { @Override public Dir opposite() { return EAST; }}, ; abstract public Dir opposite(); } 
+14
source

You can try this, the β€œgood” thing is that you can actually index enums as an array, curious ... and since we are dealing with opposites, since they always have pairs, the code supports it while you add new values ​​to end, so as not to spoil the indexing.

 enum Directions { NORTH(1), SOUTH(0), WEST(3), EAST(2); private final int opposite; Directions(int opposite) { this.opposite = opposite; } Directions opposite() { return Directions.values()[this.opposite]; } } 

For example, if you want to add more directions, you would simply add this:

 NORTH_WEST(7), NORTH_EAST(6), SOUTH_WEST(5), SOUTH_EAST(4) 

Easily.:)

+1
source
 public enum Direction { NORTH,EAST,SOUTH,WEST; public Direction opposite() { return Direction.values()[ (this.ordinal() + 2) & 3 ]; } } 
0
source

All Articles