我有以下丑陋(但正在工作)的代码,用于检查棋盘上的字段是否空置:
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
显然,它会在类似Bishop的移动线中检查坐标(xScr,ySrc)和(xDst,yDst)之间的字段。
我正在尝试使用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;
在这种情况下,我该如何表演?如果要在'anyMatch'命令中使用它必须是最终的
答案 0 :(得分:1)
如果确实需要使用流重写它,那么您可以使用x
和y
同时递增的事实。因此,您可以构建一系列增量而不是x值范围:
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;
}
一般情况下,无法使用&#34; parent&#34;中的非最终本地变量。方法直接。 Java不支持真正的闭包。你需要一个包装器对象(AtomicInteger
是一个经常被建议的候选者),或者你可以使非final变量成为一个类字段(注意潜在的线程安全问题)。就我个人而言,这两个&#34;技巧&#34;很糟糕
答案 1 :(得分:1)
您需要的不是流/折叠方面的函数式编程 而不是,你应该重构你的实际代码,使其更清晰/更短/更好。
你可以举例如:
使用有意义的名称提取实际方法中分散的逻辑部分
使用结构化对象而不是太精细的单一变量
删除不需要的嵌套:使用提前退出并且不需要条件语句可能有帮助
它可以给:
// -> extract method + structured objects
if (!isPointsMatch(pointSrc, pointDst)) {
return false; // -> early exit
}
// -> extract method + structured objects
if (isBackslashMove(pointSrc, pointDst)) {
if (board.hasAnyActiveChessmanAlive(pointSrc, pointDst)) {
return false;
}
}
// else slash move -> The else is useless
// ...
答案 2 :(得分:0)
您剪切的原始代码是程序。您的功能方法效果不佳。那么面向对象的方法呢?
class Position{
private final int x, y;
public Position(int x, int y){
this.x=x;
this.y=y;
}
public getX(){
return x;
}
public getY(){
return y;
}
}
interface Move {
Position moveFrom(Position start);
}
interface Figure {
Collection<Move> getPossibleMoves(Position start, Board board);
}
class Bishop implements Figure {
private final Collection<Move> moves = new HashSet<>();
public Bishop(){
moves.add(start->new Position(start.getX()-2,start.getY()-1));
moves.add(start->new Position(start.getX()-2,start.getY()+1));
moves.add(start->new Position(start.getX()+2,start.getY()-1));
moves.add(start->new Position(start.getX()+2,start.getY()+1));
moves.add(start->new Position(start.getX()-1,start.getY()-2));
moves.add(start->new Position(start.getX()-1,start.getY()+2));
moves.add(start->new Position(start.getX()+1,start.getY()-2));
moves.add(start->new Position(start.getX()+1,start.getY()+2));
}
@Override
public Collection<Move> getPossibleMoves(Position start, Board board){
return moves.stream()
.filter({ Position end = m.moveFrom(start);
return board.isOnBorad(end.getX(),end.getY())
&& board.getActiveChessmanAt(end.getX(), end.getY()).isAlive()})
.collect(Collectors.toSet());
}
}
Figure
的另一个实现可能会为每个步骤返回一个单独的Move
实例,直到达到限制为止:
class Tower implements Figure {
enum Direction {
NORTH(1,0),EAST(0,1),SOUTH(-1,0),WEST(0,-1);
private final Position change;
private Direction(int x, int y){
change = new Position(x, y);
}
public Position getNextFrom(Position start){
return new Position(start.getX()+change.getX(),start.getX()+change.getY());
}
@Override
public Collection<Move> getPossibleMoves(Position start, Board board){
Collection<Move> moves = new HashSet<>();
for(Direction direction : Direction.values()){
Position current = direction.getNextFrom(start);
while( board.isOnBorad(current.getX(),current.getY())
&& board.getActiveChessmanAt(current.getX(), current.getY()).isAlive()){
moves.add(p-> new Position(current.getX(),current.getY());
}
}
return moves;
}
}