Java 如何对法律行动进行硬编码以实现快速查找?

Java 如何对法律行动进行硬编码以实现快速查找?,java,arrays,lookup,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);

我已经创建了一个游戏板(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]);
我面临的第一个问题是,我不知道如何将可能的移动列表放入数组中,例如索引[0][0]。这一定是相当明显的,但我在这方面停留了一段时间。我想创建一个数组,其中有一个点对象列表。所以在半代码中:
legalMoves[0][0]={Point(1,1),Point(0,1),Point(1,0)}
我不确定这是否有效,但它在逻辑上比[[1,1]、[0,1]、[1,0]]更合理,但我不相信这一点

第二个问题是,我宁愿从磁盘读取对象,而不是在每次游戏开始时使用实例变量legalMoves创建对象。我认为这样应该更快一些?serializable类是一条出路吗

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

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

由于电路板是二维的,并且合法移动的数量通常可能不止一个,因此最终将得到一个三维数据结构:

Point legalMoves[][][] = new legalMoves[5][5][];
legalMoves[0][0] = new Point[] {Point(1,1),Point(0,1),Point(1,0)};
我宁愿从磁盘读取对象,而不是在游戏开始时使用实例变量
legalMoves
创建对象。我认为这样应该更快一些?serializable类是一条出路吗

没有分析就无法回答这一问题。我无法想象,计算5x5电路板的任何形式的合法移动都会在计算上如此激烈,以至于需要任何形式的额外I/O操作

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


使用上面描述的3D“锯齿阵列”可以很好地处理这一问题,因此这根本不是问题。

您正在寻找一种结构,它将为您提供给定点的候选结构,即
点->列表

通常,我会选择
地图

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

// (-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
包含
点的实际邻居,该点具有计算、存储和返回这些邻居的函数。您可以选择一次初始化所有邻居,但考虑到数字较小,我不认为这是性能方面的问题

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;
}

注意:类
Point
必须定义
equals()
hashCode()
,贴图才能按预期运行。

如何计算合法移动?也许你试图做的是不必要的过早优化。游戏板是不平衡的。它来自游戏BagChal,在游戏中你可以水平和垂直移动,但不一定是对角移动。看起来,如果x或y坐标中的差不止一个,或者如果新点具有负坐标,那么它将是非法的,否则它是合法的。编辑:同样,如果坐标是奇数行和偶数列,那么你就不能沿对角线移动。对@NeplatnyUdaj,这明显带有过早优化的味道。像
mapFromPointToSetOfLegalDestinations
这样的东西是你要找的吗?3D数组可以工作,或者你可以实现
点列表的2D数组
s@mstbaum正确的,列表也可以工作,只要在foreach循环中使用是合法的,
static boolean isLegalMove(Point from, Point to) {
    boolean legal = false;
    for (Point p : getNeighbours(from)) {
        if (p.equals(to)) {
            legal = true;
            break;
        }
    }
    return legal;
}