Example #1
0
        internal static MoveContent IterativeSearch(Board examineBoard, byte depth, ref int nodesSearched, ref int nodesQuiessence, ref string pvLine, ref byte plyDepthReached, ref byte rootMovesSearched, List <OpeningMove> currentGameBook)
        {
            List <Position> pvChild = new List <Position>();
            int             alpha   = -400000000;
            const int       beta    = 400000000;


            MoveContent bestMove = new MoveContent();

            //We are going to store our result boards here
            ResultBoards succ = GetSortValidMoves(examineBoard);

            rootMovesSearched = (byte)succ.Positions.Count;

            if (rootMovesSearched == 1)
            {
                //I only have one move
                return(succ.Positions[0].LastMove);
            }

            //Can I make an instant mate?
            foreach (Board pos in succ.Positions)
            {
                int value = -AlphaBeta(pos, 1, -beta, -alpha, ref nodesSearched, ref nodesQuiessence, ref pvChild, true);

                if (value >= 32767)
                {
                    return(pos.LastMove);
                }
            }

            int currentBoard = 0;

            alpha = -400000000;

            succ.Positions.Sort(Sort);

            depth--;

            plyDepthReached = ModifyDepth(depth, succ.Positions.Count);

            foreach (Board pos in succ.Positions)
            {
                currentBoard++;

                progress = (int)((currentBoard / (decimal)succ.Positions.Count) * 100);

                pvChild = new List <Position>();

                int value = -AlphaBeta(pos, depth, -beta, -alpha, ref nodesSearched, ref nodesQuiessence, ref pvChild, false);

                if (value >= 32767)
                {
                    return(pos.LastMove);
                }

                if (examineBoard.RepeatedMove == 2)
                {
                    string fen = Board.Fen(true, pos);

                    foreach (OpeningMove move in currentGameBook)
                    {
                        if (move.EndingFEN == fen)
                        {
                            value = 0;
                            break;
                        }
                    }
                }

                pos.Score = value;

                //If value is greater then alpha this is the best board
                if (value > alpha || alpha == -400000000)
                {
                    pvLine = pos.LastMove.ToString();

                    foreach (Position pvPos in pvChild)
                    {
                        pvLine += " " + pvPos.ToString();
                    }

                    alpha    = value;
                    bestMove = pos.LastMove;
                }
            }

            plyDepthReached++;
            progress = 100;

            return(bestMove);
        }
Example #2
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);
        }
Example #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 (FindPlayBookMove(ref bestMove, ChessBoard, OpeningBook) == false ||
                ChessBoard.FiftyMove > 45 || ChessBoard.RepeatedMove >= 2)
            {
                if (FindPlayBookMove(ref bestMove, ChessBoard, CurrentGameBook) == false ||
                    ChessBoard.FiftyMove > 45 || ChessBoard.RepeatedMove >= 2)
                {
                    bestMove = Search.IterativeSearch(ChessBoard, PlyDepthSearched, CurrentGameBook);
                }
            }

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

            RootMovesSearched = (byte)resultBoards.Positions.Count;

            Board.MovePiece(ChessBoard, 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;
            }

            PieceValidMoves.GenerateValidMoves(ChessBoard);
            Evaluation.EvaluateBoardScore(ChessBoard);

            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;
        }
