Пример #1
0
        //Copy Constructor
        internal Board(Board board)
        {
            Squares = new Square[64];

            for (byte x = 0; x < 64; x++)
            {
                if (board.Squares[x].Piece != null)
                {
                    Squares[x] = new Square(board.Squares[x].Piece);
                }
            }
            EndGamePhase = board.EndGamePhase;

            FiftyMove = board.FiftyMove;
            RepeatedMove = board.RepeatedMove;

            WhiteCastled = board.WhiteCastled;
            BlackCastled = board.BlackCastled;

            BlackCheck = board.BlackCheck;
            WhiteCheck = board.WhiteCheck;
            StaleMate = board.StaleMate;
            WhiteMate = board.WhiteMate;
            BlackMate = board.BlackMate;
            WhoseMove = board.WhoseMove;
            EnPassantPosition = board.EnPassantPosition;
            EnPassantColor = board.EnPassantColor;

            ZobristHash = board.ZobristHash;

            Score = board.Score;

            LastMove = new MoveContent(board.LastMove);

            MoveCount = board.MoveCount;
        }
Пример #2
0
        private Board(Square[] squares)
        {
            Squares = new Square[64];

            for (byte x = 0; x < 64; x++)
            {
                if (squares[x].Piece != null)
                {
                    Squares[x].Piece = new Piece(squares[x].Piece);
                }
            }
        }
Пример #3
0
        public void AiPonderMove()
        {
            Thinking      = true;
            NodesSearched = 0;

            var resultBoards = new ResultBoards();

            resultBoards.Positions = new List <Board>();

            if (CheckForMate(WhoseMove, ref ChessBoard))
            {
                Thinking = false;
                return;
            }

            MoveContent bestMove = new MoveContent();

            //If there is no playbook move search for the best move
            if (OpeningBook.TryGetMove(ChessBoard, ref bestMove) == false || ChessBoard.FiftyMove > 45 || ChessBoard.RepeatedMove >= 2)
            {
                if (CurrentGameBook.TryGetMove(ChessBoard, ref bestMove) == false || ChessBoard.FiftyMove > 45 || ChessBoard.RepeatedMove >= 2)
                {
                    bestMove = ChessBoard.IterativeSearch(PlyDepthSearched, ref NodesSearched, ref NodesQuiescence, ref pvLine, ref PlyDepthReached, ref RootMovesSearched, CurrentGameBook.MoveList);
                }
            }

            //Make the move
            PreviousChessBoard = new Board(ChessBoard);

            RootMovesSearched = (byte)resultBoards.Positions.Count;

            ChessBoard.MovePiece(bestMove.MovingPiecePrimary.SrcPosition, bestMove.MovingPiecePrimary.DstPosition, ChessPieceType.Queen);

            ChessBoard.LastMove.GeneratePGNString(ChessBoard);

            FileIO.SaveCurrentGameMove(ChessBoard, PreviousChessBoard, CurrentGameBook, bestMove);

            for (byte x = 0; x < 64; x++)
            {
                Square sqr = ChessBoard.Squares[x];

                if (sqr.Piece == null)
                {
                    continue;
                }

                sqr.Piece.DefendedValue = 0;
                sqr.Piece.AttackedValue = 0;
            }

            ChessBoard.GenerateValidMoves();
            ChessBoard.EvaluateBoardScore();

            PieceTakenAdd(ChessBoard.LastMove);

            MoveHistory.Push(ChessBoard.LastMove);

            if (CheckForMate(WhoseMove, ref ChessBoard))
            {
                Thinking = false;

                if (ChessBoard.WhiteMate || ChessBoard.BlackMate)
                {
                    LastMove.PgnMove += "#";
                }

                return;
            }

            if (ChessBoard.WhiteCheck || ChessBoard.BlackCheck)
            {
                LastMove.PgnMove += "+";
            }

            Thinking = false;
        }
Пример #4
0
        internal Board()
        {
            Squares = new Square[64];

            for (byte i = 0; i < 64; i++)
            {
                Squares[i] = new Square();
            }

            LastMove = new MoveContent();
        }
