Пример #1
0
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            boardInfo           = new ChessBoard();
            boardInfo.WhoseMove = ChessPieceColor.White;
            boardInfo.pieces    = new ChessPiece[]
            {
                new ChessPiece(ChessPieceType.Rook, 0, true),
                new ChessPiece(ChessPieceType.Knight, 0, true),
                new ChessPiece(ChessPieceType.Bishop, 0, true),
                new ChessPiece(ChessPieceType.Queen, 0, true),
                new ChessPiece(ChessPieceType.King, 0, true),
                new ChessPiece(ChessPieceType.Bishop, 1, true),
                new ChessPiece(ChessPieceType.Knight, 1, true),
                new ChessPiece(ChessPieceType.Rook, 1, true),
                new ChessPiece(ChessPieceType.Pawn, 0, true),
                new ChessPiece(ChessPieceType.Pawn, 1, true),
                new ChessPiece(ChessPieceType.Pawn, 2, true),
                new ChessPiece(ChessPieceType.Pawn, 3, true),
                new ChessPiece(ChessPieceType.Pawn, 4, true),
                new ChessPiece(ChessPieceType.Pawn, 5, true),
                new ChessPiece(ChessPieceType.Pawn, 6, true),
                new ChessPiece(ChessPieceType.Pawn, 7, true),
                null, null, null, null, null, null, null, null,
                null, null, null, null, null, null, null, null,
                null, null, null, null, null, null, null, null,
                null, null, null, null, null, null, null, null,
                new ChessPiece(ChessPieceType.Pawn, 0, false),
                new ChessPiece(ChessPieceType.Pawn, 1, false),
                new ChessPiece(ChessPieceType.Pawn, 2, false),
                new ChessPiece(ChessPieceType.Pawn, 3, false),
                new ChessPiece(ChessPieceType.Pawn, 4, false),
                new ChessPiece(ChessPieceType.Pawn, 5, false),
                new ChessPiece(ChessPieceType.Pawn, 6, false),
                new ChessPiece(ChessPieceType.Pawn, 7, false),
                new ChessPiece(ChessPieceType.Rook, 0, false),
                new ChessPiece(ChessPieceType.Knight, 0, false),
                new ChessPiece(ChessPieceType.Bishop, 0, false),
                new ChessPiece(ChessPieceType.Queen, 0, false),
                new ChessPiece(ChessPieceType.King, 0, false),
                new ChessPiece(ChessPieceType.Bishop, 1, false),
                new ChessPiece(ChessPieceType.Knight, 1, false),
                new ChessPiece(ChessPieceType.Rook, 1, false),
            };

            PieceMoves.InitiateChessPieceMotion();
            PieceValidMoves.GenerateValidMoves(boardInfo);
            Evaluation.EvaluateBoardScore(boardInfo);

            boardHistory.Add(new ChessBoard(boardInfo));

            base.Initialize();
        }
Пример #2
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);
        }
Пример #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);
        }
Пример #4
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);
        }
Пример #5
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);
        }