I have the following portion of ugly (but working) code for checking if fields on a chessboard are vacant:
if (abs(xDst - xSrc) == abs(yDst - ySrc)) {
boolean backslashMove = xSrc < xDst && ySrc > yDst || xSrc > xDst && ySrc < yDst;
if (backslashMove) {
int y = max(ySrc, yDst) - 1;
for (int x = min(xSrc, xDst) + 1; x < max(xSrc, xDst); x++) {
if (board.getActiveChessmanAt(x, y).isAlive()) {
return false;
}
y--;
}
} else { //slash move
Obviously, it examines fields between coordinates (xScr, ySrc) and (xDst, yDst) in Bishop-like line of move.
I'm trying to transform this with using IntStream:
if (backslashMove) {
final int y = max(ySrc, yDst) - 1;
if (IntStream.range(min(xSrc, xDst) + 1, max(xSrc, xDst))
.anyMatch(x -> board.getActiveChessmanAt(x, y).isAlive()))
return false;
How can I perform y-- in this case? It has to be final if it's about to be used within 'anyMatch' command
If you really need to rewrite it using streams, then you can use the fact that both x
and y
are incremented simultaneously. So you can build a range of increments instead of the range of x-values:
final int xSrc = min(xSrc, xDst) + 1;
final int xDst = max(xSrc, xDst);
final int ySrc = max(ySrc, yDst) - 1;
if (IntStream.range(0, xDst - xSrc)
.anyMatch(distance -> board.getActiveChessmanAt(xSrc + distance, ySrc + distance).isAlive())) {
return false;
}
In general, it's not possible to use a non-final local variable from the "parent" method directly. Java doesn't support real closures. You would need a wrapper object for this (AtomicInteger
is an often suggested candidate), or you could make the non-final variable a class field (note the potential thread safety problems). To me personally, these both "tricks" are bad.