Пример #5
0
        internal string GeneratePGNString(Board board)
        {
            if (!String.IsNullOrEmpty(PgnMove))
            {
                return(PgnMove);
            }

            bool doubleColumn = false;
            bool doubleRow    = false;


            bool doubleDestination = false;

            var srcCol = (byte)(MovingPiecePrimary.SrcPosition % 8);
            var srcRow = (byte)(8 - (MovingPiecePrimary.SrcPosition / 8));
            var dstCol = (byte)(MovingPiecePrimary.DstPosition % 8);
            var dstRow = (byte)(8 - (MovingPiecePrimary.DstPosition / 8));

            PgnMove = "";

            for (byte x = 0; x < 64; x++)
            {
                if (x == MovingPiecePrimary.DstPosition)
                {
                    continue;
                }

                Square square = board.Squares[x];

                if (square.Piece == null)
                {
                    continue;
                }


                if (square.Piece.PieceType == MovingPiecePrimary.PieceType)
                {
                    if (square.Piece.PieceColor == MovingPiecePrimary.PieceColor)
                    {
                        foreach (byte move in square.Piece.ValidMoves)
                        {
                            if (move == MovingPiecePrimary.DstPosition)
                            {
                                doubleDestination = true;

                                byte col = (byte)(x % 8);
                                byte row = (byte)(8 - (x / 8));

                                if (col == srcCol)
                                {
                                    doubleColumn = true;
                                }

                                if (row == srcRow)
                                {
                                    doubleRow = true;
                                }

                                break;
                            }
                        }
                    }
                }
            }


            if (MovingPieceSecondary.PieceType == ChessPieceType.Rook)
            {
                if (MovingPieceSecondary.PieceColor == ChessPieceColor.Black)
                {
                    if (MovingPieceSecondary.SrcPosition == 7)
                    {
                        PgnMove += "O-O";
                    }
                    else if (MovingPieceSecondary.SrcPosition == 0)
                    {
                        PgnMove += "O-O-O";
                    }
                }
                else if (MovingPieceSecondary.PieceColor == ChessPieceColor.White)
                {
                    if (MovingPieceSecondary.SrcPosition == 63)
                    {
                        PgnMove += "O-O";
                    }
                    else if (MovingPieceSecondary.SrcPosition == 56)
                    {
                        PgnMove += "O-O-O";
                    }
                }
            }
            else
            {
                PgnMove += GetPgnMove(MovingPiecePrimary.PieceType);

                switch (MovingPiecePrimary.PieceType)
                {
                case ChessPieceType.Knight:
                {
                    if (doubleDestination)
                    {
                        if (!doubleColumn)
                        {
                            PgnMove += GetColumnFromInt(srcCol);
                        }
                        else
                        {
                            if (doubleRow)
                            {
                                PgnMove += GetColumnFromInt(srcCol);
                            }

                            PgnMove += srcRow;
                        }
                    }
                    break;
                }

                case ChessPieceType.Bishop:
                {
                    if (doubleDestination)
                    {
                        if (!doubleColumn)
                        {
                            PgnMove += GetColumnFromInt(srcCol);
                        }
                        else
                        {
                            if (doubleRow)
                            {
                                PgnMove += GetColumnFromInt(srcCol);
                            }

                            PgnMove += srcRow;
                        }
                    }
                    break;
                }

                case ChessPieceType.Rook:
                {
                    if (doubleDestination)
                    {
                        if (!doubleColumn)
                        {
                            PgnMove += GetColumnFromInt(srcCol);
                        }
                        else
                        {
                            if (doubleRow)
                            {
                                PgnMove += GetColumnFromInt(srcCol);
                            }

                            PgnMove += srcRow;
                        }
                    }
                    break;
                }

                case ChessPieceType.Queen:
                {
                    if (doubleDestination)
                    {
                        if (!doubleColumn)
                        {
                            PgnMove += GetColumnFromInt(srcCol);
                        }
                        else
                        {
                            if (doubleRow)
                            {
                                PgnMove += GetColumnFromInt(srcCol);
                            }

                            PgnMove += srcRow;
                        }
                    }
                    break;
                }

                case ChessPieceType.Pawn:
                {
                    if (doubleDestination && srcCol != dstCol)
                    {
                        PgnMove += GetColumnFromInt(srcCol);
                    }
                    else if (TakenPiece.PieceType != ChessPieceType.None)
                    {
                        PgnMove += GetColumnFromInt(srcCol);
                    }
                    break;
                }
                }

                if (TakenPiece.PieceType != ChessPieceType.None)
                {
                    PgnMove += "x";
                }

                PgnMove += GetColumnFromInt(dstCol);

                PgnMove += dstRow;

                if (PawnPromotedTo == ChessPieceType.Queen)
                {
                    PgnMove += "=Q";
                }
                else if (PawnPromotedTo == ChessPieceType.Rook)
                {
                    PgnMove += "=R";
                }
                else if (PawnPromotedTo == ChessPieceType.Bishop)
                {
                    PgnMove += "=B";
                }
                else if (PawnPromotedTo == ChessPieceType.Knight)
                {
                    PgnMove += "=N";
                }
            }

            return(PgnMove);
        }
