Ejemplo n.º 1
0
        public virtual bool HasAnyValidMoves(BoardPosition from)
        {
            ChessUtility.ThrowIfNull(from, "from");
            ReadOnlyCollection <Move> validMoves = GetValidMoves(from, true);

            return(validMoves.Count > 0);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        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));
        }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 5
0
 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);
 }
Ejemplo n.º 6
0
        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));
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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));
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
 protected bool IsValidMove(Move move, bool validateCheck)
 {
     ChessUtility.ThrowIfNull(move, "move");
     return(IsValidMove(move, validateCheck, true));
 }
Ejemplo n.º 11
0
 public bool IsValidMove(Move move)
 {
     ChessUtility.ThrowIfNull(move, "move");
     return(IsValidMove(move, true, true));
 }
Ejemplo n.º 12
0
 public ChessPiece GetPieceAt(BoardPosition position)
 {
     ChessUtility.ThrowIfNull(position, "position");
     return(GetPieceAt(position.File, position.Rank));
 }
Ejemplo n.º 13
0
 public virtual bool IsWinner(ChessPlayer player)
 {
     return(IsCheckmated(ChessUtility.GetOpponentOf(player)));
 }
Ejemplo n.º 14
0
 public ReadOnlyCollection <Move> GetValidMoves(BoardPosition from)
 {
     ChessUtility.ThrowIfNull(from, "from");
     return(GetValidMoves(from, false));
 }