import java.util.*; public class PositionAnalysis { //assumes: Move m has its srccol,srcrow,destcol,destrow fields set //does: checks if the move is self-consistent public static boolean checkConsistency(Move m, Chess c) { Field srcfld = c.field[m.srccol][m.srcrow]; Field destfld = c.field[m.destcol][m.destrow]; if (srcfld == destfld) return false; if (srcfld.piece == null) return false; //user clicked an empty field if (!srcfld.piece.owner.equals(c.user)) return false; //user tried to move enemy piece if (destfld.piece != null) if (srcfld.piece.owner.equals(destfld.piece.owner)) return false; //can't capture my own piece return true; } //assumes: Move m has its srccol,srcrow,destcol,destrow fields set //does: checks if the move is self-consistent public static boolean checkConsistency(Move m, Position p) { Square srcsqr = p.square[m.srccol][m.srcrow]; Square destsqr = p.square[m.destcol][m.destrow]; if (srcsqr == destsqr) return false; if (srcsqr.piece == null) return false; //an empty square if (!srcsqr.piece.owner.equals(p.getTurn())) return false; //user tried to move enemy piece if (destsqr.piece != null) if (srcsqr.piece.owner.equals(destsqr.piece.owner)) return false; //can't capture my own piece return true; } //assumes: Move m has its srcpiece, srcfld, destfld fields set //does: establishes if the move is a castle and sets partner attributes of the move public static void establishCastle(Move m, Chess c) { if (m.srcpiece.getName().equals("king") && m.srcpiece.cancastle) { if (m.srcfld == c.e1 && m.destfld == c.g1 && c.h1.piece != null) if (c.h1.piece.getName().equals("rook") && c.h1.piece.cancastle) { m.castle = 1; m.prtnrcol = 8; m.prtnrrow=1; m.prtnrfld=c.h1; m.prtnrsqr=c.curPos.square[8][1]; m.prtnrpiece=c.h1.piece; } if (m.srcfld == c.e8 && m.destfld == c.g8 && c.h8.piece != null) if (c.h8.piece.getName().equals("rook") && c.h8.piece.cancastle) { m.castle = 1; m.prtnrcol = 8; m.prtnrrow=8; m.prtnrfld=c.h8; m.prtnrsqr=c.curPos.square[8][8]; m.prtnrpiece=c.h8.piece; } if (m.srcfld == c.e1 && m.destfld == c.c1 && c.a1.piece != null) if (c.a1.piece.getName().equals("rook") && c.a1.piece.cancastle) { m.castle = 2; m.prtnrcol = 1; m.prtnrrow=1; m.prtnrfld=c.a1; m.prtnrsqr=c.curPos.square[1][1]; m.prtnrpiece=c.a1.piece; } if (m.srcfld == c.e8 && m.destfld == c.c8 && c.a8.piece != null) if (c.a8.piece.getName().equals("rook") && c.a8.piece.cancastle) { m.castle = 2; m.prtnrcol = 1; m.prtnrrow=8; m.prtnrfld=c.a8; m.prtnrsqr=c.curPos.square[1][8]; m.prtnrpiece=c.a8.piece; } } } //assumes: Move m has its srcpiece, srcsqr, destsqr fields set //does: establishes if the move is a castle and sets partner attributes of the move public static void establishCastle(Move m, Position p) { if (m.srcpiece.getName().equals("king") && m.srcpiece.cancastle) { if (m.srcsqr == p.square[5][1] && m.destsqr == p.square[7][1] && p.square[8][1].piece != null) if (p.square[8][1].piece.getName().equals("rook") && p.square[8][1].piece.cancastle) { m.castle = 1; m.prtnrcol = 8; m.prtnrrow=1; m.prtnrsqr=p.square[8][1]; m.prtnrpiece=p.square[8][1].piece; } if (m.srcsqr == p.square[5][8] && m.destsqr == p.square[7][8] && p.square[8][8].piece != null) if (p.square[8][8].piece.getName().equals("rook") && p.square[8][8].piece.cancastle) { m.castle = 1; m.prtnrcol = 8; m.prtnrrow=8; m.prtnrsqr=p.square[8][8]; m.prtnrpiece=p.square[8][8].piece; } if (m.srcsqr == p.square[5][1] && m.destsqr == p.square[3][1] && p.square[1][1].piece != null) if (p.square[1][1].piece.getName().equals("rook") && p.square[1][1].piece.cancastle) { m.castle = 2; m.prtnrcol = 1; m.prtnrrow=1; m.prtnrsqr=p.square[1][1]; m.prtnrpiece=p.square[1][1].piece; } if (m.srcsqr == p.square[5][8] && m.destsqr == p.square[3][8] && p.square[1][8].piece != null) if (p.square[1][8].piece.getName().equals("rook") && p.square[1][8].piece.cancastle) { m.castle = 2; m.prtnrcol = 1; m.prtnrrow=8; m.prtnrsqr=p.square[1][8]; m.prtnrpiece=p.square[1][8].piece; } } } //assumes: Move m has its srcpiece,srccol,destcol,destfld fields set //does: sets the empasse field public static void establishEnpasseStatus(Move m, Chess c) { if (m.srcpiece.name.equals("pawn")) //moving piece is pawn if (m.srccol == m.destcol + 1 || m.srccol == m.destcol - 1) //pawn moves to a neighbouring column if (m.destfld.piece == null) //and no enemy piece here if ((m.srcrow==5 && m.destrow==6) || (m.srcrow==4 && m.destrow==3)) //and it looks like en passe capture { Field f = c.field[m.destcol][m.srcrow]; //field where my victim stands Piece p = f.piece; //my potential victim if (p == null) return; //and my victim is a piece if (!p.name.equals("pawn")) return; //namely, a pawn if (p.owner.equals(m.srcpiece.owner)) return;//and an enemy pawn m.enpasse = true; } } //assumes: Move m has its srcpiece,srccol,destcol,destsqr fields set //does: sets the empasse field public static void establishEnpasseStatus(Move m, Position p) { if (m.srcpiece.name.equals("pawn")) //moving piece is pawn if (m.srccol == m.destcol + 1 || m.srccol == m.destcol - 1) //pawn moves to a neighbouring column if (m.destsqr.piece == null) //and no enemy piece here if ((m.srcrow==5 && m.destrow==6) || (m.srcrow==4 && m.destrow==3)) //and it looks like en passe capture { Square s = p.square[m.destcol][m.srcrow]; //square where my victim stands Piece pc = s.piece; //my potential victim if (pc == null) return; //and my victim is a piece if (!pc.name.equals("pawn")) return; //namely, a pawn if (pc.owner.equals(m.srcpiece.owner)) return;//and an enemy pawn m.enpasse = true; } } //assumes: Move m has its enpasse, destfld, srcpiece fields set //does: establishes victim attributes of Move public static void establishVictim(Move m, Chess c) { if (m.enpasse == false) { if (m.destfld.piece != null) { m.victcol = m.destcol; m.victrow = m.destrow; m.victfld = m.destfld; m.victsqr = m.destsqr; m.victpiece = m.destfld.piece; } } else //m.enpasse == true { m.victcol = m.destcol; m.victrow = m.srcrow; m.victfld = c.field[m.destcol][m.srcrow]; m.victsqr = c.curPos.square[m.destcol][m.srcrow]; m.victpiece = m.victfld.piece; } } //assumes: Move m has its enpasse, destsqr, srcpiece fields set //does: establishes victim attributes of Move public static void establishVictim(Move m, Position p) { if (m.enpasse == false) { if (m.destsqr.piece != null) { m.victcol = m.destcol; m.victrow = m.destrow; m.victsqr = m.destsqr; m.victpiece = m.destsqr.piece; } } else //m.enpasse == true { m.victcol = m.destcol; m.victrow = m.srcrow; m.victsqr = p.square[m.destcol][m.srcrow]; m.victpiece = m.victsqr.piece; } } //assumes: Move m has its srcpiece field set //does: establishes source attributes of Move public static void establishSourceAttributes(Move m) { m.srcname = (m.srcpiece.name == null) ? null : new String(m.srcpiece.name); m.srcowner = (m.srcpiece.owner == null) ? null : new String(m.srcpiece.owner); m.srcenpasse = m.srcpiece.enpasse; m.srccancastle = m.srcpiece.cancastle; } //assumes: Move m has its victpiece field set //does: establishes victim attributes of Move public static void establishVictimAttributes(Move m) { if (m.victpiece != null) { m.victname = (m.victpiece.name == null) ? null : new String(m.victpiece.name); m.victowner = (m.victpiece.owner == null) ? null : new String(m.victpiece.owner); m.victenpasse = m.victpiece.enpasse; m.victcancastle = m.victpiece.cancastle; } } //assumes: Move m has its srcpiece, victcol, victrow fields set //does: sets bencol, benrow fields of the Move m public static void establishBeneficiary(Move m, Chess c) { for (int i = 1; i <= 8; i++) for (int j = 1; j <= 8; j++) if (c.field[i][j].piece != null) if (!c.field[i][j].piece.owner.equals(m.srcpiece.owner)) //enemy piece if (c.field[i][j].piece.name.equals("pawn")) //namely, a pawn if (c.field[i][j].piece.enpasse == true) //that can be taken enpasse if (!(i == m.victcol && j == m.victrow)) { //and is not taken on this move m.bencol = i; m.benrow = j; } } //assumes: Move m has its srcpiece, victcol, victrow fields set //does: sets bencol, benrow fields of the Move m public static void establishBeneficiary(Move m, Position p) { for (int i = 1; i <= 8; i++) for (int j = 1; j <= 8; j++) if (p.square[i][j].piece != null) if (!p.square[i][j].piece.owner.equals(m.srcpiece.owner)) //enemy piece if (p.square[i][j].piece.name.equals("pawn")) //namely, a pawn if (p.square[i][j].piece.enpasse == true) //that can be taken enpasse if (!(i == m.victcol && j == m.victrow)) { //and is not taken on this move m.bencol = i; m.benrow = j; } } //assumes: move is self-consistent and has its enpasse, castle fields set //does: checks if the move is valid (i.e. that the pieces move the way they should) //including enpasse and castle public static boolean checkValidity(Move m, Position pos) { Square srcsqr = pos.square[m.srccol][m.srcrow]; Square destsqr = pos.square[m.destcol][m.destrow]; Square prtnrsqr = pos.square[m.prtnrcol][m.prtnrrow]; Piece srcpiece = srcsqr.piece; if (srcpiece.name.equals("pawn")) { if (Chessboard.withinPawnRange(srcsqr,destsqr,srcpiece.owner)) if (!pos.pieceBetween(srcsqr,destsqr,Chessboard.SAME_VER)) return true; if (Chessboard.withinPawnAttackingRange(srcsqr,destsqr,srcpiece.owner)) if ((destsqr.piece != null) || (m.enpasse == true)) return true; return false; } else if (srcpiece.name.equals("knight")) { if (Chessboard.withinKnightRange(srcsqr,destsqr)) return true; return false; } else if (srcpiece.name.equals("bishop")) { if (Chessboard.withinBishopRange(srcsqr,destsqr)) if (!pos.pieceBetween(srcsqr,destsqr,Chessboard.SAME_DIAG)) return true; return false; } else if (srcpiece.name.equals("rook")) { if (Chessboard.withinRookRange(srcsqr,destsqr)) if (!pos.pieceBetween(srcsqr,destsqr,Chessboard.relativeLocation(srcsqr,destsqr))) return true; return false; } else if (srcpiece.name.equals("queen")) { if (Chessboard.withinQueenRange(srcsqr,destsqr)) if (!pos.pieceBetween(srcsqr,destsqr,Chessboard.relativeLocation(srcsqr,destsqr))) return true; return false; } else if (srcpiece.name.equals("king")) { if (Chessboard.withinKingRange(srcsqr,destsqr)) return true; if (m.castle == 1 || m.castle == 2) if (!pos.pieceBetween(srcsqr,prtnrsqr,Chessboard.SAME_HOR)) return true; return false; } return false; } //assumes: move is self-consistent and has its enpasse, castle fields set //does: checks if the move is possible (i.e. that it does not expose my king to check) public static boolean checkPossibility(Move m, Position pos) { //do I expose my king to check? if (pos.myKingUnderCheck(m)) return false; //do I castle while under check or through checked squares? if (noCheckDuringCastle(m,pos) == false) return false; return true; } public static boolean noCheckDuringCastle(Move m, Position pos) { if (m.castle == 1) { //check e,f,g squares if (pos.isThreatened(pos.square[5][m.srcrow])) return false; if (pos.isThreatened(pos.square[6][m.srcrow])) return false; if (pos.isThreatened(pos.square[7][m.srcrow])) return false; } if (m.castle == 2) { //check e,d,c squares if (pos.isThreatened(pos.square[5][m.srcrow])) return false; if (pos.isThreatened(pos.square[4][m.srcrow])) return false; if (pos.isThreatened(pos.square[3][m.srcrow])) return false; } return true; } public static void establishMoveResults(Move m, Position pos) { Square enKingSqr = pos.getEnemyKing().getSquare(); //do I check enemy king with my source piece? if (pos.threatens(m.destsqr,m.srcpiece.name,enKingSqr)) m.check = true; //do I make a discovered check? Enumeration e = continueLine(enKingSqr,m.srcsqr,pos); if (e == null) return; while(e.hasMoreElements()) { Square sq = (Square) e.nextElement(); if (sq.piece != null) if (sq.piece.owner.equals(m.srcpiece.owner)) //also my piece if (Chessboard.withinRange(sq.piece,enKingSqr)) { //and an attack the king m.addCheck(); break; } } //do I mate the enemy king? } //returns Enumeration of Squares on the line from sq1 to sq2 AFTER sq2 public static Enumeration continueLine(Square sq1, Square sq2, Position pos) { int relloc = Chessboard.relativeLocation(sq1,sq2); if (sq1 == sq2) return null; if (relloc == Chessboard.NOT_RELATED) return null; Vector squares = new Vector(); int inc1,inc2; if (relloc == Chessboard.SAME_VER) { inc1 = (sq2.row > sq1.row) ? 1 : -1; for (int i = sq2.row + inc1; i >= 1 && i <= 8; i+=inc1) squares.addElement(pos.square[sq2.col][i]); } if (relloc == Chessboard.SAME_HOR) { inc1 = (sq2.col > sq1.col) ? 1 : -1; for (int i = sq2.col + inc1; i >= 1 && i <= 8; i+=inc1) squares.addElement(pos.square[i][sq2.row]); } if (relloc == Chessboard.SAME_DIAG) { inc1 = (sq2.row > sq1.row) ? 1 : -1; inc2 = (sq2.col > sq1.col) ? 1 : -1; for (int i = sq2.row + inc1, j = sq2.col + inc2; i >= 1 && i <= 8 && j >= 1 && j <= 8; i+=inc1,j+=inc2) squares.addElement(pos.square[j][i]); } return squares.elements(); } }