当前位置: 首页 > 面试题库 >

如何实现连通房?

经伟
2023-03-14
问题内容

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

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

我应该使用哪种数据结构,或者应该如何尽可能高效地实现呢?


问题答案:

首先要确定什么是有效方向:它是来自固定列表还是自由格式的文本?最简单的解决方案是具有四个基本方向。有人建议将其作为int数组来进行。在C / C ++ /
C#中,这可能是一个有效的html" target="_blank">解决方案(所有枚举都只是int常量),但是在Java中没有理由这样做。

在Java中,你可以使用(类型安全)枚举这亦可以有状态和行为,和使用EnumMap,这是
非常
有效的。在内部,它只是一个按枚举序号索引的数组。您可能会争辩说那和int数组有什么区别?答案是,内部的int数组EnumMap是类型安全随机访问集合的内部实现细节。

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

Map<String, Direction> exits;

我不建议这样做。我建议列举可能的方向:

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

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

  • 坐(动词=坐);
  • 开门(动词=打开,object1 =门)
  • 看书
  • 用铁钥匙锁住箱子(动词=锁,对象1 =箱子,介词2 =带有,对象2 =铁钥匙);
  • 向兽人投掷火球;
  • 等等

因此,以上内容涵盖了相当全面的行为。所有这些的要点是:

  • 出口将支持许多动词或命令(例如,您可以打开/关闭门,但不能打开/关闭通道);
  • 怪物和物品也将支持命令(可以“挥动”魔杖,可以“击打”兽人);
  • 出口,怪物和物品就是所有类型的对象(游戏中可以通过某种方式进行交互的事物)。

所以:

public enum Command { LOOK, HIT, WAVE, OPEN, CLOSE, ... };

(毫无疑问将与这些实例相关联的行为)并且:

public class GameObject {
  boolean isSupported(Command command);
  boolean trigger(Command command);
}

public class Exit extends GameObject {
  ...
}

游戏对象也可能具有其他状态,例如是否可以看到它们。有趣的是,Direction枚举实例也可以说是Commands,它再次更改了抽象。

因此,希望可以帮助您指出正确的方向。没有抽象的“正确”答案,因为这完全取决于您需要建模和支持的内容。希望这可以给您一个起点。



 类似资料:
  • import scala.reflect.ClassTag import org.apache.spark.graphx._ /** Connected components algorithm. */ object ConnectedComponents { /** * Compute the connected component membership of each vertex

  • 因此,我尝试将插入排序与必须传入的通用比较器一起使用。我无法更改方法名称。我如何实现一个比较器来传递到insertionSort方法中?我是java和面向对象编程的新手。 该测试只是一个junit测试。

  • 比如我现在有两个表,结构分别为: 如果我现在操作修改 表A 中的数据,比如 id: 2 所在对象改为 { id: 2, name: 'dd' } 请问 mongo 是否可以在修改 表A 的同时修改 表B 中所有人物的 array 中的 id: 2 所在项 我现在能想到的就是笨办法就是改完 表A 之后嵌套遍历 表B,在通过匹配逐一修改,但我感觉这样做既没有效率也够笨重 还望指点,谢谢!

  • 问题内容: 如何构建一个Android应用程序以启动A 以使用,以便在修改观察到的目录(即用户拍照)后执行其他代码。调试时,永远不会触发onEvent方法。 这是我在服务中遇到的onStart事件。在对火灾“我的服务开始......” 但是在那次Toast之后,如果我拍照,则onEvent永远不会触发。这是通过调试确定的。它永远不会碰到那个断点,而Toast也不会触发。 浏览该目录后,新图像将保存

  • 在Eclipse中运行RESTful客户端时,出现以下错误: 在浏览器中调用时,URL不会被阻止。如何通过客户端使用它? TIA! 编辑:(客户端代码)

  • 我正在用python制作一个连接4 AI,并且我正在使用带有迭代深化和alpha beta修剪的minimax。对于更深的深度,它仍然很慢,所以我想实现一个换位表。阅读后,我想我得到了大致的想法,但我无法完全使其工作。这是我代码的一部分:(最小最大值的最大化部分): 现在我用zobrist散列方法散列板,我使用有序的判决将散列板添加到。在这个哈希键中,我添加了板的值和该板的最佳移动。不幸的是,这似