我在Groovy中制作一个Text Adventure游戏作为一种练习,我遇到了一个奇怪的错误.
现在,我有enum一个玩家能够前往的方向,目前包含北,南,东,西,上和下.
我有一个Room课程,其中包含Map其他连通房间及其方向.当我在某个时候添加Room到另一个Room时Direction,我希望能够在相反的方向上将电流添加Room到另一个.Room
例如:如果我将房间1到房间2的连接添加到北方,我希望能够同时从房间2到房间1添加连接.
目前,我正在尝试使用带有附加实例变量(类型)的enum命名来实现它.这是不允许的?我没有得到编译器错误或任何东西,但我似乎无法让它工作.DirectionoppositeDirection
这是完整的enum声明:
public enum Direction {
North(South), South(North), East(West), West(East), Up(Down), Down(Up)
private Direction opposite
Direction(Direction d){
opposite = d
}
public opposite(){
return opposite
}
}
Run Code Online (Sandbox Code Playgroud)
这是我从以下方法调用它的方法:
public void addConnection(Direction d, Spot spot){
connections[d] = spot
spot.connections[d.opposite()] = this
}
Run Code Online (Sandbox Code Playgroud)
这里connections是一个public Map<Direction, Spot>.
在这种情况下,会添加一个条目connections,如下所示:
null:Spot@some_hexadecimal_representation
Run Code Online (Sandbox Code Playgroud)
任何帮助都会很棒.谢谢!
Groovy似乎绕过Java中的编译错误:
Main.java:2: illegal forward reference
North(South), South(North), East(West), West(East), Up(Down), Down(Up);
^
Main.java:2: illegal forward reference
North(South), South(North), East(West), West(East), Up(Down), Down(Up);
^
Main.java:2: illegal forward reference
North(South), South(North), East(West), West(East), Up(Down), Down(Up);
^
3 errors
Run Code Online (Sandbox Code Playgroud)
groovy编译器不会抱怨,但初始化需要前向声明的枚举值为null:
public enum Direction {
North(South), South(North), East(West), West(East), Up(Down), Down(Up)
Direction(Direction d){
println "opposite of $this is $d"
}
}
Direction.South // Force enum instantiation in GroovyConsole.
Run Code Online (Sandbox Code Playgroud)
产出:
opposite of North is null
opposite of South is North
opposite of East is null
opposite of West is East
opposite of Up is null
opposite of Down is Up
Run Code Online (Sandbox Code Playgroud)
一个似乎在Java中运行良好的解决方案是在类上添加一个static块Direction来初始化opposite值.转换为Groovy,即:
enum Direction {
North, South, East, West, Up, Down
private Direction opposite
Direction getOpposite() { opposite }
static {
def opposites = { d1, d2 -> d1.opposite = d2; d2.opposite = d1 }
opposites(North, South)
opposites(East, West)
opposites(Up, Down)
}
}
Direction.values().each {
println "opposite of $it is $it.opposite"
}
Run Code Online (Sandbox Code Playgroud)
现在打印正确的值:
opposite of North is South
opposite of South is North
opposite of East is West
opposite of West is East
opposite of Up is Down
opposite of Down is Up
Run Code Online (Sandbox Code Playgroud)
另一个可能更简单的解决方案是使用枚举上的方向索引来查找对立面:
public enum Direction {
North(1), South(0), East(3), West(2), Up(5), Down(4)
private oppositeIndex
Direction getOpposite() {
values()[oppositeIndex]
}
Direction(oppositeIndex) {
this.oppositeIndex = oppositeIndex
}
}
Run Code Online (Sandbox Code Playgroud)
但我发现第一个更清晰,因为它不需要索引的那些神奇数字呵呵.
现在,我可能会在这里进入高尔夫球场,但是你可以在不需要额外场的情况下获得相反的方向,只需使用枚举值' ordinal()(它们的索引):
enum Direction {
North, South, East, West, Up, Down
Direction getOpposite() {
values()[ordinal() + ordinal() % 2 * -2 + 1]
}
}
Run Code Online (Sandbox Code Playgroud)
它并不像它看起来那么可怕!偶数方向(北,东,上)返回方向ordinal() + 1为相反方向,而奇数方向(其他方向)则返回方向ordinal() - 1.当然,它在很大程度上依赖于枚举中元素的顺序,但是,你不喜欢简洁吗?= d