Пример #6
0
        internal static MoveContent MovePiece(Board board, byte srcPosition, byte dstPosition, ChessPieceType promoteToPiece)
        {
            Piece piece = board.Squares[srcPosition].Piece;

            //Record my last move
            board.LastMove = new MoveContent();



            if (piece.PieceColor == ChessPieceColor.Black)
            {
                board.MoveCount++;
                //Add One to FiftyMoveCount to check for tie.
                board.FiftyMove++;
            }

            //En Passant
            if (board.EnPassantPosition > 0)
            {
                board.LastMove.EnPassantOccured = SetEnpassantMove(board, srcPosition, dstPosition, piece.PieceColor);
            }

            if (!board.LastMove.EnPassantOccured)
            {
                Square sqr = board.Squares[dstPosition];

                if (sqr.Piece != null)
                {
                    board.LastMove.TakenPiece = new PieceTaken(sqr.Piece.PieceColor, sqr.Piece.PieceType,
                                                               sqr.Piece.Moved, dstPosition);
                    board.FiftyMove = 0;
                }
                else
                {
                    board.LastMove.TakenPiece = new PieceTaken(ChessPieceColor.White, ChessPieceType.None, false,
                                                               dstPosition);
                }
            }

            board.LastMove.MovingPiecePrimary = new PieceMoving(piece.PieceColor, piece.PieceType, piece.Moved, srcPosition, dstPosition);

            //Delete the piece in its source position
            board.Squares[srcPosition].Piece = null;

            //Add the piece to its new position
            piece.Moved    = true;
            piece.Selected = false;
            board.Squares[dstPosition].Piece = piece;

            //Reset EnPassantPosition
            board.EnPassantPosition = 0;

            //Record En Passant if Pawn Moving
            if (piece.PieceType == ChessPieceType.Pawn)
            {
                board.FiftyMove = 0;
                RecordEnPassant(piece.PieceColor, piece.PieceType, board, srcPosition, dstPosition);
            }

            board.WhoseMove = board.WhoseMove == ChessPieceColor.White ? ChessPieceColor.Black : ChessPieceColor.White;

            KingCastle(board, piece, srcPosition, dstPosition);

            //Promote Pawns
            if (PromotePawns(board, piece, dstPosition, promoteToPiece))
            {
                board.LastMove.PawnPromotedTo = promoteToPiece;
            }
            else
            {
                board.LastMove.PawnPromotedTo = ChessPieceType.None;
            }

            if (board.FiftyMove >= 50)
            {
                board.StaleMate = true;
            }

            return(board.LastMove);
        }