Example #4
0
        public void AiPonderMove()
        {
            Thinking = true;

            /* Fix added to prevent premature declaration of checkmate against computer's king.
             *
             * The original version only looked at squares that were available for the black king to move to PRIOR to white's latest move.
             * So... suppose you had a situation like this:
             *	r4r2/pppb1p1k/8/3p2Q1/q4P2/2np4/6PP/5RK1/ w - 0 27
             *  ... and moved the white queen from G5 to H5.
             *	At the start of white's move, the black king has 5 possible moves... 4 of which are attackable by white, and noted by
             *	GenerateValidMoves in WhiteAttackBoard[]. When AiPonderMove executes, it immediately eliminates those 4 squares as options
             *	for the black king, even though 2 of them are now safe because no white piece can attack them. However, square 7 is now
             *	directly in the queen's attack path, so it's eliminated as an option as well. Boom, premature checkmate... game over.
             */
            ChessBoard.BlackMate = false;
            ChessBoard.WhiteMate = false;
            PieceValidMoves.GenerateValidMoves(ChessBoard);

            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 (FindPlayBookMove(ref bestMove, ChessBoard, OpeningBook) == false ||
                ChessBoard.HalfMoveClock > 90 || ChessBoard.RepeatedMove >= 2)
            {
                if (FindPlayBookMove(ref bestMove, ChessBoard, CurrentGameBook) == false ||
                    ChessBoard.HalfMoveClock > 90 || ChessBoard.RepeatedMove >= 2)
                {
                    bestMove = Search.IterativeSearch(ChessBoard, PlyDepthSearched, ref NodesSearched, ref NodesQuiessence, ref pvLine, ref PlyDepthReached, ref RootMovesSearched, CurrentGameBook);
                }
            }

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

            RootMovesSearched = (byte)resultBoards.Positions.Count;

            Board.MovePiece(ChessBoard, 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;
            }

            PieceValidMoves.GenerateValidMoves(ChessBoard);
            Evaluation.EvaluateBoardScore(ChessBoard);

            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;
        }
Example #5
0
        internal static MoveContent IterativeSearchOld(Board examineBoard, ChessEngine.Engine.Engine.TimeSettings gameTimeSettings, ref int nodesSearched, ref int nodesQuiessence, ref string pvLine, BackgroundWorker worker, ref byte plyDepthReached, ref byte rootMovesSearched, List <OpeningMove> currentGameBook)
        {
            Zobrist.MarkAncient();
            MoveContent            moveContent1   = new MoveContent();
            MoveContent            moveContent2   = new MoveContent();
            string                 str1           = "";
            List <Search.Position> positionList1  = new List <Search.Position>();
            ResultBoards           sortValidMoves = Search.GetSortValidMoves(examineBoard);

            rootMovesSearched = (byte)sortValidMoves.Positions.Count;
            int  num1  = 30;
            int  num2  = 40;
            byte depth = 1;

            if (gameTimeSettings == ChessEngine.Engine.Engine.TimeSettings.Moves40In10Minutes)
            {
                num1 = 15;
            }
            else if (gameTimeSettings == ChessEngine.Engine.Engine.TimeSettings.Moves40In20Minutes)
            {
                num1 = 30;
            }
            else if (gameTimeSettings == ChessEngine.Engine.Engine.TimeSettings.Moves40In30Minutes)
            {
                num1 = 45;
            }
            else if (gameTimeSettings == ChessEngine.Engine.Engine.TimeSettings.Moves40In40Minutes)
            {
                num1 = 60;
            }
            else if (gameTimeSettings == ChessEngine.Engine.Engine.TimeSettings.Moves40In60Minutes)
            {
                num1 = 90;
            }
            else if (gameTimeSettings == ChessEngine.Engine.Engine.TimeSettings.Moves40In90Minutes)
            {
                num1 = 135;
            }
            DateTime now = DateTime.Now;

            do
            {
                pvLine = "";
                int num3 = -400000000;
                sortValidMoves.Positions.Sort(new Comparison <Board>(Search.Sort));
                foreach (Board position1 in sortValidMoves.Positions)
                {
                    if (DateTime.Now - now > TimeSpan.FromSeconds((double)num1))
                    {
                        pvLine = str1;
                        return(moveContent2);
                    }
                    if (worker != null)
                    {
                        worker.ReportProgress((int)((DateTime.Now - now).TotalSeconds / (double)num1 * 100.0));
                    }
                    List <Search.Position> pvLine1 = new List <Search.Position>();
                    int num4 = -Search.AlphaBeta(position1, depth, -400000000, -num3, ref nodesSearched, ref nodesQuiessence, ref pvLine1, true);
                    if (num4 >= (int)short.MaxValue)
                    {
                        pvLine = str1;
                        return(position1.LastMove);
                    }
                    if ((int)examineBoard.RepeatedMove == 2)
                    {
                        string str2 = Board.Fen(true, position1);
                        foreach (OpeningMove openingMove in currentGameBook)
                        {
                            if (openingMove.EndingFEN == str2)
                            {
                                num4 = 0;
                                break;
                            }
                        }
                    }
                    position1.Score = num4;
                    if (num4 > num3)
                    {
                        List <Search.Position> positionList2 = new List <Search.Position>();
                        pvLine = position1.LastMove.ToString();
                        foreach (Search.Position position2 in pvLine1)
                        {
                            pvLine = pvLine + " " + position2.ToString();
                            positionList2.Add(position2);
                        }
                        positionList2.Reverse();
                        num3         = num4;
                        moveContent1 = position1.LastMove;
                    }
                }
                moveContent2    = moveContent1;
                str1            = pvLine;
                plyDepthReached = depth;
                ++depth;
            }while (DateTime.Now - now < TimeSpan.FromSeconds((double)num1) && (int)plyDepthReached < 19);
            plyDepthReached = (byte)((uint)plyDepthReached + 1U);
            int num5 = num2 != 1 ? num2 - 1 : 40;

            return(moveContent2);
        }
