Пример #1
0
        public void AiPonderMove(BackgroundWorker worker)
        {
            this.Thinking      = true;
            this.NodesSearched = 0;
            ResultBoards resultBoards = new ResultBoards();

            resultBoards.Positions = new List <Board>();
            if (ChessEngine.Engine.Engine.CheckForMate(this.WhoseMove, ref this.ChessBoard))
            {
                this.Thinking = false;
            }
            else
            {
                MoveContent bestMove = new MoveContent();
                if ((!ChessEngine.Engine.Engine.FindPlayBookMove(ref bestMove, this.ChessBoard, (IEnumerable <OpeningMove>) this.OpeningBook) || (int)this.ChessBoard.FiftyMove > 45 || (int)this.ChessBoard.RepeatedMove >= 2) && (!ChessEngine.Engine.Engine.FindPlayBookMove(ref bestMove, this.ChessBoard, (IEnumerable <OpeningMove>) this.CurrentGameBook) || (int)this.ChessBoard.FiftyMove > 45 || (int)this.ChessBoard.RepeatedMove >= 2))
                {
                    bestMove = Search.IterativeSearch(this.ChessBoard, this.PlyDepthSearched, ref this.NodesSearched, ref this.NodesQuiessence, ref this.pvLine, worker, ref this.PlyDepthReached, ref this.RootMovesSearched, this.CurrentGameBook);
                }
                this.PreviousChessBoard = new Board(this.ChessBoard);
                this.RootMovesSearched  = (byte)resultBoards.Positions.Count;
                Board.MovePiece(this.ChessBoard, bestMove.MovingPiecePrimary.SrcPosition, bestMove.MovingPiecePrimary.DstPosition, ChessPieceType.Queen);
                this.ChessBoard.LastMove.GeneratePGNString(this.ChessBoard);
                for (byte index = 0; (int)index < 64; ++index)
                {
                    Square square = this.ChessBoard.Squares[(int)index];
                    if (square.Piece != null)
                    {
                        square.Piece.DefendedValue = (short)0;
                        square.Piece.AttackedValue = (short)0;
                    }
                }
                PieceValidMoves.GenerateValidMoves(this.ChessBoard);
                Evaluation.EvaluateBoardScore(this.ChessBoard);
                this.PieceTakenAdd(this.ChessBoard.LastMove);
                this.MoveHistory.Push(this.ChessBoard.LastMove);
                if (ChessEngine.Engine.Engine.CheckForMate(this.WhoseMove, ref this.ChessBoard))
                {
                    this.Thinking = false;
                    if (!this.ChessBoard.WhiteMate && !this.ChessBoard.BlackMate)
                    {
                        return;
                    }
                    this.LastMove.PgnMove += "#";
                }
                else
                {
                    if (this.ChessBoard.WhiteCheck || this.ChessBoard.BlackCheck)
                    {
                        this.LastMove.PgnMove += "+";
                    }
                    this.Thinking = false;
                }
            }
        }
Пример #2
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;
        }
Пример #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, 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;
        }
Пример #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.
             *
             *	The time it takes to regenerate the valid moves is nontrivial under Android. To improve performance,
             *	my fix regenerates the valid moves ONLY when it might prevent a game-ending premature declaration
             *	of checkmate, unless the difficulty is set to Hard or VeryHard (in which case it runs every time).
             *	Even a novice player is likely to get confused if the engine declares checkmate for no apparent reason,
             *	but the bug's more insidious manifestations at the two easiest difficulty levels help to make the computer a tiny bit easier
             *	to beat by giving it a blind spot that a player can exploit, the same way HUMAN opponents have blind spots and weaknesses of their own.
             */
            if (ChessBoard.BlackMate || ChessBoard.WhiteMate || (GameDifficulty == Difficulty.VeryHard) || (GameDifficulty == Difficulty.Hard))
            {
                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.FiftyMove > 45 || ChessBoard.RepeatedMove >= 2)
            {
                if (FindPlayBookMove(ref bestMove, ChessBoard, CurrentGameBook) == false ||
                    ChessBoard.FiftyMove > 45 || 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;
        }