如何使用所有可能的对 (+- 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" 移动)。
我正在画一个骑士在国际象棋中的可能路径,其中一个例子是这样的:
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" 移动)。