124 lines
3.0 KiB
Java
124 lines
3.0 KiB
Java
package chess.model.rules;
|
|
|
|
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;
|
|
|
|
/**
|
|
* Check if a move can be done.
|
|
*/
|
|
|
|
public class PermissiveRuleChecker implements PieceVisitor<Boolean> {
|
|
|
|
private final Move move;
|
|
|
|
public PermissiveRuleChecker(Move move) {
|
|
this.move = move;
|
|
assert move.isValid() : "Move is invalid!";
|
|
}
|
|
|
|
public boolean isValidFor(Piece piece) {
|
|
return visit(piece);
|
|
}
|
|
|
|
@Override
|
|
public Boolean visitPiece(Bishop bishop) {
|
|
Direction moveDirection = Direction.findDirection(this.move);
|
|
|
|
switch (moveDirection) {
|
|
case FrontLeft:
|
|
case BackLeft:
|
|
case FrontRight:
|
|
case BackRight:
|
|
return true;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Boolean visitPiece(King king) {
|
|
return this.move.traversedCells() == 1;
|
|
}
|
|
|
|
@Override
|
|
public Boolean visitPiece(Knight knight) {
|
|
Coordinate piecePos = move.getStart();
|
|
final Coordinate[] positions = {
|
|
new Coordinate(piecePos.getX() - 1, piecePos.getY() - 2),
|
|
new Coordinate(piecePos.getX() - 1, piecePos.getY() + 2),
|
|
new Coordinate(piecePos.getX() + 1, piecePos.getY() - 2),
|
|
new Coordinate(piecePos.getX() + 1, piecePos.getY() + 2),
|
|
new Coordinate(piecePos.getX() + 2, piecePos.getY() - 1),
|
|
new Coordinate(piecePos.getX() + 2, piecePos.getY() + 1),
|
|
new Coordinate(piecePos.getX() - 2, piecePos.getY() - 1),
|
|
new Coordinate(piecePos.getX() - 2, piecePos.getY() + 1),
|
|
};
|
|
|
|
for (int i = 0; i < positions.length; i++) {
|
|
if (this.move.getFinish().equals(positions[i]))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public Boolean visitPiece(Pawn pawn) {
|
|
Direction moveDirection = Direction.findDirection(this.move);
|
|
int directionIndexOffset = moveDirection.getIndexOffset();
|
|
int distance = this.move.traversedCells();
|
|
|
|
// Revoke moving backwards
|
|
if (directionIndexOffset * pawn.multiplier() > 0)
|
|
return false;
|
|
|
|
// Allowing straight moves
|
|
if (Math.abs(directionIndexOffset) == Math.abs(Direction.Front.getIndexOffset())) {
|
|
if (pawn.hasMoved())
|
|
return distance == 1;
|
|
return distance == 1 || distance == 2;
|
|
}
|
|
|
|
// Allowing small diagonal moves
|
|
if (directionIndexOffset * pawn.multiplier() == Direction.FrontLeft.getIndexOffset()
|
|
|| directionIndexOffset * pawn.multiplier() == Direction.FrontRight.getIndexOffset()) {
|
|
return distance == 1;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public Boolean visitPiece(Queen queen) {
|
|
Direction moveDirection = Direction.findDirection(this.move);
|
|
return moveDirection != Direction.Unset;
|
|
}
|
|
|
|
@Override
|
|
public Boolean visitPiece(Rook rook) {
|
|
Direction moveDirection = Direction.findDirection(this.move);
|
|
|
|
switch (moveDirection) {
|
|
case Front:
|
|
case Back:
|
|
case Left:
|
|
case Right:
|
|
return true;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
}
|