Esempio n. 1
0
        internal static MoveContent AlphaBetaRoot(ChessBoard examineBoard, byte depth)
        {
            nodesSearched = 0;
            SearchResult result = new SearchResult();

            //We are going to store our result boards here
            List<ChessBoard> validBoards = getValidBoards(examineBoard);

             Thread threadOne = new Thread(() =>
            {
                result = getBestMove(examineBoard, validBoards, depth);
            });

            threadOne.Start();
            threadOne.Join();

            System.Diagnostics.Debug.WriteLine("Node Searched: " + nodesSearched);

            return result.bestMove;
        }
Esempio n. 2
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();
        }
Esempio n. 3
0
        private static void GenerateValidMovesKingCastle(ChessBoard board, ChessPiece king)
        {
            if (king == null || king.Moved)
            {
                return;
            }

            if (king.PieceColor == ChessPieceColor.White &&
                board.whiteCastled)
            {
                return;
            }
            if (king.PieceColor == ChessPieceColor.Black &&
                board.blackCastled)
            {
                return;
            }
            if (king.PieceColor == ChessPieceColor.Black &&
                board.blackInCheck)
            {
                return;
            }
            if (king.PieceColor == ChessPieceColor.White &&
                board.whiteInCheck)
            {
                return;
            }

            //This code will add the castleling move to the pieces available moves
            if (king.PieceColor == ChessPieceColor.White)
            {
                if (board.whiteInCheck)
                {
                    return;
                }

                if (board.pieces[63] != null
                    && board.pieces[63].Identifier == ChessPieceType.Rook
                    && board.pieces[63].PieceColor == king.PieceColor
                    && board.pieces[62] == null
                    && board.pieces[61] == null
                    && BlackAttackBoard[61] == false
                    && BlackAttackBoard[62] == false)
                {
                    //Ok looks like move is valid lets add it
                    king.ValidMoves.Push(62);
                    WhiteAttackBoard[62] = true;
                }

                if (board.pieces[56] != null
                    && board.pieces[56].Identifier == ChessPieceType.Rook
                    && board.pieces[56].PieceColor == king.PieceColor
                    && board.pieces[57] == null
                    && board.pieces[58] == null
                    && board.pieces[59] == null
                    && BlackAttackBoard[58] == false
                    && BlackAttackBoard[59] == false)
                {
                    //Ok looks like move is valid lets add it
                    king.ValidMoves.Push(58);
                    WhiteAttackBoard[58] = true;
                }
            }
            else if (king.PieceColor == ChessPieceColor.Black)
            {
                if (board.blackInCheck)
                {
                    return;
                }

                //There are two ways to castle, scenario 1:
                if (board.pieces[7] != null)
                {
                    //Check if the Right Rook is still in the correct position
                    if (board.pieces[7].Identifier == ChessPieceType.Rook
                        && !board.pieces[7].Moved)
                    {
                        if (board.pieces[7].PieceColor == king.PieceColor)
                        {
                            //Move one column to right see if its empty

                            if (board.pieces[6] == null)
                            {
                                if (board.pieces[5] == null)
                                {
                                    if (WhiteAttackBoard[5] == false && WhiteAttackBoard[6] == false)
                                    {
                                        //Ok looks like move is valid lets add it
                                        king.ValidMoves.Push(6);
                                        BlackAttackBoard[6] = true;
                                    }
                                }
                            }
                        }
                    }
                }
                //There are two ways to castle, scenario 2:
                if (board.pieces[0] != null)
                {
                    //Check if the Left Rook is still in the correct position
                    if (board.pieces[0].Identifier == ChessPieceType.Rook &&
                        !board.pieces[0].Moved)
                    {
                        if (board.pieces[0].PieceColor ==
                            king.PieceColor)
                        {
                            //Move one column to right see if its empty
                            if (board.pieces[1] == null)
                            {
                                if (board.pieces[2] == null)
                                {
                                    if (board.pieces[3] == null)
                                    {
                                        if (WhiteAttackBoard[2] == false &&
                                            WhiteAttackBoard[3] == false)
                                        {
                                            //Ok looks like move is valid lets add it
                                            king.ValidMoves.Push(2);
                                            BlackAttackBoard[2] = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        private static void GenerateValidMovesKing(ChessPiece piece, ChessBoard board, byte srcPosition)
        {
            if (piece == null)
            {
                return;
            }

            byte length = MoveArrays.KingTotalMoves[srcPosition];
            for (byte i = 0; i < length; ++i)
            {
                byte dstPos = MoveArrays.KingMoves[srcPosition][i];

                if (piece.PieceColor == ChessPieceColor.White)
                {
                    //I can't move where I am being attacked
                    if (BlackAttackBoard[dstPos])
                    {
                        WhiteAttackBoard[dstPos] = true;
                        continue;
                    }
                }
                else if (WhiteAttackBoard[dstPos])
                {
                    BlackAttackBoard[dstPos] = true;
                    continue;
                }

                AnalyzeMove(board, dstPos, piece);
            }
        }
Esempio n. 5
0
        private static void CheckValidMovesPawn(byte[] moves, ChessPiece pcMoving, byte srcPosition,
                                                ChessBoard board, byte count)
        {
            for (byte i = 0; i < count; ++i)
            {
                byte dstPos = moves[i];

                // Piece in capture position
                if (dstPos % 8 != srcPosition % 8)
                {
                    //If there is a piece there I can potentialy kill
                    AnalyzeMovePawn(board, dstPos, pcMoving);

                    if (pcMoving.PieceColor == ChessPieceColor.White)
                    {
                        WhiteAttackBoard[dstPos] = true;
                    }
                    else
                    {
                        BlackAttackBoard[dstPos] = true;
                    }
                }
                    // if there is something in front pawns can't move there
                else if (board.pieces[dstPos] != null)
                {
                    return;
                }
                    //if there is nothing in front of me (blocked == false)
                else
                {
                    pcMoving.ValidMoves.Push(dstPos);
                }
            }
        }
Esempio n. 6
0
        private static void AnalyzeMovePawn(ChessBoard board, byte dstPos, ChessPiece movingPiece)
        {
            bool movingPieceIsWhite = movingPiece.PieceColor == ChessPieceColor.White;

            //Because Pawns only kill diagonaly we handle the En Passant scenario specialy
            if (board.EnPassantPosition == dstPos && board.EnPassantPosition > 0 && movingPiece.PieceColor != board.EnPassantColor)
            {
                //We have an En Passant Possible
                movingPiece.ValidMoves.Push(dstPos);

                if (movingPieceIsWhite)
                {
                    WhiteAttackBoard[dstPos] = true;
                }
                else
                {
                    BlackAttackBoard[dstPos] = true;
                }
            }

            ChessPiece pcAttacked = board.pieces[dstPos];

            //If there no piece there I can potentialy kill
            if (pcAttacked == null)
                return;

            //Regardless of what is there I am attacking this square
            if (movingPieceIsWhite)
            {
                WhiteAttackBoard[dstPos] = true;

                //if that piece is the same color
                if (pcAttacked.PieceColor == movingPiece.PieceColor)
                {
                    pcAttacked.DefendedValue += movingPiece.PieceActionValue;
                    return;
                }

                pcAttacked.AttackedValue += movingPiece.PieceActionValue;

                //If this is a king set it in check
                if (pcAttacked.Identifier == ChessPieceType.King)
                {
                    board.blackInCheck = true;
                }
                else
                {
                    //Add this as a valid move
                    movingPiece.ValidMoves.Push(dstPos);
                }
            }
            else
            {
                BlackAttackBoard[dstPos] = true;

                //if that piece is the same color
                if (pcAttacked.PieceColor == movingPiece.PieceColor)
                {
                    pcAttacked.DefendedValue += movingPiece.PieceActionValue;
                    return;
                }

                pcAttacked.AttackedValue += movingPiece.PieceActionValue;

                //If this is a king set it in check
                if (pcAttacked.Identifier == ChessPieceType.King)
                {
                    board.whiteInCheck = true;
                }
                else
                {
                    //Add this as a valid move
                    movingPiece.ValidMoves.Push(dstPos);
                }
            }

            return;
        }
Esempio n. 7
0
        private static bool AnalyzeMove(ChessBoard board, byte dstPos, ChessPiece movingPiece)
        {
            //If I am not a pawn everywhere I move I can attack

            bool movingPieceIsWhite = movingPiece.PieceColor == ChessPieceColor.White;
            if (movingPieceIsWhite)
            {
                WhiteAttackBoard[dstPos] = true;
            }
            else
            {
                BlackAttackBoard[dstPos] = true;
            }

            ChessPiece pcAttacked = board.pieces[dstPos];

            //If there no piece there I can potentialy kill just add the move and exit
            if (pcAttacked == null)
            {
                movingPiece.ValidMoves.Push(dstPos);
                return true;
            }

            if (pcAttacked.PieceColor != movingPiece.PieceColor)
            {
                // Different color I am attacking

                pcAttacked.AttackedValue += movingPiece.PieceActionValue;

                //If this is a king set it in check
                if (pcAttacked.Identifier == ChessPieceType.King)
                {
                    if (movingPieceIsWhite)
                    {
                        board.blackInCheck = true;
                    }
                    else
                    {
                        board.whiteInCheck = true;
                    }
                }
                else
                {
                    //Add this as a valid move
                    movingPiece.ValidMoves.Push(dstPos);
                }

                //We don't continue movement past this piece
                return false;
            }
            else
            {
                //Same Color I am defending
                pcAttacked.DefendedValue += movingPiece.PieceActionValue;

                //Since this piece is of my kind I can't move there
                return false;
            }
        }
Esempio n. 8
0
        internal static void GenerateValidMoves(ChessBoard board)
        {
            // Reset Board
            board.blackInCheck = false;
            board.whiteInCheck = false;

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

            //Generate Moves
            for (byte x = 0; x < 64; ++x)
            {
                ChessPiece piece = board.pieces[x];

                if (piece == null)
                    continue;

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

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

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

                            break;
                        }
                    case ChessPieceType.Bishop:
                        {
                            byte length = MoveArrays.BishopTotalMoves1[x];
                            for (byte i = 0; i < length; ++i)
                            {
                                if (!AnalyzeMove(board, MoveArrays.BishopMoves1[x][i], piece))
                                {
                                    break;
                                }
                            }
                            length = MoveArrays.BishopTotalMoves2[x];
                            for (byte i = 0; i < length; ++i)
                            {
                                if (!AnalyzeMove(board, MoveArrays.BishopMoves2[x][i], piece))
                                {
                                    break;
                                }
                            }
                            length = MoveArrays.BishopTotalMoves3[x];
                            for (byte i = 0; i < length; ++i)
                            {
                                if (!AnalyzeMove(board, MoveArrays.BishopMoves3[x][i], piece))
                                {
                                    break;
                                }
                            }
                            length = MoveArrays.BishopTotalMoves4[x];
                            for (byte i = 0; i < length; ++i)
                            {
                                if (!AnalyzeMove(board, MoveArrays.BishopMoves4[x][i], piece))
                                {
                                    break;
                                }
                            }
                            break;
                        }
                    case ChessPieceType.Rook:
                        {
                            byte length = MoveArrays.RookTotalMoves1[x];
                            for (byte i = 0; i < length; ++i)
                            {
                                if (!AnalyzeMove(board, MoveArrays.RookMoves1[x][i], piece))
                                {
                                    break;
                                }
                            }
                            length = MoveArrays.RookTotalMoves2[x];
                            for (byte i = 0; i < length; ++i)
                            {
                                if (!AnalyzeMove(board, MoveArrays.RookMoves2[x][i], piece))
                                {
                                    break;
                                }
                            }
                            length = MoveArrays.RookTotalMoves3[x];
                            for (byte i = 0; i < length; ++i)
                            {
                                if (!AnalyzeMove(board, MoveArrays.RookMoves3[x][i], piece))
                                {
                                    break;
                                }
                            }
                            length = MoveArrays.RookTotalMoves4[x];
                            for (byte i = 0; i < length; ++i)
                            {
                                if (!AnalyzeMove(board, MoveArrays.RookMoves4[x][i], piece))
                                {
                                    break;
                                }
                            }

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

                            // Rook Moves

                            length = MoveArrays.RookTotalMoves1[x];
                            for (byte i = 0; i < length; ++i)
                            {
                                if (!AnalyzeMove(board, MoveArrays.RookMoves1[x][i], piece))
                                {
                                    break;
                                }
                            }
                            length = MoveArrays.RookTotalMoves2[x];
                            for (byte i = 0; i < length; ++i)
                            {
                                if (!AnalyzeMove(board, MoveArrays.RookMoves2[x][i], piece))
                                {
                                    break;
                                }
                            }
                            length = MoveArrays.RookTotalMoves3[x];
                            for (byte i = 0; i < length; ++i)
                            {
                                if (!AnalyzeMove(board, MoveArrays.RookMoves3[x][i], piece))
                                {
                                    break;
                                }
                            }
                            length = MoveArrays.RookTotalMoves4[x];
                            for (byte i = 0; i < length; ++i)
                            {
                                if (!AnalyzeMove(board, MoveArrays.RookMoves4[x][i], piece))
                                {
                                    break;
                                }
                            }

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

                            break;
                        }
                }
            }

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

            //Now that all the pieces were examined we know if the king is in check
            GenerateValidMovesKingCastle(board, board.pieces[whiteKingPosition]);
            GenerateValidMovesKingCastle(board, board.pieces[blackKingPosition]);
        }
Esempio n. 9
0
        internal static List<Position> EvaluateMoves(ChessBoard board, byte depth)
        {
            //We are going to store our result boards here
            List<Position> positions = new List<Position>();

            for (byte x = 0; x < 64; ++x)
            {
                ChessPiece piece = board.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 != board.WhoseMove)
                    continue;

                //For each valid move for this piece
                foreach (byte dst in piece.ValidMoves)
                {
                    Position move = new Position();

                    move.SrcPosition = x;
                    move.DstPosition = dst;

                    ChessPiece pieceAttacked = board.pieces[move.DstPosition];

                    //If the move is a capture add it's value to the score
                    if (pieceAttacked != null)
                    {
                        move.Score += pieceAttacked.PieceValue;

                        if (piece.PieceValue < pieceAttacked.PieceValue)
                        {
                            move.Score += pieceAttacked.PieceValue - piece.PieceValue;
                        }
                    }

                    if (!piece.Moved)
                    {
                        move.Score += 10;
                    }

                    move.Score += piece.PieceActionValue;

                    //Add Score for Castling
                    if (!board.whiteCastled && board.WhoseMove == ChessPieceColor.White)
                    {
                        if (piece.Identifier == ChessPieceType.King)
                        {
                            if (move.DstPosition != 62 && move.DstPosition != 58)
                            {
                                move.Score -= 40;
                            }
                            else
                            {
                                move.Score += 40;
                            }
                        }
                        if (piece.Identifier == ChessPieceType.Rook)
                        {
                            move.Score -= 40;
                        }
                    }

                    if (!board.blackCastled && board.WhoseMove == ChessPieceColor.Black)
                    {
                        if (piece.Identifier == ChessPieceType.King)
                        {
                            if (move.DstPosition != 6 && move.DstPosition != 2)
                            {
                                move.Score -= 40;
                            }
                            else
                            {
                                move.Score += 40;
                            }
                        }
                        if (piece.Identifier == ChessPieceType.Rook)
                        {
                            move.Score -= 40;
                        }
                    }

                    positions.Add(move);
                }
            }

            return positions;
        }
Esempio n. 10
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;
        }
Esempio n. 11
0
        private static SearchResult getBestMove(ChessBoard examineBoard, List<ChessBoard> validBoards, byte depth)
        {
            int alpha = -400000000;
            const int beta = 400000000;

            SearchResult result = new SearchResult();

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

            //Can I make an instant mate?
            foreach (ChessBoard pos in validBoards)
            {
                int value = -AlphaBeta(pos, 1, -beta, -alpha);
                if (value >= Constants.GameOverValue)
                {
                    result.alpha = value;
                    result.bestMove = pos.LastMove;
                    return result;
                }
            }
            --depth;

            byte plyDepthReached = ModifyDepth(depth, validBoards.Count);
            int currentBoard = 0;
            alpha = -400000000;

            ChessBoard bestBoard = new ChessBoard(short.MinValue);
            foreach (ChessBoard board in validBoards)
            {
                ++currentBoard;

                int value = -AlphaBeta(board, plyDepthReached, -beta, -alpha);
                board.Score = value;

                //If value is greater then alpha this is the best board
                if (value > alpha)
                {
                    alpha = value;
                    bestBoard = new ChessBoard(board);
                }
            }

            result.alpha = alpha;
            result.bestMove = bestBoard.LastMove;
            return result;
        }
Esempio n. 12
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;
        }
Esempio n. 13
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;
        }
Esempio n. 14
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);
        }