Exemplo n.º 1
0
        private static List <ChessBoard> getValidBoards(ChessBoard examineBoard)
        {
            List <ChessBoard> validBoards = new List <ChessBoard>();

            for (byte x = 0; x < 64; ++x)
            {
                ChessPiece piece = examineBoard.pieces[x];

                //Make sure there is a piece on the square
                //Make sure the color is the same color as the one we are moving.
                if (piece == null || piece.PieceColor != examineBoard.WhoseMove)
                {
                    continue;
                }

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

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

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

                    //Invalid Move
                    if (board.whiteInCheck && examineBoard.WhoseMove == ChessPieceColor.White)
                    {
                        continue;
                    }
                    //Invalid Move
                    if (board.blackInCheck && 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);

                    validBoards.Add(board);
                }
            }
            return(validBoards);
        }
Exemplo n.º 2
0
        private static int AlphaBeta(ChessBoard examineBoard, byte depth, int alpha, int beta)
        {
            if (examineBoard == null || examineBoard.pieces == null)
            {
                return(0);
            }

            ++nodesSearched;

            if (examineBoard.FiftyMove >= 50 || examineBoard.RepeatedMove >= 3)
            {
                return(0);
            }

            if (depth == 0)
            {
                //Evaluate Score
                Evaluation.EvaluateBoardScore(examineBoard);
                //Invert Score to support Negamax
                return(SideToMoveScore(examineBoard.Score, examineBoard.WhoseMove));
            }

            List <Position> positions = EvaluateMoves(examineBoard, depth);

            int length = positions.Count;

            if (examineBoard.whiteInCheck || examineBoard.blackInCheck || length == 0)
            {
                if (SearchForMate(examineBoard.WhoseMove, examineBoard, ref examineBoard.blackInMate, ref examineBoard.whiteInMate, ref examineBoard.staleMate))
                {
                    if (examineBoard.blackInMate)
                    {
                        if (examineBoard.WhoseMove == ChessPieceColor.Black)
                        {
                            return(-Constants.GameOverValue - depth);
                        }
                        else
                        {
                            return(Constants.GameOverValue + depth);
                        }
                    }
                    if (examineBoard.whiteInMate)
                    {
                        if (examineBoard.WhoseMove == ChessPieceColor.Black)
                        {
                            return(Constants.GameOverValue + depth);
                        }
                        else
                        {
                            return(-Constants.GameOverValue - depth);
                        }
                    }

                    //If Not Mate then StaleMate
                    return(0);
                }
            }

            // Sort by score, this increases te chance we can prune moves early on
            positions.Sort(Sort);

            for (int i = 0; i < length; ++i)
            {
                Position move = positions[i];

                //Make a copy
                ChessBoard board = new ChessBoard(examineBoard);

                //Move Piece
                ChessEngine.MoveContent(board, move.SrcPosition, move.DstPosition, ChessPieceType.Queen);

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

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

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

                int value = -AlphaBeta(board, (byte)(depth - 1), -beta, -alpha);

                if (value >= beta)
                {
                    // Beta cut-off
                    return(beta);
                }
                if (value > alpha)
                {
                    alpha = value;
                }
            }

            return(alpha);
        }
Exemplo n.º 3
0
        internal static bool SearchForMate(ChessPieceColor movingSide, ChessBoard examineBoard, ref bool blackMate, ref bool whiteMate, ref bool staleMate)
        {
            bool foundNonCheckBlack = false;
            bool foundNonCheckWhite = false;

            for (byte x = 0; x < 64; ++x)
            {
                ChessPiece piece = examineBoard.pieces[x];

                //Make sure there is a piece on the square
                //Make sure the color is the same color as the one we are moving.
                if (piece == null || piece.PieceColor != movingSide)
                {
                    continue;
                }

                //For each valid move for this piece
                foreach (byte dst in piece.ValidMoves)
                {
                    //We make copies of the board and move so we don't change the original
                    ChessBoard board = new ChessBoard(examineBoard);

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

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

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

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

            if (!foundNonCheckBlack)
            {
                if (examineBoard.blackInCheck)
                {
                    blackMate = true;
                    return(true);
                }
                if (!examineBoard.whiteInMate && movingSide != ChessPieceColor.White)
                {
                    staleMate = true;
                    return(true);
                }
            }

            if (!foundNonCheckWhite)
            {
                if (examineBoard.whiteInCheck)
                {
                    whiteMate = true;
                    return(true);
                }
                if (!examineBoard.blackInMate && movingSide != ChessPieceColor.Black)
                {
                    staleMate = true;
                    return(true);
                }
            }
            return(false);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                this.Exit();
            }

            if (boardInfo.WhoseMove == ChessPieceColor.Black && blackIsAI)
            {
                ++waitASecond;
                if (waitASecond > 5)
                {
                    waitASecond = 0;
                    ChessEngine.EngineMove(boardInfo);
                }

                /*
                 * if(boardHistory.Count >= 20)
                 * {
                 *  boardHistory.RemoveAt(0);
                 * }
                 * boardHistory.Add(new ChessBoard(boardInfo));
                 */
            }
            else
            {
                // Let AI play vs AI

                /*
                 ++waitASecond;
                 * if (waitASecond > 5)
                 * {
                 *  waitASecond = 0;
                 *  ChessEngine.EngineMove(boardInfo);
                 * }
                 * */


                MouseState state = Mouse.GetState();
                if (state.LeftButton == ButtonState.Pressed)
                {
                    int xPos = (int)(state.X / Constants.SquareSize);
                    int yPos = (int)(state.Y / Constants.SquareSize);

                    if (xPos < Constants.NumberOfFiles && yPos < Constants.NumberOfRanks)
                    {
                        if (selectedIndex > boardInfo.pieces.Length)
                        {
                            byte index = (byte)(yPos * Constants.NumberOfFiles + xPos);
                            if (boardInfo.pieces[index] != null && boardInfo.pieces[index].PieceColor == boardInfo.WhoseMove)
                            {
                                selectedIndex = index;
                            }
                        }
                        else
                        {
                            byte index = (byte)(yPos * Constants.NumberOfFiles + xPos);
                            if (index != selectedIndex)
                            {
                                //SourceIndex has no piece
                                if (boardInfo.pieces[selectedIndex] == null)
                                {
                                    return;
                                }

                                //Select new piece if same color
                                if (boardInfo.pieces[index] != null && boardInfo.pieces[index].PieceColor == boardInfo.WhoseMove)
                                {
                                    selectedIndex = index;
                                }

                                //Check if this is infact a valid move
                                if (!ChessEngine.IsValidMove(boardInfo, selectedIndex, index))
                                {
                                    return;
                                }

                                ChessEngine.MovePiece(boardInfo, selectedIndex, index);
                                selectedIndex = 99;
                            }
                        }
                    }
                    else if (undoRectangle.Contains(new Point(state.X, state.Y)))
                    {
                        System.Diagnostics.Debug.WriteLine("UNDO PRESSED");
                        selectedIndex = 99;
                        if (boardHistory.Count > 1)
                        {
                            boardHistory.RemoveAt(boardHistory.Count - 1);
                        }
                        if (boardHistory.Count > 0)
                        {
                            boardInfo = new ChessBoard(boardHistory[boardHistory.Count - 1]);
                            PieceValidMoves.GenerateValidMoves(boardInfo);
                        }
                    }
                    else if (selectedIndex < boardInfo.pieces.Length)
                    {
                        selectedIndex = 99;
                    }
                }
            }

            base.Update(gameTime);
        }