小编典典

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

java

我正在画一个国际象棋骑士的可能路径,一种情况是这样的:

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

但是我不知道如果没有必要怎么做。至少有一种聪明的方法吗?


阅读 193

收藏
2020-11-26

共1个答案

小编典典

您可以创建一个Vector类或类似的类(或使用任何类似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个循环和1个条件循环。 ,±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(保持简单,愚蠢)路线并简单地写下所有可能的动作是有利的。目的很明显,行数相同(并且您不必想出巧妙的方法来“计算”移动)。

2020-11-26