Java 如何实现互联房间?
这可能是一个重复的问题,因为我不知道搜索查询的词组。我正在用Java创建一个类似Zork的基于文本的游戏,角色移动到相互连接的不同房间。我想能够列出一个球员在这个房间里的所有选择 例如,房间A东与B相连,B西与A相连,南与C相连,北与D相连,依此类推Java 如何实现互联房间?,java,data-structures,Java,Data Structures,这可能是一个重复的问题,因为我不知道搜索查询的词组。我正在用Java创建一个类似Zork的基于文本的游戏,角色移动到相互连接的不同房间。我想能够列出一个球员在这个房间里的所有选择 例如,房间A东与B相连,B西与A相连,南与C相连,北与D相连,依此类推 我应该使用什么样的数据结构,或者我应该如何尽可能有效地实现这一点?一个房间数组,每个房间都有一个出口列表,并参考它所指向的房间。您可以使用一个数组来实现这一点: class Room { private Room[] exits = new
我应该使用什么样的数据结构,或者我应该如何尽可能有效地实现这一点?一个房间数组,每个房间都有一个出口列表,并参考它所指向的房间。您可以使用一个数组来实现这一点:
class Room {
private Room[] exits = new Room[4];
}
在本例中,出口[0]
可能包含对北面房间的引用,出口[1]
房间东面的引用,依此类推。如果元素包含null
,则可能表示该方向没有出口
请注意,您可以使用此方法创建非线性数据结构,例如A->B->C->A。您可以将房间对象存储在列表、集合或(如Lars D所建议的)数组中 在房间内,我认为存储出口的一个好方法(考虑到它们可能不是4个基本方向)是在地图中,用枚举表示方向,用相邻房间作为值
这在存储空间上非常有效,而且应该足够快地导航。首先要确定什么是有效的方向:它是来自固定列表还是自由格式的文本?最简单的解决方案是有四个基本方向。有些人建议将其作为int数组。这在C/C++/C#中可能是一个有效的解决方案(它们中的枚举都只是int常量),但在Java中没有理由这样做 在Java中,您可以使用(typesafe)枚举,顺便说一句,它可以具有状态和行为,还可以使用非常高效的。在内部,它只是一个由枚举序数值索引的数组。您可能会争论它与int数组之间的区别是什么?答案是
EnumMap
中的int数组是类型安全随机访问集合的内部实现细节
如果允许自由形式文本作为退出方向,则结构将如下所示:
Map<String, Direction> exits;
这至少是一种可能性。例如:
- 坐(动词=坐)李>
- 打开门(动词=打开,对象1=门)
- 看看书李>
- 用铁钥匙锁上箱子(动词=锁,对象1=箱子,介词2=带,对象2=铁钥匙)李>
- 向兽人投掷火球李>
- 等等
- 出口将支持许多动词或命令(例如,您可以打开/关闭门,但不能打开/关闭通道)李>
- 怪物和物品也支持命令(魔杖可以“挥动”,兽人可以“命中”)李>
- 出口、怪物和物品都是所有类型的物品(游戏中可以以某种方式进行交互的物品)
所以希望这能帮你找到正确的方向。抽象没有“正确”的答案,因为它完全取决于您需要建模和支持什么。然而,这应该给你一个起点。当我看到这个问题时,首先想到的是制作一个图形数据结构,但是阅读这些其他评论,一个地图可能要好得多。图表太复杂了 使用适当的图形库将比这里的大多数映射方法更强大、更灵活。Jung库()在Java中提供了许多基于图形的功能。虽然它看起来有点复杂,但从长远来看,它可能是值得投入时间的。在我看来,您需要一种称为多重映射的数据结构 这是一个类似于散列的集合,但其中的键可以有多个值。Java中没有这样一个集合,但它可以通过使用一个具有两个级别的普通集合来轻松构建:在映射中存储列表。钥匙是门的唯一标记,列表包含门连接的所有房间。通常只有两个房间,但门可能有某种程度的魔力 大致相同的事情是拥有自己的类门,其中包含您想要的任何内容,以及对两个连接房间的引用。然后,这只需要法线贴图 在任何一种情况下,Room类中都只有可以在集合中查找的门键
当然,您可以将房间的拓扑直接放入房间对象中,使门结构直接引用其他房间,但我怀疑门将具有其自身的状态(打开、关闭、锁定等),并且在任何情况下,您都有一个鸡和蛋的问题,即如何首先创建所有这些链接。使用图书馆藏品可以解决所有这些问题。使用地图还可以存储一些非标准方向,如进站、出站、坠落等。-1这是一种糟糕且过于简单的表示方式。它使用字符串和int常量。至少使用EnumMap和方向枚举。即使如此,除了最基本的示例之外,它还不足以满足所有的需求。我建议您看看EnumMap的实现。它可能“糟糕且过于简单”,但也很简单且易于理解。从OP的问题来看,最终效率似乎不是这里的主要目标,而是理解可能涉及的数据结构。我提供了一个选项。@Greg:这样的数组在C#中可能有意义,因为枚举只是int,所以数组是一个自然选择,但在Java枚举中是这样的
public enum Direction {
NORTH("north", "n"),
NORTHWEST("northwest", "nw"),
...
IN("in"),
OUT("out");
private final static Map<String, Direction> INSTANCES;
static {
Map<String, Direction> map = new HashMap<String, Direction>();
for (Direction direction : values()) {
for (String exit : direction.exits) {
if (map.containsKey(exit)) {
throw new IllegalStateException("Exit '" + exit + "' duplicated");
}
map.put(exit, direction);
}
}
INSTANCES = Collections.unmodifiableMap(map);
}
private final List<String> exits;
Direction(String... exits) {
this.exits = Collections.unmodifiableList(Arrays.asList(exits));
}
public List<String> getExits() { return exits; }
public String getName() { return exits.get(0); }
public static Map<String, Direction> getInstances() { return INSTANCES; }
public static Direction getDirection(String exit) { return INSTANCES.get(exit); }
}
private final Map<Direction, Exit> exits =
new EnumMap<Direction, Exit>(Direction.class);
Map<String, Room> exits;
Verb [[preposition1] object1 [[preposition2] object2]]
public enum Command { LOOK, HIT, WAVE, OPEN, CLOSE, ... };
public class GameObject {
boolean isSupported(Command command);
boolean trigger(Command command);
}
public class Exit extends GameObject {
...
}