首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何实现房间互通?

如何实现房间互通?
EN

Stack Overflow用户
提问于 2009-11-08 03:16:50
回答 7查看 4.6K关注 0票数 2

这可能是一个重复的问题,因为我不知道如何表达搜索查询。我正在用Java创建一个类似Zork的基于文本的游戏,其中角色移动到相互连接的不同房间。我希望能够列出玩家可用于此房间的所有选项。

例如,房间A向东连接到B,B向西连接到A,向南连接到C,向北连接到D,依此类推。

我应该使用什么数据结构,或者我应该如何尽可能高效地实现它?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2009-11-08 03:25:19

首先要决定的是什么构成了一个有效的方向:它是来自固定的列表还是可以是自由格式的文本?最简单的解决方案是有四个基本方向。有些人建议使用int数组来执行此操作。这在C/C++/C#中可能是一个有效的解决方案(它们中的枚举都只是int常量),但在Java中没有理由这样做。

在Java语言中,你可以使用(类型安全)枚举--顺便说一下,枚举可以有状态和行为--还可以使用高效的EnumMap。在内部,它只是一个按枚举序数值索引的数组。你可能会问,这和整型数组有什么区别?答案是EnumMap中的整型数组是一个类型安全的随机访问集合的内部实现细节。

如果您允许自由格式的文本作为退出方向,您的结构将如下所示:

代码语言:javascript
复制
Map<String, Direction> exits;

不过,我并不推荐这样做。我建议列举可能的方向:

代码语言:javascript
复制
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); }
}

然后您可以使用以下命令进行存储:

代码语言:javascript
复制
private final Map<Direction, Exit> exits =
  new EnumMap<Direction, Exit>(Direction.class);

这为您提供了类型安全、性能和可扩展性。

考虑这一点的第一种方法是将其视为地图:

代码语言:javascript
复制
Map<String, Room> exits;

其中键是自由方向(北、东、南等)。

下一个问题:什么是出口?在最简单的情况下,出口只是你最终所在的房间,但然后你开始问各种各样的问题,比如:

  • 玩家可以看到出口吗?
  • 出口是关闭的还是打开的?
  • 出口可以关闭、打开、锁定、解锁、推开等吗?
  • 使用出口可以是程序性的(例如,你必须携带某种护身符)?
  • 你在哪里结束可以是程序性的(例如,你可以掉到陷阱里,在其他地方使用出口触发某种其他动作(例如,触发警报)?

有必要考虑一下文本冒险游戏的界面。玩家键入以下形式的命令:

代码语言:javascript
复制
Verb [[preposition1] object1 [[preposition2] object2]] 

这至少是一种可能性。示例包括:

  • sit (动词= sit);
  • open door (动词=打开,object1 =门)
  • 看书;
  • 用铁钥匙锁箱子(动词=锁,object1 =箱子,preposition2 =带,object2 =铁钥匙);
  • 在code投下火球

因此,上面的内容涵盖了一组相当全面的行为。所有这一切的意义在于:

Exits将支持许多动词或命令(例如,你可以打开/关闭一扇门,但不能打开/关闭passageway);

  • Monsters,物品也将支持命令(魔杖可以“挥舞”,兽人可以是怪物,物品可以是所有类型的物体(游戏中可以通过某种方式与之交互的东西)。

)

所以:

代码语言:javascript
复制
public enum Command { LOOK, HIT, WAVE, OPEN, CLOSE, ... };

(毫无疑问,会有与这些实例相关的行为)和:

代码语言:javascript
复制
public class GameObject {
  boolean isSupported(Command command);
  boolean trigger(Command command);
}

public class Exit extends GameObject {
  ...
}

GameObjects还可能具有其他状态,例如它们是否可见。有趣的是,Direction枚举实例也可以说是命令,这再次改变了抽象。

因此,希望这能为您指明正确的方向。抽象没有“正确”的答案,因为这完全取决于您需要建模和支持什么。然而,这将有望给你一个起点。

票数 16
EN

Stack Overflow用户

发布于 2009-11-08 03:20:30

一个房间数组,每个房间都有一个出口列表,参照它所指向的房间。

票数 1
EN

Stack Overflow用户

发布于 2009-11-08 03:23:24

您可以将您的Room对象存储在列表、集合或数组(如Lars D建议的那样)中。

在Room中,我认为存储出口(考虑到它们可能不只是4个基本方向)的一个好方法是在Map中,方向为Enum,相邻的Room为值。

这在存储空间上非常有效,而且导航速度也应该足够快。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1694101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档