private static Move DetermineMove(Board board, UCIChessMove uciMove)
        {
            string from      = uciMove.From;
            string to        = uciMove.To;
            var    fromPos   = Position.Parse(from);
            var    toPos     = Position.Parse(to);
            var    fromPiece = board[fromPos];

            int fileDiff = Math.Abs((int)fromPiece.Position.File - (int)toPos.File);

            if (fromPiece.Type == PieceType.King && (fileDiff == 3 || fileDiff == 4))
            {
                King king = (King)fromPiece;
                Rook rook;
                if (fileDiff == 4)
                {
                    rook = (Rook)board[File.A, fromPiece.Position.Rank];
                }
                else
                {
                    rook = (Rook)board[File.H, fromPiece.Position.Rank];
                }

                return(MoveBuilder.CreateCastleMove(king, rook));
            }

            if (uciMove.PromotionChar != null)
            {
                string promotionChar = uciMove.PromotionChar.ToUpper();
                var    promotionType = (from p in (PieceType[])Enum.GetValues(typeof(PieceType))
                                        where p.ToNotationLetter().ToUpper() == promotionChar.ToUpper()
                                        select p).First();
                var promotionMoves = MoveBuilder.CreatePromotionMoves((Pawn)fromPiece, toPos, board[toPos] != null);
                return((from m in promotionMoves
                        where m.Promotion.NewPieceType.Type == promotionType
                        select m).First());
            }

            // Check for en passant
            var existingPieceRank = fromPiece.Position.Rank;
            var isCorrectRank     = fromPiece.Color == PieceColor.Black ? existingPieceRank == Rank._4 : existingPieceRank == Rank._5;

            try
            {
                int vertDir          = fromPiece.Color == PieceColor.White ? -1 : 1;
                var existingPieceTo  = board[toPos];
                var capturedPiecePos = toPos.MoveVert(vertDir);
                var capturedPiece    = board[capturedPiecePos];
                if (capturedPiece.Color == fromPiece.Color.Opposite() &&
                    capturedPiece.MoveHistory.Count == 1)
                {
                    // This is an en passant
                    return(MoveBuilder.CreateEnPassantMove((Pawn)fromPiece, toPos, capturedPiecePos));
                }
            }
            catch { }

            // Only other option is that this is a normal move.
            return(MoveBuilder.CreateNormalMove(fromPiece, toPos, board[toPos] != null));
        }
Esempio n. 2
0
        private List <Move> GetEnPassantMoves(Board board)
        {
            var enPassantMoves = new List <Move>();

            // Is the pawn in the right rank?
            if (Color == PieceColor.Black && Position.Rank != Rank._4)
            {
                return(new List <Move>());
            }
            if (Color == PieceColor.White && Position.Rank != Rank._5)
            {
                return(new List <Move>());
            }

            // Create a few KVP of Key = new position and value = piece to capture position
            var positions = new List <KeyValuePair <Position, Position> >();

            if ((int)Position.File >= (int)File.B)
            {
                positions.Add(
                    new KeyValuePair <Position, Position>(
                        Position.MoveVert(IncrementDirection).MoveHoriz(-1),
                        Position.MoveHoriz(-1)));
            }
            if ((int)Position.File <= (int)File.G)
            {
                positions.Add(
                    new KeyValuePair <Position, Position>(
                        Position.MoveVert(IncrementDirection).MoveHoriz(1),
                        Position.MoveHoriz(1)));
            }
            foreach (var kvp in positions)
            {
                var newPos     = kvp.Key;
                var capturePos = kvp.Value;

                // There has to be an enemy piece there
                var pieceToCapture = board[capturePos];
                if (pieceToCapture == null ||
                    pieceToCapture.Color == this.Color)
                {
                    continue;
                }

                // The piece must have made a pawn advances 2 move.
                if (pieceToCapture.MoveHistory == null ||
                    pieceToCapture.MoveHistory.Count != 1)
                {
                    continue;
                }

                // The move must be the most recently played move in the game.
                var pieceToCaptureLastMove = pieceToCapture.MoveHistory.Last();
                if (pieceToCaptureLastMove != board.LastMove)
                {
                    continue;
                }

                // We have a candidate for en passant!
                enPassantMoves.Add(MoveBuilder.CreateEnPassantMove(this, newPos, capturePos));
            }

            return(enPassantMoves);
        }