Пример #7
0
        internal static bool SearchForMate(ChessPieceColor movingSide, Board examineBoard, ref bool blackMate, ref bool whiteMate, ref bool staleMate)
        {
            bool foundNonCheckBlack = false;
            bool foundNonCheckWhite = false;

            for (byte x = 0; x < 64; x++)
            {
                Square sqr = examineBoard.Squares[x];

                //Make sure there is a piece on the square
                if (sqr.Piece == null)
                {
                    continue;
                }

                //Make sure the color is the same color as the one we are moving.
                if (sqr.Piece.PieceColor != movingSide)
                {
                    continue;
                }

                //For each valid move for this piece
                foreach (byte dst in sqr.Piece.ValidMoves)
                {
                    //We make copies of the board and move so that we can move it without effecting the parent board
                    Board board = examineBoard.FastCopy();

                    //Make move so we can examine it
                    Board.MovePiece(board, x, dst, ChessPieceType.Queen);

                    //We Generate Valid Moves for Board
                    PieceValidMoves.GenerateValidMoves(board);

                    if (board.BlackCheck == false)
                    {
                        foundNonCheckBlack = true;
                    }
                    else if (movingSide == ChessPieceColor.Black)
                    {
                        continue;
                    }

                    if (board.WhiteCheck == false)
                    {
                        foundNonCheckWhite = true;
                    }
                    else if (movingSide == ChessPieceColor.White)
                    {
                        continue;
                    }
                }
            }

            if (foundNonCheckBlack == false)
            {
                if (examineBoard.BlackCheck)
                {
                    blackMate = true;
                    return(true);
                }
                if (!examineBoard.WhiteMate && movingSide != ChessPieceColor.White)
                {
                    staleMate = true;
                    return(true);
                }
            }

            if (foundNonCheckWhite == false)
            {
                if (examineBoard.WhiteCheck)
                {
                    whiteMate = true;
                    return(true);
                }
                if (!examineBoard.BlackMate && movingSide != ChessPieceColor.Black)
                {
                    staleMate = true;
                    return(true);
                }
            }

            return(false);
        }
Пример #8
0
        private static ResultBoards GetSortValidMoves(Board examineBoard)
        {
            ResultBoards succ = new ResultBoards
            {
                Positions = new List <Board>(30)
            };

            piecesRemaining = 0;

            for (byte x = 0; x < 64; x++)
            {
                Square sqr = examineBoard.Squares[x];

                //Make sure there is a piece on the square
                if (sqr.Piece == null)
                {
                    continue;
                }

                piecesRemaining++;

                //Make sure the color is the same color as the one we are moving.
                if (sqr.Piece.PieceColor != examineBoard.WhoseMove)
                {
                    continue;
                }

                //For each valid move for this piece
                foreach (byte dst in sqr.Piece.ValidMoves)
                {
                    //We make copies of the board and move so that we can move it without effecting the parent board
                    Board board = examineBoard.FastCopy();

                    //Make move so we can examine it
                    Board.MovePiece(board, x, dst, ChessPieceType.Queen);

                    //We Generate Valid Moves for Board
                    PieceValidMoves.GenerateValidMoves(board);

                    //Invalid Move
                    if (board.WhiteCheck && examineBoard.WhoseMove == ChessPieceColor.White)
                    {
                        continue;
                    }

                    //Invalid Move
                    if (board.BlackCheck && examineBoard.WhoseMove == ChessPieceColor.Black)
                    {
                        continue;
                    }

                    //We calculate the board score
                    Evaluation.EvaluateBoardScore(board);

                    //Invert Score to support Negamax
                    board.Score = SideToMoveScore(board.Score, board.WhoseMove);

                    succ.Positions.Add(board);
                }
            }

            succ.Positions.Sort(Sort);
            return(succ);
        }
