/**All methods in this class assume an empty board */ public class Chessboard { public static final int SAME_HOR = 1, SAME_HOR_SEP = 2; public static final int SAME_VER = 3, SAME_VER_SEP = 4; public static final int SAME_DIAG = 5, SAME_DIAG_SEP = 6; public static final int SAME_KNIGHT_MOVE = 7, NOT_RELATED = 8; public static final int DIAG_SLASH = 9; //low left to upper right public static final int DIAG_BACKSLASH = 10; //upper left to lower right public static int relativeLocation(Square sq1, Square sq2) { if (sameVertical(sq1,sq2)) return SAME_VER; if (sameHorizontal(sq1,sq2)) return SAME_HOR; if (sameDiagonal(sq1,sq2)) return SAME_DIAG; if (sameKnightMove(sq1,sq2)) return SAME_KNIGHT_MOVE; return NOT_RELATED; } public static boolean sameVertical(Square sq1,Square sq2) { if (sq1.col == sq2.col && sq1.row != sq2.row) return true; else return false; } public static boolean sameHorizontal(Square sq1,Square sq2) { if (sq1.row == sq2.row && sq1.col != sq2.col) return true; else return false; } public static boolean sameDiagonal(Square sq1,Square sq2) { if (Math.abs(sq1.col - sq2.col) == Math.abs(sq1.row - sq2.row)) return true; else return false; } public static boolean sameKnightMove(Square sq1,Square sq2) { if ((Math.abs(sq1.col - sq2.col) == 2) && (Math.abs(sq1.row - sq2.row) == 1)) return true; if ((Math.abs(sq1.col - sq2.col) == 1) && (Math.abs(sq1.row - sq2.row) == 2)) return true; return false; } //same line (vertical/horizontal/diagonal)? public static boolean sameLine(Square sq1,Square sq2) { if (sq1.col == sq2.col && sq1.row != sq2.row) return true; //same vertical if (sq1.row == sq2.row && sq1.col != sq2.col) return true; //same horizontal if (Math.abs(sq1.col - sq2.col) == Math.abs(sq1.row - sq2.row)) return true; //same diagonal return false; } //is sq2 within attacking range of pawn owned by pawnOwner on sq1? //en passe doesn't count public static boolean withinPawnAttackingRange(Square sq1,Square sq2,String pawnOwner) { if (!sameDiagonal(sq1,sq2)) return false; if (diagonalLength(sq1,sq2) > 2) return false; if (pawnOwner.equals("white")) { // white pawn goes forward if (sq2.row > sq1.row) return true; } else { //black pawn goes backward if (sq2.row < sq1.row) return true; } return false; } //is sq2 within moving range of pawn owned by pawnOwner on sq1? //only pawn moves, captures don't count public static boolean withinPawnRange(Square sq1,Square sq2,String pawnOwner) { if (!sameVertical(sq1,sq2)) return false; int length = verticalLength(sq1,sq2); if (length > 3) return false; //a2-a4 length is 3 if (pawnOwner.equals("white")) { // white pawn goes forward if (sq2.row > sq1.row && length == 2) return true; if (sq2.row > sq1.row && length == 3 && sq1.row == 2) return true; } else { //black pawn goes backward if (sq2.row < sq1.row && length == 2) return true; if (sq2.row < sq1.row && length == 3 && sq1.row == 7) return true; } return false; } //same as sameKnightMove(); adduced here only for symmetry public static boolean withinKnightRange(Square sq1,Square sq2) { if ((Math.abs(sq1.col - sq2.col) == 2) && (Math.abs(sq1.row - sq2.row) == 1)) return true; if ((Math.abs(sq1.col - sq2.col) == 1) && (Math.abs(sq1.row - sq2.row) == 2)) return true; return false; } //same as sameDiagonal(); adduced here only for symmetry public static boolean withinBishopRange(Square sq1,Square sq2) { if (Math.abs(sq1.col - sq2.col) == Math.abs(sq1.row - sq2.row)) return true; else return false; } public static boolean withinRookRange(Square sq1,Square sq2) { if (sq1.col == sq2.col && sq1.row != sq2.row) return true; if (sq1.row == sq2.row && sq1.col != sq2.col) return true; return false; } public static boolean withinQueenRange(Square sq1,Square sq2) { if (Math.abs(sq1.col - sq2.col) == Math.abs(sq1.row - sq2.row)) return true; if (sq1.col == sq2.col && sq1.row != sq2.row) return true; if (sq1.row == sq2.row && sq1.col != sq2.col) return true; return false; } //is sq2 within range of king that stands on sq1? public static boolean withinKingRange(Square sq1,Square sq2) { if (Math.abs(sq2.col-sq1.col) == 1 && Math.abs(sq2.row-sq1.row)==1) return true; if (sq2.col == sq1.col && Math.abs(sq2.row-sq1.row)==1) return true; if (sq2.row == sq1.row && Math.abs(sq2.col-sq1.col)==1) return true; return false; } //is sq2 within attacking range of the piece p? public static boolean withinAttackingRange(Piece p, Square sq2) { Square sq1 = p.getSquare(); if (p.name.equals("pawn")) return withinPawnAttackingRange(sq1,sq2,p.owner); if (p.name.equals("knight")) return withinKnightRange(sq1,sq2); if (p.name.equals("bishop")) return withinBishopRange(sq1,sq2); if (p.name.equals("rook")) return withinRookRange(sq1,sq2); if (p.name.equals("queen")) return withinQueenRange(sq1,sq2); if (p.name.equals("king")) return withinKingRange(sq1,sq2); return false; } //is sq2 within range of the piece p? public static boolean withinRange(Piece p, Square sq2) { Square sq1 = p.getSquare(); if (p.name.equals("pawn")) return withinPawnRange(sq1,sq2,p.owner); if (p.name.equals("knight")) return withinKnightRange(sq1,sq2); if (p.name.equals("bishop")) return withinBishopRange(sq1,sq2); if (p.name.equals("rook")) return withinRookRange(sq1,sq2); if (p.name.equals("queen")) return withinQueenRange(sq1,sq2); if (p.name.equals("king")) return withinKingRange(sq1,sq2); return false; } public static int diagDetails(Square sq1,Square sq2) { if (sq1.col < sq2.col && sq1.row < sq2.row) return DIAG_SLASH; if (sq1.col > sq2.col && sq1.row > sq2.row) return DIAG_SLASH; return DIAG_BACKSLASH; } public static int verticalLength(Square sq1,Square sq2) { return Math.abs(sq1.row - sq2.row) + 1; } public static int horizontalLength(Square sq1,Square sq2) { return Math.abs(sq1.col - sq2.col) + 1; } public static int diagonalLength(Square sq1,Square sq2) { return Math.abs(sq1.col - sq2.col) + 1; } public static int lineLength(Square sq1,Square sq2) { if (sq1.col == sq2.col && sq1.row != sq2.row) //vertical line return Math.abs(sq1.row - sq2.row) + 1; //verticalLength() if (sq1.row == sq2.row && sq1.col != sq2.col) //horizontal line return Math.abs(sq1.col - sq2.col) + 1; //horizontalLength() if (Math.abs(sq1.col-sq2.col) == Math.abs(sq1.row-sq2.row)) //diagonal line return Math.abs(sq1.col - sq2.col) + 1; //diagonalLength() return -1; } //same as withinKingRange(); adduced here for convenience public static boolean squaresAdjacent(Square sq1,Square sq2) { if (Math.abs(sq2.col-sq1.col) == 1 && Math.abs(sq2.row-sq1.row) == 1) return true; if (sq2.col == sq1.col && Math.abs(sq2.row-sq1.row)==1) return true; if (sq2.row == sq1.row && Math.abs(sq2.col-sq1.col)==1) return true; return false; } //is s1 between sq2 and sq3? //assumes sameLine(sq2,sq3) public static boolean isBetween(Square sq1,Square sq2,Square sq3) { if (sameVertical(sq2,sq3)) if (sq1.col==sq2.col && between(sq1.row,sq2.row,sq3.row)) return true; if (sameHorizontal(sq2,sq3)) if (sq1.row==sq2.row && between(sq1.col,sq2.col,sq3.col)) return true; if (sameDiagonal(sq2,sq3)) if (sameDiagonal(sq1,sq2) && between(sq1.col,sq2.col,sq3.col) && between(sq1.row,sq2.row,sq3.row)) return true; return false; } //is a between b and c? public static boolean between(int a, int b, int c) { if (a > Math.min(b,c) && a < Math.max(b,c)) return true; return false; } }