/* * Returns true if a move results in a caputre for a given * position */ public static Boolean isMoveCapture(Move move, Position position) { if (position.getPiece(move.destination) == PieceType.Empty) { //Deal with En Passant capture PieceType piece = position.getPiece(move.origin); if ((piece == (position.whiteMove ? PieceType.P : PieceType.p)) && (move.destination == position.getEpSquare())) { return true; } else { return false; } } else { return true; } }
/* * Return a Forsyth-Edwards Notation string corresponding to a Position object */ public static String convertPositionToFEN(Position position) { StringBuilder feNotation = new StringBuilder(); //Piece placement for (int rank = 7; rank >= 0; rank--) { int emptySquares = 0; for (int file = 0; file < 8; file++) { PieceType piece = position.getPiece(Position.getSquare(file, rank)); if (piece == PieceType.Empty) { emptySquares++; } else { if (emptySquares > 0) { feNotation.Append(emptySquares); emptySquares = 0; } switch (piece) { case PieceType.K: feNotation.Append('K'); break; case PieceType.Q: feNotation.Append('Q'); break; case PieceType.R: feNotation.Append('R'); break; case PieceType.B: feNotation.Append('B'); break; case PieceType.N: feNotation.Append('N'); break; case PieceType.P: feNotation.Append('P'); break; case PieceType.k: feNotation.Append('k'); break; case PieceType.q: feNotation.Append('q'); break; case PieceType.r: feNotation.Append('r'); break; case PieceType.b: feNotation.Append('b'); break; case PieceType.n: feNotation.Append('n'); break; case PieceType.p: feNotation.Append('p'); break; default: throw new ParserError("Error creating FEN String"); } } } if (emptySquares > 0) { feNotation.Append(emptySquares); } if (rank > 0) { feNotation.Append("/"); } } //Active Colour feNotation.Append(position.whiteMove ? " w " : " b "); //Castling Rights Boolean anyCastle = false; if (position.h1Castle()) { feNotation.Append('K'); anyCastle = true; } if (position.a1Castle()) { feNotation.Append('Q'); anyCastle = true; } if (position.h8Castle()) { feNotation.Append('k'); anyCastle = true; } if (position.a8Castle()) { feNotation.Append('q'); anyCastle = true; } if (!anyCastle) { feNotation.Append('-'); } //En Passant Target Square { feNotation.Append(" "); if (position.getEpSquare() >= 0) { int file = Position.getFile(position.getEpSquare()); int rank = Position.getRank(position.getEpSquare()); feNotation.Append((char)(file + 'a')); feNotation.Append((char)(rank + '1')); } else { feNotation.Append('-'); } } //Move Counters feNotation.Append(' '); feNotation.Append(position.halfMoveClock); feNotation.Append(' '); feNotation.Append(position.fullMoveCounter); return feNotation.ToString(); }
/* * Remove EPSquare from position if it is not legal */ private static void fixupEPSquare(Position position) { int epSquare = position.getEpSquare(); if (epSquare >= 0) { ArrayList moves = MoveGenerator.mgInstance.legalMoves(position); Boolean epValid = false; foreach (Move move in moves) { if (move.destination == epSquare) { if (position.getPiece(move.origin) == (position.whiteMove ? PieceType.P : PieceType.p)) { epValid = true; break; } } } if (!epValid) { position.setEpSquare(-1); } } }
/* * Generate and return a list of psuedo-legal moves. * Pseudo-legal moves are those that don't necessarily defend * from check threats. */ public ArrayList psuedoLegalMoves(Position position) { ArrayList moveList = getMoveListObject(); Boolean whiteToMove = position.whiteMove; for (int file = 0; file < 8; file++) { for (int rank = 0; rank < 8; rank++) { int square = Position.getSquare(file, rank); PieceType piece = position.getPiece(square); if ((piece == PieceType.Empty) || (((int)piece < 6) != whiteToMove)) { continue; } if ((piece == PieceType.R) || (piece == PieceType.r) || (piece == PieceType.Q) || (piece == PieceType.q)) { if (addDirection(moveList, position, square, 7 - file, 1)) return moveList; if (addDirection(moveList, position, square, 7 - rank, 8)) return moveList; if (addDirection(moveList, position, square, file, -1)) return moveList; if (addDirection(moveList, position, square, rank, -8)) return moveList; } if ((piece == PieceType.B) || (piece == PieceType.b) || (piece == PieceType.Q) || (piece == PieceType.q)) { if (addDirection(moveList, position, square, Math.Min(7 - file, 7 - rank), 9)) return moveList; if (addDirection(moveList, position, square, Math.Min(file, 7 - rank), 7)) return moveList; if (addDirection(moveList, position, square, Math.Min(file, rank), -9)) return moveList; if (addDirection(moveList, position, square, Math.Min(7 - file, rank), -7)) return moveList; } if ((piece == PieceType.N) || (piece == PieceType.n)) { if (file < 6 && rank < 7 && addDirection(moveList, position, square, 1, 10)) return moveList; if (file < 7 && rank < 6 && addDirection(moveList, position, square, 1, 17)) return moveList; if (file > 0 && rank < 6 && addDirection(moveList, position, square, 1, 15)) return moveList; if (file > 1 && rank < 7 && addDirection(moveList, position, square, 1, 6)) return moveList; if (file > 1 && rank > 0 && addDirection(moveList, position, square, 1, -10)) return moveList; if (file > 0 && rank > 1 && addDirection(moveList, position, square, 1, -17)) return moveList; if (file < 7 && rank > 1 && addDirection(moveList, position, square, 1, -15)) return moveList; if (file < 6 && rank > 0 && addDirection(moveList, position, square, 1, -6)) return moveList; } if ((piece == PieceType.K) || (piece == PieceType.k)) { if (file < 7 && addDirection(moveList, position, square, 1, 1)) return moveList; if (file < 7 && rank < 7 && addDirection(moveList, position, square, 1, 9)) return moveList; if (rank < 7 && addDirection(moveList, position, square, 1, 8)) return moveList; if (file > 0 && rank < 7 && addDirection(moveList, position, square, 1, 7)) return moveList; if (file > 0 && addDirection(moveList, position, square, 1, -1)) return moveList; if (file > 0 && rank > 0 && addDirection(moveList, position, square, 1, -9)) return moveList; if (rank > 0 && addDirection(moveList, position, square, 1, -8)) return moveList; if (file < 7 && rank > 0 && addDirection(moveList, position, square, 1, -7)) return moveList; int kingOrigin = whiteToMove ? Position.getSquare(4, 0) : Position.getSquare(4, 7); if (Position.getSquare(file, rank) == kingOrigin) { int aCastle = whiteToMove ? Position.A1_CASTLE : Position.A8_CASTLE; int hCastle = whiteToMove ? Position.H1_CASTLE : Position.H8_CASTLE; PieceType rook = whiteToMove ? PieceType.R : PieceType.r; if (((position.getCastleMask() & (1 << hCastle)) != 0) && (position.getPiece(kingOrigin + 1) == PieceType.Empty) && (position.getPiece(kingOrigin + 2) == PieceType.Empty) && (position.getPiece(kingOrigin + 3) == rook) && !squareAttacked(position, kingOrigin) && !squareAttacked(position, kingOrigin + 1) && !squareAttacked(position, kingOrigin + 2)) { moveList.Add(getMoveObject(kingOrigin, kingOrigin + 2, PieceType.Empty)); } if (((position.getCastleMask() & (1 << aCastle)) != 0) && (position.getPiece(kingOrigin - 1) == PieceType.Empty) && (position.getPiece(kingOrigin - 2) == PieceType.Empty) && (position.getPiece(kingOrigin - 3) == PieceType.Empty) && (position.getPiece(kingOrigin - 4) == rook) && !squareAttacked(position, kingOrigin) && !squareAttacked(position, kingOrigin - 1) && !squareAttacked(position, kingOrigin - 2)) { moveList.Add(getMoveObject(kingOrigin, kingOrigin - 2, PieceType.Empty)); } } } if ((piece == PieceType.P) || (piece == PieceType.p)) { int rankDir = whiteToMove ? 8 : -8; if (position.getPiece(square + rankDir) == PieceType.Empty) { //non capture moves addPawnMoves(moveList, square, square + rankDir); if ((rank == (whiteToMove ? 1 : 6)) && (position.getPiece(square + 2 * rankDir) == PieceType.Empty)) { //double step moves addPawnMoves(moveList, square, square + rankDir * 2); } } //Capture to the left if (file > 0) { int toSquare = square + rankDir - 1; PieceType captured = position.getPiece(toSquare); if (captured != PieceType.Empty) { if (((int)captured < 6) != whiteToMove) { if (captured == (whiteToMove ? PieceType.k : PieceType.K)) { returnMoveList(moveList); moveList = getMoveListObject(); moveList.Add(getMoveObject(square, toSquare, PieceType.Empty)); return moveList; } else { addPawnMoves(moveList, square, toSquare); } } } else if (toSquare == position.getEpSquare()) { addPawnMoves(moveList, square, toSquare); } } //Capture to the right if (file < 7) { int toSquare = square + rankDir + 1; PieceType captured = position.getPiece(toSquare); if (captured != PieceType.Empty) { if (((int)captured < 6) != whiteToMove) { if (captured == (whiteToMove ? PieceType.k : PieceType.K)) { returnMoveList(moveList); moveList = getMoveListObject(); moveList.Add(getMoveObject(square, toSquare, PieceType.Empty)); return moveList; } else { addPawnMoves(moveList, square, toSquare); } } } else if (toSquare == position.getEpSquare()) { addPawnMoves(moveList, square, toSquare); } } } } } return moveList; }