我正在画一个国际象棋骑士的可能路径,一种情况是这样的:
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类或类似的类(或使用任何类似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(保持简单,愚蠢)路线并简单地写下所有可能的动作是有利的。目的很明显,行数相同(并且您不必想出巧妙的方法来“计算”移动)。