120 lines
3.2 KiB
Java
120 lines
3.2 KiB
Java
package chess.model.visitor;
|
|
|
|
import chess.model.ChessBoard;
|
|
import chess.model.Color;
|
|
import chess.model.Coordinate;
|
|
import chess.model.Direction;
|
|
import chess.model.Move;
|
|
import chess.model.Piece;
|
|
import chess.model.PieceVisitor;
|
|
import chess.model.pieces.Bishop;
|
|
import chess.model.pieces.King;
|
|
import chess.model.pieces.Knight;
|
|
import chess.model.pieces.Pawn;
|
|
import chess.model.pieces.Queen;
|
|
import chess.model.pieces.Rook;
|
|
|
|
public class PiecePathChecker implements PieceVisitor<Boolean> {
|
|
|
|
private final ChessBoard board;
|
|
private final Move move;
|
|
|
|
public PiecePathChecker(ChessBoard board, Move move) {
|
|
this.move = move;
|
|
this.board = board;
|
|
}
|
|
|
|
public boolean isValid() {
|
|
if (this.move.getStart().equals(this.move.getFinish()))
|
|
return false;
|
|
Piece piece = this.board.pieceAt(move.getStart());
|
|
if (piece == null)
|
|
return false;
|
|
return visit(piece);
|
|
}
|
|
|
|
@Override
|
|
public Boolean visitPiece(Bishop bishop) {
|
|
if (!new PermissiveRuleChecker(this.move).isValidFor(bishop))
|
|
return false;
|
|
return testPath(bishop.getColor());
|
|
}
|
|
|
|
@Override
|
|
public Boolean visitPiece(King king) {
|
|
if (!new PermissiveRuleChecker(this.move).isValidFor(king))
|
|
return false;
|
|
|
|
Piece destPiece = board.pieceAt(this.move.getFinish());
|
|
if (destPiece == null)
|
|
return true;
|
|
return destPiece.getColor() != king.getColor();
|
|
}
|
|
|
|
@Override
|
|
public Boolean visitPiece(Knight knight) {
|
|
if (!new PermissiveRuleChecker(this.move).isValidFor(knight))
|
|
return false;
|
|
|
|
Piece destPiece = board.pieceAt(this.move.getFinish());
|
|
if (destPiece == null)
|
|
return true;
|
|
return destPiece.getColor() != knight.getColor();
|
|
}
|
|
|
|
@Override
|
|
public Boolean visitPiece(Pawn pawn) {
|
|
if (!new PermissiveRuleChecker(this.move).isValidFor(pawn))
|
|
return false;
|
|
|
|
Direction moveDirection = Direction.fromInt(Direction.findDirection(move).getIndexOffset() * pawn.multiplier());
|
|
|
|
if (moveDirection == Direction.Front)
|
|
return testPath(pawn.getColor()) && this.board.pieceAt(this.move.getFinish()) == null;
|
|
|
|
assert moveDirection == Direction.FrontLeft || moveDirection == Direction.FrontRight;
|
|
|
|
Piece destPiece = this.board.pieceAt(this.move.getFinish());
|
|
if (destPiece == null)
|
|
return false;
|
|
|
|
return destPiece.getColor() != pawn.getColor();
|
|
}
|
|
|
|
@Override
|
|
public Boolean visitPiece(Queen queen) {
|
|
if (!new PermissiveRuleChecker(this.move).isValidFor(queen))
|
|
return false;
|
|
return testPath(queen.getColor());
|
|
}
|
|
|
|
@Override
|
|
public Boolean visitPiece(Rook rook) {
|
|
if (!new PermissiveRuleChecker(this.move).isValidFor(rook))
|
|
return false;
|
|
return testPath(rook.getColor());
|
|
}
|
|
|
|
private boolean testPath(Color color) {
|
|
Direction moveDirection = Direction.findDirection(this.move);
|
|
int distance = this.move.traversedCells();
|
|
int stepIndex = move.getStart().toIndex();
|
|
|
|
for (int step = 0; step < distance; step++) {
|
|
stepIndex += moveDirection.getIndexOffset();
|
|
|
|
if (Coordinate.fromIndex(stepIndex).equals(move.getFinish())) {
|
|
Piece pieceDest = this.board.pieceAt(move.getFinish());
|
|
if (pieceDest == null)
|
|
return true;
|
|
return pieceDest.getColor() != color;
|
|
}
|
|
|
|
if (!this.board.isCellEmpty(Coordinate.fromIndex(stepIndex)))
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|