如何将Enum与其相反的值相关联,如在主要方向(南北,东西等)?

时间:2009-10-15 21:19:16

标签: java enums

我还在为我的迷宫游戏制作我的Cell课程。在另一个线程的帮助之后,有人建议我使用EnumMap作为我的墙/邻居,到目前为止这个工作很有用。

这是我到目前为止所做的:

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's opposite.

        return randomNeighbor;
    }
}

如果你看看那里的最后一条评论,我先说下我当前单元格中的北墙。然后我带我的北邻居,现在我必须拆掉我的南墙,所以两个牢房之间的墙壁已被拆除。

什么是扩展我的枚举的简单方法,所以我可以给它一个方向,然后它又回到我身边呢?

4 个答案:

答案 0 :(得分:15)

另一种没有开关/案例的方式,或者必须存储状态:

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();
}

答案 1 :(得分:10)

我认为,最简单的方法就是添加一个方法。请注意,只有在枚举常量的数量不会随时间变化时才能正常工作。

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.");
        }
    }
}

然后,在您的代码中,您可以这样做:

randomNeighbor.walls.put(randDir.opposite(), false);

答案 2 :(得分:1)

你可以尝试这个,关于这个的“好”的事情是你可以实际上像数组一样索引枚举,有点......因为我们正在处理对立面,因为总是有对,代码支持它只要你将新值添加到最后,这样就不会搞砸索引。

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];
    }

}

例如,如果您想添加更多路线,只需添加以下内容:

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

易。 :)

答案 3 :(得分:0)

public enum Direction
{
    NORTH,EAST,SOUTH,WEST;

    public Direction opposite()
    {
        return Direction.values()[ (this.ordinal() + 2) & 3 ];
    }
}