Example #6
0
        internal static MoveContent IterativeSearch(Board examineBoard, byte depth, ref int nodesSearched, ref int nodesQuiessence, ref string pvLine, BackgroundWorker worker, ref byte plyDepthReached, ref byte rootMovesSearched, List <OpeningMove> currentGameBook)
        {
            List <Search.Position> pvLine1 = new List <Search.Position>();
            int num1 = -400000000;

            Zobrist.MarkAncient();
            MoveContent  moveContent    = new MoveContent();
            ResultBoards sortValidMoves = Search.GetSortValidMoves(examineBoard);

            rootMovesSearched = (byte)sortValidMoves.Positions.Count;
            if ((int)rootMovesSearched == 1)
            {
                return(sortValidMoves.Positions[0].LastMove);
            }
            foreach (Board position in sortValidMoves.Positions)
            {
                if (-Search.AlphaBeta(position, (byte)1, -400000000, -num1, ref nodesSearched, ref nodesQuiessence, ref pvLine1, true) >= (int)short.MaxValue)
                {
                    return(position.LastMove);
                }
            }
            int num2 = 0;
            int num3 = -400000000;

            sortValidMoves.Positions.Sort(new Comparison <Board>(Search.Sort));
            --depth;
            plyDepthReached = Search.ModifyDepth(depth, sortValidMoves.Positions.Count);
            foreach (Board position1 in sortValidMoves.Positions)
            {
                ++num2;
                if (worker != null)
                {
                    worker.ReportProgress((int)((Decimal)num2 / (Decimal)sortValidMoves.Positions.Count * new Decimal(100)));
                }
                List <Search.Position> pvLine2 = new List <Search.Position>();
                int num4 = -Search.AlphaBeta(position1, depth, -400000000, -num3, ref nodesSearched, ref nodesQuiessence, ref pvLine2, false);
                if (num4 >= (int)short.MaxValue)
                {
                    return(position1.LastMove);
                }
                if ((int)examineBoard.RepeatedMove == 2)
                {
                    string str = Board.Fen(true, position1);
                    foreach (OpeningMove openingMove in currentGameBook)
                    {
                        if (openingMove.EndingFEN == str)
                        {
                            num4 = 0;
                            break;
                        }
                    }
                }
                position1.Score = num4;
                if (num4 > num3 || num3 == -400000000)
                {
                    pvLine = position1.LastMove.ToString();
                    foreach (Search.Position position2 in pvLine2)
                    {
                        pvLine = pvLine + " " + position2.ToString();
                    }
                    num3        = num4;
                    moveContent = position1.LastMove;
                }
            }
            plyDepthReached = (byte)((uint)plyDepthReached + 1U);
            return(moveContent);
        }