如何使用所有可能的对 (+- 1, +- 2) 组合进行循环

How to do for loop with all possible combinations of pairs (+- 1, +- 2)

我正在画一个骑士在国际象棋中的可能路径,其中一个例子是这样的:

if (boundsOK(x + 1, y + 2)) {
    temp = boardArray[x + 1][y + 2];

    if (isLegalMove(x, y, x + 1, y + 2) != MoveType.NONE) {
        moves.add(x);
        moves.add(y);
        moves.add(x + 1);
        moves.add(y + 2);

        move(x + 1, y + 2, x, y);
    }
    boardArray[x + 1][y + 2] = temp;
}

现在我想构造一个循环来尝试组合,而不是 1 和 2:

 1  2

-1  2

 1 -2

-1 -2


 2  1

-2  1

 2 -1

-2 -1

但我不知道如何在没有不必要的情况下做到这一点。至少有一个聪明的方法吗?

您可以创建一个 Vector class 或类似的(或使用任何类似 Pair 的类型),用您的值填充一个列表并对其进行迭代(无需过多考虑性能):

var moves = List.of(
        new Move(1,2),
        new Move(-1,2),
        new Move(1,-2),
        new Move(-1,-2),
        new Move(2,1),
        new Move(-2,1),
        new Move(2,-1),
        new Move(-2,-1));

for (var move : moves) {
    var x = move.getX();
    var y = move.getY();
    testMove(x, y) … // or refactor your method to receive a Move instance directly
}

如果您真的想节省一些行数(您在打高尔夫球吗?),您可以使用循环创建实例,但这并不能真正使代码更好(无论是从可读性的角度,还是从性能,也不是来自要键入的字符数):

var moves = new ArrayList<Move>();
for (int x : List.of(1,-1)) {
    for (int y : List.of(2,-2)) {
        moves.add(new Move(x,y));
    }
}
for (int x : List.of(2,-2)) {
    for (int y : List.of(1,-1)) {
        moves.add(new Move(x,y));
    }
}

再想一想,如果我们注意到移动总是必须包含数字 1 和 2 并且从来没有移动 (±1,±1 ) 或 (±2,±2):

var moves = new ArrayList<Move>(8);
var offsets = List.of(-2,-1,1,2);
for (int x : offsets) {
    for (int y : offsets) {
        if (Math.abs(x) != Math.abs(y)) {
            moves.add(new Move(x,y));
        }
    }
}

但是,我仍然认为走 KISS(保持简单,愚蠢)路线并简单地写出所有可能的动作是有利的。意图很明确,行数大致相同(而且您不必想出巧妙的方法来 "compute" 移动)。