private void CheckCardinalDirections(Board board) { foreach (int fileOffset in new[] { -1, 0, 1 }) { foreach (int rankOffset in Math.Abs(fileOffset) == 1 ? new[] { 0 } : new[] { -1, 1 }) { Square testSquare = new Square(Position, fileOffset, rankOffset); Movement testMove = new Movement(Position, testSquare); while (testSquare.IsValid) { Square enemyKingPosition = Color == Side.White ? board.BlackKing.Position : board.WhiteKing.Position; if (board.IsOccupied(testSquare)) { if (!board.IsOccupiedBySide(testSquare, Color) && Rules.MoveObeysRules(board, testMove, Color) && testSquare != enemyKingPosition) { LegalMoves.Add(new Movement(testMove)); } break; } if (Rules.MoveObeysRules(board, testMove, Color) && testSquare != enemyKingPosition) { LegalMoves.Add(new Movement(testMove)); } testSquare = new Square(testSquare, fileOffset, rankOffset); testMove = new Movement(Position, testSquare); } } } }
public bool canCastleQueenside() //returns true if the king can castle queenside (from E file to C file) { Piece rook = new Piece(); Coordinate pTmp = new Coordinate(Position); pTmp.changeFile(-4); //moves from E file to A file rook = board.board[pTmp.Rank, pTmp.File]; if (rook == null) //there is no piece where rook should be { return(false); } if (!(rook is Rook)) //the piece there is not a rook { return(false); } if (rook.hasMoved == true) //the rook there has already moved { return(false); } //figure out if the squares between the rook and king are empty MOVE TO POSSIBLE/LEGAL MOVES pTmp.changeFile(1); if (board.isTherePiece(pTmp) == true) //if there is a piece on B file { return(false); } pTmp.changeFile(1); if (board.isTherePiece(pTmp) == true) //if there is a piece on C file { return(false); } if (IntoCheck(pTmp)) //if being on C file would cause check { return(false); } pTmp.changeFile(1); if (board.isTherePiece(pTmp) == true) //if there is a piece on the D file { return(false); } if (IntoCheck(pTmp)) //if being on the D file would cause check { return(false); } if (board.inCheck(Color)) //if the king is already in check { return(false); } //if all of these are false and it has reached here, castling kingside is legal pTmp.changeFile(-1); //moves pTmp from D file to C file LegalMoves.Add(pTmp); return(true); }
private void CheckAttackingSquares(Board board) { foreach (int fileOffset in new[] { -1, 1 }) { int rankOffset = Color == Side.White ? 1 : -1; Square testSquare = new Square(Position, fileOffset, rankOffset); Movement testMove = new Movement(Position, testSquare); Square enemyKingPosition = Color == Side.White ? board.BlackKing.Position : board.WhiteKing.Position; if (testSquare.IsValid && board.IsOccupiedBySide(testSquare, Color.Complement()) && Rules.MoveObeysRules(board, testMove, Color) && testSquare != enemyKingPosition) { bool pawnAtSecondToLastRank = Position.Rank == (Color == Side.White ? 7 : 2); Movement move = pawnAtSecondToLastRank ? new PromotionMove(Position, testSquare) : new Movement(testMove); LegalMoves.Add(move); } } }
private void CheckSurroundingSquares(Board board) { for (int fileOffset = -1; fileOffset <= 1; fileOffset++) { for (int rankOffset = -1; rankOffset <= 1; rankOffset++) { if (fileOffset == 0 && rankOffset == 0) { continue; } Square testSquare = new Square(Position, fileOffset, rankOffset); Movement testMove = new Movement(Position, testSquare); Square enemyKingPosition = Color == Side.White ? board.BlackKing.Position : board.WhiteKing.Position; if (testSquare.IsValid && !board.IsOccupiedBySide(testSquare, Color) && Rules.MoveObeysRules(board, testMove, Color) && testSquare != enemyKingPosition) { LegalMoves.Add(new Movement(testMove)); } } } }
private void CheckCastlingMoves(Board board) { if (!HasMoved && !Rules.IsPlayerInCheck(board, Color)) { int castlingRank = Color == Side.White ? 1 : 8; List <Square> rookSquares = new List <Square> { new Square(1, castlingRank), new Square(8, castlingRank) }; List <Square> inBetweenSquares = new List <Square>(); List <Movement> inBetweenMoves = new List <Movement>(); for (int rookSquareIndex = 0; rookSquareIndex < rookSquares.Count; rookSquareIndex++) { if (board[rookSquares[rookSquareIndex]] is Rook rook && !rook.HasMoved && rook.Color == Color) { bool checkingQueensideCastle = rookSquareIndex == 0; inBetweenSquares.Add(new Square(checkingQueensideCastle ? 4 : 6, castlingRank)); inBetweenSquares.Add(new Square(checkingQueensideCastle ? 3 : 7, castlingRank)); if (checkingQueensideCastle) { inBetweenSquares.Add(new Square(2, castlingRank)); } if (!board.IsOccupied(inBetweenSquares[0]) && !board.IsOccupied(inBetweenSquares[1]) && (!checkingQueensideCastle || !board.IsOccupied(inBetweenSquares[2]))) { inBetweenMoves.Add(new Movement(Position, inBetweenSquares[0])); inBetweenMoves.Add(new Movement(Position, inBetweenSquares[1])); if (Rules.MoveObeysRules(board, inBetweenMoves[0], Color) && Rules.MoveObeysRules(board, inBetweenMoves[1], Color)) { LegalMoves.Add(new CastlingMove(Position, inBetweenSquares[1], rook)); } } inBetweenSquares.Clear(); inBetweenMoves.Clear(); } } } }
private void CheckKnightCircleSquares(Board board) { for (int fileOffset = -2; fileOffset <= 2; fileOffset++) { if (fileOffset == 0) { continue; } foreach (int rankOffset in Math.Abs(fileOffset) == 2 ? new[] { -1, 1 } : new[] { -2, 2 }) { Square testSquare = new Square(Position, fileOffset, rankOffset); Movement testMove = new Movement(Position, testSquare); Square enemyKingPosition = Color == Side.White ? board.BlackKing.Position : board.WhiteKing.Position; if (testSquare.IsValid && !board.IsOccupiedBySide(testSquare, Color) && Rules.MoveObeysRules(board, testMove, Color) && testSquare != enemyKingPosition) { LegalMoves.Add(new Movement(testMove)); } } } }
private void CheckForwardMovingSquares(Board board) { int advancingDirection = Color == Side.White ? 1 : -1; Square testSquare = new Square(Position, 0, advancingDirection); Movement testMove = new Movement(Position, testSquare); if (!board.IsOccupied(testSquare) && Rules.MoveObeysRules(board, testMove, Color)) { bool amOnSecondToLastRank = Position.Rank == (Color == Side.White ? 7 : 2); LegalMoves.Add(amOnSecondToLastRank ? new PromotionMove(Position, testSquare) : new Movement(testMove)); } if (!HasMoved) { testSquare = new Square(testSquare, 0, advancingDirection); testMove = new Movement(Position, testSquare); if (!board.IsOccupied(testSquare) && Rules.MoveObeysRules(board, testMove, Color)) { LegalMoves.Add(new Movement(testMove)); } } }
private void CheckEnPassantCaptures(Board board, Square enPassantEligibleSquare) { if (Color == Side.White ? Position.Rank == 5 : Position.Rank == 4) { foreach (int fileOffset in new[] { -1, 1 }) { Square lateralSquare = new Square(Position, fileOffset, 0); if (lateralSquare.IsValid && board[lateralSquare] is Pawn enemyLateralPawn && enemyLateralPawn.Color != Color) { Square squareToCheckWithEligibleSquare = new Square(enemyLateralPawn.Position, 0, enemyLateralPawn.Color == Side.White ? -1 : 1); if (squareToCheckWithEligibleSquare.Equals(enPassantEligibleSquare)) { EnPassantMove testMove = new EnPassantMove(Position, enPassantEligibleSquare, enemyLateralPawn); if (Rules.MoveObeysRules(board, testMove, Color)) { LegalMoves.Add(new EnPassantMove(Position, enPassantEligibleSquare, enemyLateralPawn)); } } } } } }