Пример #9
0
        internal static void GenerateValidMoves(Board board)
        {
            // Reset Board
            board.BlackCheck = false;
            board.WhiteCheck = false;

            WhiteAttackBoard = new bool[64];
            BlackAttackBoard = new bool[64];

            //Generate Moves
            for (byte x = 0; x < 64; x++)
            {
                Square sqr = board.Squares[x];

                if (sqr.Piece == null)
                {
                    continue;
                }

                sqr.Piece.ValidMoves = new Stack <byte>(sqr.Piece.LastValidMoveCount);

                switch (sqr.Piece.PieceType)
                {
                case ChessPieceType.Pawn:
                {
                    if (sqr.Piece.PieceColor == ChessPieceColor.White)
                    {
                        CheckValidMovesPawn(MoveArrays.WhitePawnMoves[x].Moves, sqr.Piece, x,
                                            board,
                                            MoveArrays.WhitePawnTotalMoves[x]);
                        break;
                    }
                    if (sqr.Piece.PieceColor == ChessPieceColor.Black)
                    {
                        CheckValidMovesPawn(MoveArrays.BlackPawnMoves[x].Moves, sqr.Piece, x,
                                            board,
                                            MoveArrays.BlackPawnTotalMoves[x]);
                        break;
                    }

                    break;
                }

                case ChessPieceType.Knight:
                {
                    for (byte i = 0; i < MoveArrays.KnightTotalMoves[x]; i++)
                    {
                        AnalyzeMove(board, MoveArrays.KnightMoves[x].Moves[i], sqr.Piece);
                    }

                    break;
                }

                case ChessPieceType.Bishop:
                {
                    for (byte i = 0; i < MoveArrays.BishopTotalMoves1[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.BishopMoves1[x].Moves[i],
                                        sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }
                    for (byte i = 0; i < MoveArrays.BishopTotalMoves2[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.BishopMoves2[x].Moves[i],
                                        sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }
                    for (byte i = 0; i < MoveArrays.BishopTotalMoves3[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.BishopMoves3[x].Moves[i],
                                        sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }
                    for (byte i = 0; i < MoveArrays.BishopTotalMoves4[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.BishopMoves4[x].Moves[i],
                                        sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }

                    break;
                }

                case ChessPieceType.Rook:
                {
                    for (byte i = 0; i < MoveArrays.RookTotalMoves1[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.RookMoves1[x].Moves[i], sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }
                    for (byte i = 0; i < MoveArrays.RookTotalMoves2[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.RookMoves2[x].Moves[i], sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }
                    for (byte i = 0; i < MoveArrays.RookTotalMoves3[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.RookMoves3[x].Moves[i], sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }
                    for (byte i = 0; i < MoveArrays.RookTotalMoves4[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.RookMoves4[x].Moves[i], sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }

                    break;
                }

                case ChessPieceType.Queen:
                {
                    for (byte i = 0; i < MoveArrays.QueenTotalMoves1[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.QueenMoves1[x].Moves[i], sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }
                    for (byte i = 0; i < MoveArrays.QueenTotalMoves2[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.QueenMoves2[x].Moves[i], sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }
                    for (byte i = 0; i < MoveArrays.QueenTotalMoves3[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.QueenMoves3[x].Moves[i], sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }
                    for (byte i = 0; i < MoveArrays.QueenTotalMoves4[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.QueenMoves4[x].Moves[i], sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }

                    for (byte i = 0; i < MoveArrays.QueenTotalMoves5[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.QueenMoves5[x].Moves[i], sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }
                    for (byte i = 0; i < MoveArrays.QueenTotalMoves6[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.QueenMoves6[x].Moves[i], sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }
                    for (byte i = 0; i < MoveArrays.QueenTotalMoves7[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.QueenMoves7[x].Moves[i], sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }
                    for (byte i = 0; i < MoveArrays.QueenTotalMoves8[x]; i++)
                    {
                        if (
                            AnalyzeMove(board, MoveArrays.QueenMoves8[x].Moves[i], sqr.Piece) ==
                            false)
                        {
                            break;
                        }
                    }

                    break;
                }

                case ChessPieceType.King:
                {
                    if (sqr.Piece.PieceColor == ChessPieceColor.White)
                    {
                        whiteKingPosition = x;
                    }
                    else
                    {
                        blackKingPosition = x;
                    }

                    break;
                }
                }
            }


            if (board.WhoseMove == ChessPieceColor.White)
            {
                GenerateValidMovesKing(board.Squares[blackKingPosition].Piece, board,
                                       blackKingPosition);
                GenerateValidMovesKing(board.Squares[whiteKingPosition].Piece, board,
                                       whiteKingPosition);
            }
            else
            {
                GenerateValidMovesKing(board.Squares[whiteKingPosition].Piece, board,
                                       whiteKingPosition);
                GenerateValidMovesKing(board.Squares[blackKingPosition].Piece, board,
                                       blackKingPosition);
            }


            //Now that all the pieces were examined we know if the king is in check
            GenerateValidMovesKingCastle(board, board.Squares[whiteKingPosition].Piece);
            GenerateValidMovesKingCastle(board, board.Squares[blackKingPosition].Piece);
        }