如何对快速查找的合法动作进行硬编码?

时间:2015-03-09 14:47:25

标签: java arrays lookup

我创建了一个游戏板(5x5),我现在想要尽可能快地决定移动是否合法。例如,(0,0)的一块想要去(1,1),那是合法的吗?首先,我试图通过计算找到它,但这看起来很麻烦。我想基于棋盘上的位置对可能的移动进行硬编码,然后遍历所有可能的移动以查看它们是否与棋子的目的地匹配。我在纸上得到这个问题。这就是我想要的:

//game piece is at 0,0 now, decide if 1,1 is legal
Point destination = new Point(1,1);     
destination.findIn(legalMoves[0][0]);

我面临的第一个问题是我不知道如何在数组中放置可能的移动列表,例如index [0] [0]。这必须是相当明显的,但我坚持了一段时间。我想创建一个数组,其中有一个Point对象列表。所以在半码中:legalMoves[0][0] = {Point(1,1),Point(0,1),Point(1,0)} 我不确定这是否有效但它在逻辑上有意义而不是[[1,1],[0,1],[1,0]],但我不会在此出售。

我遇到的第二个问题是,不是在游戏的每个开始时使用实例变量legalMoves创建对象,我宁愿让它从磁盘读取。我认为这样应该更快?可序列化类是可行的吗?

我的第三个小问题是,对于25个职位,法律行动是不平衡的。有些人有8个可能的法律行动,有些人有3个。也许这根本不是问题。

2 个答案:

答案 0 :(得分:1)

  

我面临的第一个问题是我不知道如何在数组中放置可能的移动列表,例如索引[0][0]

由于电路板是2D的,并且合法移动的数量通常可以多于一个,因此最终会得到一个3D数据结构:

Point legalMoves[][][] = new legalMoves[5][5][];
legalMoves[0][0] = new Point[] {Point(1,1),Point(0,1),Point(1,0)};
  

而不是在每次使用实例变量legalMoves的游戏开始时创建对象,我宁愿让它从磁盘读取。我认为这样应该更快?可序列化类是可行的吗?

如果没有分析,这是无法回答的。我无法想象5x5电路板的任何计算合法移动在计算上都是如此强烈,以至于证明任何类型的额外I / O操作都是合理的。

  对于25个职位,法律行动是不平衡的。有些人有8个可能的法律行动,有些人有3个。也许这根本不是问题。

这可以通过上面描述的3D“锯齿状阵列”很好地处理,所以它根本不是问题。

答案 1 :(得分:1)

您正在寻找能够为您提供给定点的候选人的结构,即Point -> List<Point>

通常,我会选择Map<Point, List<Point>>

您可以在程序启动时静态初始化此结构,也可以在需要时动态初始化。例如,在这里我使用2个辅助数组,其中包含一个点的可能翻译,这些将产生该点的邻居

// (-1  1) (0  1) (1  1)
// (-1  0) (----) (1  0)
// (-1 -1) (0 -1) (1 -1)
// from (1 0) anti-clockwise:
static int[] xOffset = {1,1,0,-1,-1,-1,0,1};
static int[] yOffset = {0,1,1,1,0,-1,-1,-1};

以下Map包含Point的实际邻居,其中包含计算,存储和返回这些邻居的函数。您可以选择在一次通过中初始化所有邻居,但是如果数量较少,我认为这不是一个性能问题。

static Map<Point, List<Point>> neighbours = new HashMap<>();

static List<Point> getNeighbours(Point a) {
    List<Point> nb = neighbours.get(a);
    if (nb == null) {
        nb = new ArrayList<>(xOffset.length); // size the list
        for (int i=0; i < xOffset.length; i++) {
            int x = a.getX() + xOffset[i];
            int y = a.getY() + yOffset[i];
            if (x>=0 && y>=0 && x < 5 && y < 5) {
                nb.add(new Point(x, y));
            }
        }
        neighbours.put(a, nb);
    }
    return nb;
}

现在检查合法行动是在邻居中找到要点的问题:

static boolean isLegalMove(Point from, Point to) {
    boolean legal = false;
    for (Point p : getNeighbours(from)) {
        if (p.equals(to)) {
            legal = true;
            break;
        }
    }
    return legal;
}

注意:课程Point必须定义equals()hashCode()才能让地图按预期行事。