public virtual bool HasAnyValidMoves(BoardPosition from) { ChessUtility.ThrowIfNull(from, "from"); ReadOnlyCollection <Move> validMoves = GetValidMoves(from, true); return(validMoves.Count > 0); }
protected virtual bool IsValidMove(Move move, bool validateCheck, bool careAboutWhoseTurnItIs) { ChessUtility.ThrowIfNull(move, "move"); if (move.OriginalPosition.Equals(move.NewPosition)) { return(false); } ChessPiece piece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank); if (careAboutWhoseTurnItIs && move.Player != WhoseTurn) { return(false); } if (piece == null || piece.Owner != move.Player) { return(false); } ChessPiece pieceAtDestination = GetPieceAt(move.NewPosition); if (pieceAtDestination != null && pieceAtDestination.Owner == move.Player) { return(false); } if (!piece.IsLegalMove(move, this)) { return(false); } if (validateCheck && WouldBeInCheckAfter(move, move.Player)) { return(false); } return(true); }
public virtual bool WouldBeInCheckAfter(Move move, ChessPlayer player) { ChessUtility.ThrowIfNull(move, "move"); GameCreationData gcd = new GameCreationData { Board = Board, CanWhiteCastleKingSide = CanWhiteCastleKingSide, CanWhiteCastleQueenSide = CanWhiteCastleQueenSide, CanBlackCastleKingSide = CanBlackCastleKingSide, CanBlackCastleQueenSide = CanBlackCastleQueenSide, EnPassant = null }; if (_moves.Count > 0) { DetailedMove last = _moves.Last(); if (last.Piece is Pawn && new BoardDistance(last.OriginalPosition, last.NewPosition).Y == 2) { gcd.EnPassant = new BoardPosition(last.NewPosition.File, last.Player == ChessPlayer.White ? 3 : 6); } } gcd.HalfMoveClock = _halfMoveClock; gcd.FullMoveNumber = _fullMoveNumber; ChessGame copy = new ChessGame(gcd); copy.ApplyMove(move, true); return(copy.IsInCheck(player)); }
protected virtual void UseGameCreationData(GameCreationData data) { Board = CloneBoard(data.Board); WhoseTurn = data.WhoseTurn; ChessPiece e1 = GetPieceAt(ChessFile.E, 1); ChessPiece e8 = GetPieceAt(ChessFile.E, 8); ChessPiece a1 = GetPieceAt(ChessFile.A, 1); ChessPiece h1 = GetPieceAt(ChessFile.H, 1); ChessPiece a8 = GetPieceAt(ChessFile.A, 8); ChessPiece h8 = GetPieceAt(ChessFile.H, 8); CanBlackCastleKingSide = CanBlackCastleQueenSide = CanWhiteCastleKingSide = CanWhiteCastleQueenSide = CastlingCanBeLegal; if (CastlingCanBeLegal) { if (!(e1 is King) || e1.Owner != ChessPlayer.White) { CanWhiteCastleKingSide = CanWhiteCastleQueenSide = false; } if (!(e8 is King) || e8.Owner != ChessPlayer.Black) { CanBlackCastleKingSide = CanBlackCastleQueenSide = false; } if (!(a1 is Rook) || a1.Owner != ChessPlayer.White || !data.CanWhiteCastleQueenSide) { CanWhiteCastleQueenSide = false; } if (!(h1 is Rook) || h1.Owner != ChessPlayer.White || !data.CanWhiteCastleKingSide) { CanWhiteCastleKingSide = false; } if (!(a8 is Rook) || a8.Owner != ChessPlayer.Black || !data.CanBlackCastleQueenSide) { CanBlackCastleQueenSide = false; } if (!(h8 is Rook) || h8.Owner != ChessPlayer.Black || !data.CanBlackCastleKingSide) { CanBlackCastleKingSide = false; } } if (data.EnPassant != null) { DetailedMove latestMove = new DetailedMove(new Move(new BoardPosition(data.EnPassant.File, data.WhoseTurn == ChessPlayer.White ? 7 : 2), new BoardPosition(data.EnPassant.File, data.WhoseTurn == ChessPlayer.White ? 5 : 4), ChessUtility.GetOpponentOf(data.WhoseTurn)), new Pawn(ChessUtility.GetOpponentOf(data.WhoseTurn)), false, CastlingType.None); _moves.Add(latestMove); } _halfMoveClock = data.HalfMoveClock; _fullMoveNumber = data.FullMoveNumber; }
protected static ChessPiece[][] CloneBoard(ChessPiece[][] originalBoard) { ChessUtility.ThrowIfNull(originalBoard, "originalBoard"); ChessPiece[][] newBoard = new ChessPiece[originalBoard.Length][]; for (int i = 0; i < originalBoard.Length; i++) { newBoard[i] = new ChessPiece[originalBoard[i].Length]; Array.Copy(originalBoard[i], newBoard[i], originalBoard[i].Length); } return(newBoard); }
protected virtual ReadOnlyCollection <Move> GetValidMoves(BoardPosition from, bool returnIfAny) { ChessUtility.ThrowIfNull(from, "from"); ChessPiece piece = GetPieceAt(from); if (piece == null || piece.Owner != WhoseTurn) { return(new ReadOnlyCollection <Move>(new List <Move>())); } return(piece.GetLegalMoves(from, returnIfAny, this, IsValidMove)); }
public override bool IsLegalMove(Move move, ChessGame game) { ChessUtility.ThrowIfNull(move, "move"); ChessUtility.ThrowIfNull(game, "game"); BoardPosition origin = move.OriginalPosition; BoardPosition destination = move.NewPosition; BoardDistance posDelta = new BoardDistance(origin, destination); if (posDelta.X != 0 && posDelta.Y != 0) { return(false); } bool increasingRank = destination.Rank > origin.Rank; bool increasingFile = (int)destination.File > (int)origin.File; if (posDelta.X == 0) { int f = (int)origin.File; for (int r = origin.Rank + (increasingRank ? 1 : -1); increasingRank?r <destination.Rank : r> destination.Rank; r += increasingRank ? 1 : -1) { if (game.GetPieceAt((ChessFile)f, r) != null) { return(false); } } } else // (posDelta.DeltaY == 0) { int r = origin.Rank; for (int f = (int)origin.File + (increasingFile ? 1 : -1); increasingFile?f <(int)destination.File : f> (int) destination.File; f += increasingFile ? 1 : -1) { if (game.GetPieceAt((ChessFile)f, r) != null) { return(false); } } } return(true); }
public override ReadOnlyCollection <Move> GetLegalMoves(BoardPosition from, bool returnIfAny, ChessGame game, Func <Move, bool> gameMoveValidator) { ChessUtility.ThrowIfNull(from, "from"); List <Move> validMoves = new List <Move>(); ChessPiece piece = game.GetPieceAt(from); int l0 = game.BoardHeight; int l1 = game.BoardWidth; for (int i = -7; i < 8; i++) { if (i == 0) { continue; } if (from.Rank + i > 0 && from.Rank + i <= l0) { Move move = new Move(from, new BoardPosition(from.File, from.Rank + i), piece.Owner); if (gameMoveValidator(move)) { validMoves.Add(move); if (returnIfAny) { return(new ReadOnlyCollection <Move>(validMoves)); } } } if ((int)from.File + i > -1 && (int)from.File + i < l1) { Move move = new Move(from, new BoardPosition(from.File + i, from.Rank), piece.Owner); if (gameMoveValidator(move)) { validMoves.Add(move); if (returnIfAny) { return(new ReadOnlyCollection <Move>(validMoves)); } } } } return(new ReadOnlyCollection <Move>(validMoves)); }
public virtual MoveType ApplyMove(Move move, bool alreadyValidated) { ChessUtility.ThrowIfNull(move, "move"); if (!alreadyValidated && !IsValidMove(move)) { return(MoveType.Invalid); } MoveType type = MoveType.Move; ChessPiece movingPiece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank); ChessPiece capturedPiece = GetPieceAt(move.NewPosition.File, move.NewPosition.Rank); ChessPiece newPiece = movingPiece; bool isCapture = capturedPiece != null; CastlingType castle = CastlingType.None; if (movingPiece is Pawn) { _halfMoveClock = 0; BoardDistance pd = new BoardDistance(move.OriginalPosition, move.NewPosition); if (pd.X == 1 && pd.Y == 1 && GetPieceAt(move.NewPosition) == null) { // en passant isCapture = true; SetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank, null); } if (move.NewPosition.Rank == (move.Player == ChessPlayer.White ? 8 : 1)) { newPiece = MapPgnCharToPiece(move.Promotion.Value, move.Player); type |= MoveType.Promotion; } } else if (movingPiece is King) { if (movingPiece.Owner == ChessPlayer.White) { CanWhiteCastleKingSide = CanWhiteCastleQueenSide = false; } else { CanBlackCastleKingSide = CanBlackCastleQueenSide = false; } if (new BoardDistance(move.OriginalPosition, move.NewPosition).X == 2 && CastlingCanBeLegal) { castle = ApplyCastle(move); type |= MoveType.Castling; } } else if (movingPiece is Rook) { if (move.Player == ChessPlayer.White) { if (move.OriginalPosition.File == ChessFile.A && move.OriginalPosition.Rank == 1) { CanWhiteCastleQueenSide = false; } else if (move.OriginalPosition.File == ChessFile.H && move.OriginalPosition.Rank == 1) { CanWhiteCastleKingSide = false; } } else { if (move.OriginalPosition.File == ChessFile.A && move.OriginalPosition.Rank == 8) { CanBlackCastleQueenSide = false; } else if (move.OriginalPosition.File == ChessFile.H && move.OriginalPosition.Rank == 8) { CanBlackCastleKingSide = false; } } } if (isCapture) { type |= MoveType.Capture; _halfMoveClock = 0; if (move.NewPosition.File == ChessFile.A && move.NewPosition.Rank == 1) { CanWhiteCastleQueenSide = false; } else if (move.NewPosition.File == ChessFile.H && move.NewPosition.Rank == 1) { CanWhiteCastleKingSide = false; } else if (move.NewPosition.File == ChessFile.A && move.NewPosition.Rank == 8) { CanBlackCastleQueenSide = false; } else if (move.NewPosition.File == ChessFile.H && move.NewPosition.Rank == 8) { CanBlackCastleKingSide = false; } } if (!isCapture && !(movingPiece is Pawn)) { _halfMoveClock++; if (_halfMoveClock >= 100) { fiftyMoves = true; } else { fiftyMoves = false; } } if (move.Player == ChessPlayer.Black) { _fullMoveNumber++; } SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, newPiece); SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, null); WhoseTurn = ChessUtility.GetOpponentOf(move.Player); _moves.Add(new DetailedMove(move, movingPiece, isCapture, castle)); _positions.Add(GetPosition()); return(type); }
protected bool IsValidMove(Move move, bool validateCheck) { ChessUtility.ThrowIfNull(move, "move"); return(IsValidMove(move, validateCheck, true)); }
public bool IsValidMove(Move move) { ChessUtility.ThrowIfNull(move, "move"); return(IsValidMove(move, true, true)); }
public ChessPiece GetPieceAt(BoardPosition position) { ChessUtility.ThrowIfNull(position, "position"); return(GetPieceAt(position.File, position.Rank)); }
public virtual bool IsWinner(ChessPlayer player) { return(IsCheckmated(ChessUtility.GetOpponentOf(player))); }
public ReadOnlyCollection <Move> GetValidMoves(BoardPosition from) { ChessUtility.ThrowIfNull(from, "from"); return(GetValidMoves(from, false)); }