Esempio n. 1
0
        public bool MovePieceAN(string move)
        {
            byte sourceColumn = 0, sourceRow = 0, destinationColumn = 0, destinationRow = 0;

            MoveContent.ParseAN(move, ref sourceColumn, ref sourceRow, ref destinationColumn, ref destinationRow);
            return(MovePiece(sourceColumn, sourceRow, destinationColumn, destinationRow));
        }
Esempio n. 2
0
 private void PieceTakenRemove(MoveContent lastMove)
 {
     if (lastMove.TakenPiece.PieceType == ChessPieceType.None)
     {
         return;
     }
     if (lastMove.TakenPiece.PieceColor == ChessPieceColor.White)
     {
         if (lastMove.TakenPiece.PieceType == ChessPieceType.Queen)
         {
             --this.PiecesTakenCount.WhiteQueen;
         }
         else if (lastMove.TakenPiece.PieceType == ChessPieceType.Rook)
         {
             --this.PiecesTakenCount.WhiteRook;
         }
         else if (lastMove.TakenPiece.PieceType == ChessPieceType.Bishop)
         {
             --this.PiecesTakenCount.WhiteBishop;
         }
         else if (lastMove.TakenPiece.PieceType == ChessPieceType.Knight)
         {
             --this.PiecesTakenCount.WhiteKnight;
         }
         else if (lastMove.TakenPiece.PieceType == ChessPieceType.Pawn)
         {
             --this.PiecesTakenCount.WhitePawn;
         }
     }
     if (lastMove.TakenPiece.PieceColor != ChessPieceColor.Black)
     {
         return;
     }
     if (lastMove.TakenPiece.PieceType == ChessPieceType.Queen)
     {
         --this.PiecesTakenCount.BlackQueen;
     }
     else if (lastMove.TakenPiece.PieceType == ChessPieceType.Rook)
     {
         --this.PiecesTakenCount.BlackRook;
     }
     else if (lastMove.TakenPiece.PieceType == ChessPieceType.Bishop)
     {
         --this.PiecesTakenCount.BlackBishop;
     }
     else if (lastMove.TakenPiece.PieceType == ChessPieceType.Knight)
     {
         --this.PiecesTakenCount.BlackKnight;
     }
     else
     {
         if (lastMove.TakenPiece.PieceType != ChessPieceType.Pawn)
         {
             return;
         }
         --this.PiecesTakenCount.BlackPawn;
     }
 }
        internal Board()
        {
            Squares = new Square[64];

            for (byte i = 0; i < 64; i++)
            {
                Squares[i] = new Square();
            }

            LastMove = new MoveContent();
        }
Esempio n. 4
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;
                }
            }
        }
Esempio n. 5
0
        private void PieceTakenRemove(MoveContent lastMove)
        {
            if (lastMove.TakenPiece.PieceType != ChessPieceType.None)
            {
                if (lastMove.TakenPiece.PieceColor == ChessPieceColor.White)
                {
                    if (lastMove.TakenPiece.PieceType == ChessPieceType.Queen)
                    {
                        PiecesTakenCount.WhiteQueen--;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Rook)
                    {
                        PiecesTakenCount.WhiteRook--;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Bishop)
                    {
                        PiecesTakenCount.WhiteBishop--;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Knight)
                    {
                        PiecesTakenCount.WhiteKnight--;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Pawn)
                    {
                        PiecesTakenCount.WhitePawn--;
                    }
                }

                if (lastMove.TakenPiece.PieceColor == ChessPieceColor.Black)
                {
                    if (lastMove.TakenPiece.PieceType == ChessPieceType.Queen)
                    {
                        PiecesTakenCount.BlackQueen--;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Rook)
                    {
                        PiecesTakenCount.BlackRook--;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Bishop)
                    {
                        PiecesTakenCount.BlackBishop--;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Knight)
                    {
                        PiecesTakenCount.BlackKnight--;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Pawn)
                    {
                        PiecesTakenCount.BlackPawn--;
                    }
                }
            }
        }
Esempio n. 6
0
        private void PieceTakenAdd(MoveContent lastMove)
        {
            if (lastMove.TakenPiece.PieceType != ChessPieceType.None)
            {
                if (lastMove.TakenPiece.PieceColor == ChessPieceColor.White)
                {
                    if (lastMove.TakenPiece.PieceType == ChessPieceType.Queen)
                    {
                        PiecesTakenCount.WhiteQueen++;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Rook)
                    {
                        PiecesTakenCount.WhiteRook++;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Bishop)
                    {
                        PiecesTakenCount.WhiteBishop++;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Knight)
                    {
                        PiecesTakenCount.WhiteKnight++;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Pawn)
                    {
                        PiecesTakenCount.WhitePawn++;
                    }
                }

                if (ChessBoard.LastMove.TakenPiece.PieceColor == ChessPieceColor.Black)
                {
                    if (lastMove.TakenPiece.PieceType == ChessPieceType.Queen)
                    {
                        PiecesTakenCount.BlackQueen++;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Rook)
                    {
                        PiecesTakenCount.BlackRook++;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Bishop)
                    {
                        PiecesTakenCount.BlackBishop++;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Knight)
                    {
                        PiecesTakenCount.BlackKnight++;
                    }
                    else if (lastMove.TakenPiece.PieceType == ChessPieceType.Pawn)
                    {
                        PiecesTakenCount.BlackPawn++;
                    }
                }
            }
        }
Esempio n. 7
0
        //Copy Constructor
        internal Board(Board board)
        {
            Squares = new Square[64];

            for (byte x = 0; x < 64; x++)
            {
                if (board.Squares[x].Piece != null)
                {
                    Squares[x] = new Square(board.Squares[x].Piece);
                }
            }

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

            for (byte x = 0; x < 64; x++)
            {
                WhiteAttackBoard[x] = board.WhiteAttackBoard[x];
                BlackAttackBoard[x] = board.BlackAttackBoard[x];
            }

            EndGamePhase = board.EndGamePhase;

            HalfMoveClock = board.HalfMoveClock;
            RepeatedMove  = board.RepeatedMove;

            WhiteCastled = board.WhiteCastled;
            BlackCastled = board.BlackCastled;

            WhiteCanCastle = board.WhiteCanCastle;
            BlackCanCastle = board.BlackCanCastle;

            WhiteKingPosition = board.WhiteKingPosition;
            BlackKingPosition = board.BlackKingPosition;

            BlackCheck        = board.BlackCheck;
            WhiteCheck        = board.WhiteCheck;
            StaleMate         = board.StaleMate;
            WhiteMate         = board.WhiteMate;
            BlackMate         = board.BlackMate;
            WhoseMove         = board.WhoseMove;
            EnPassantPosition = board.EnPassantPosition;
            EnPassantColor    = board.EnPassantColor;

            ZobristHash = board.ZobristHash;

            Score = board.Score;

            LastMove = new MoveContent(board.LastMove);

            MoveCount = board.MoveCount;
        }
Esempio n. 8
0
        public MoveContent(MoveContent moveContent)
        {
            MovingPiecePrimary   = new PieceMoving(moveContent.MovingPiecePrimary);
            MovingPieceSecondary = new PieceMoving(moveContent.MovingPieceSecondary);

            TakenPiece = new PieceTaken(moveContent.TakenPiece.PieceColor,
                                        moveContent.TakenPiece.PieceType,
                                        moveContent.TakenPiece.Moved,
                                        moveContent.TakenPiece.Position);

            EnPassantOccured = moveContent.EnPassantOccured;
            PawnPromoted     = moveContent.PawnPromoted;
        }
Esempio n. 9
0
        public void TestAI()
        {
            // set up a simple scenario with an obvious checkmate in 1 move
            var engine = new Engine("k7/7R/6R1/8/8/8/8/K7 w - - 0 1");

            engine.GameDifficulty = Engine.Difficulty.Easy;
            engine.AiPonderMove();
            MoveContent lastMove = engine.GetMoveHistory().ToArray()[0];
            string      move     = lastMove.GetPureCoordinateNotation();

            // did the AI find the checkmate?
            Assert.AreEqual("g6g8", move);
        }
Esempio n. 10
0
        internal Board()
        {
            Squares = new Square[64];

            for (byte i = 0; i < 64; i++)
            {
                Squares[i] = new Square();
            }

            LastMove = new MoveContent();

            BlackCanCastle = true;
            WhiteCanCastle = true;

            WhiteAttackBoard = new bool[64];
            BlackAttackBoard = new bool[64];
        }
Esempio n. 11
0
        private static bool FindPlayBookMove(ref MoveContent bestMove, Board chessBoard, IEnumerable <OpeningMove> openingBook)
        {
            string str = Board.Fen(true, chessBoard);

            foreach (OpeningMove openingMove in openingBook)
            {
                if (openingMove.StartingFEN.Contains(str))
                {
                    int index = 0;
                    if (openingMove.Moves.Count > 1)
                    {
                        index = new Random(DateTime.Now.Second).Next(openingMove.Moves.Count - 1);
                    }
                    bestMove = openingMove.Moves[index];
                    return(true);
                }
            }
            return(false);
        }
Esempio n. 12
0
        private static bool FindPlayBookMove(ref MoveContent bestMove, Board chessBoard, IEnumerable <OpeningMove> openingBook)
        {
            //Get the Hash for the current Board;
            string boardFen = Board.Fen(true, chessBoard);

            //Check the Opening Move Book
            foreach (OpeningMove move in openingBook)
            {
                if (move.StartingFEN.Contains(boardFen))
                {
                    int index = 0;

                    bestMove = move.Moves[index];
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 13
0
        public void TestNotation()
        {
            byte sourceColumn = 0, sourceRow = 0, destinationColumn = 0, destinationRow = 0;

            Assert.IsFalse(MoveContent.ParseAN("toolong", ref sourceColumn, ref sourceRow, ref destinationColumn, ref destinationRow));
            Assert.IsFalse(MoveContent.ParseAN("abc", ref sourceColumn, ref sourceRow, ref destinationColumn, ref destinationRow));

            Assert.IsTrue(MoveContent.ParseAN("a8h1", ref sourceColumn, ref sourceRow, ref destinationColumn, ref destinationRow));
            Assert.AreEqual(sourceColumn, 0);
            Assert.AreEqual(sourceRow, 0);
            Assert.AreEqual(destinationColumn, 7);
            Assert.AreEqual(destinationRow, 7);

            Assert.IsTrue(MoveContent.ParseAN("b3e4", ref sourceColumn, ref sourceRow, ref destinationColumn, ref destinationRow));
            Assert.AreEqual(sourceColumn, 1);
            Assert.AreEqual(sourceRow, 5);
            Assert.AreEqual(destinationColumn, 4);
            Assert.AreEqual(destinationRow, 4);
        }
Esempio n. 14
0
        internal static void SaveCurrentGameMove(Board currentBoard, Board previousBoard,
                                                 ICollection <OpeningMove> gameBook, MoveContent bestMove)
        {
            try
            {
                var move = new OpeningMove();

                move.StartingFEN = Board.Fen(true, previousBoard);
                move.EndingFEN   = Board.Fen(true, currentBoard);
                move.Moves.Add(bestMove);

                gameBook.Add(move);

                foreach (var move1 in gameBook)
                {
                    byte repeatedMoves = 0;

                    foreach (var move2 in gameBook)
                    {
                        if (move1.EndingFEN == move2.EndingFEN)
                        {
                            repeatedMoves++;
                        }
                    }

                    if (previousBoard.RepeatedMove < repeatedMoves)
                    {
                        previousBoard.RepeatedMove = repeatedMoves;
                        currentBoard.RepeatedMove  = repeatedMoves;
                    }
                }

                if (currentBoard.RepeatedMove >= 3)
                {
                    currentBoard.StaleMate = true;
                }
            }
            catch (Exception)
            {
            }
        }
        //Copy Constructor
        internal Board(Board board)
        {
            Squares = new Square[64];

            for (byte x = 0; x < 64; x++)
            {
                if (board.Squares[x].Piece != null)
                {
                    Squares[x] = new Square(board.Squares[x].Piece);
                }
            }
            EndGamePhase = board.EndGamePhase;

            FiftyMove    = board.FiftyMove;
            RepeatedMove = board.RepeatedMove;

            WhiteCastled = board.WhiteCastled;
            BlackCastled = board.BlackCastled;

            BlackCheck        = board.BlackCheck;
            WhiteCheck        = board.WhiteCheck;
            StaleMate         = board.StaleMate;
            WhiteMate         = board.WhiteMate;
            BlackMate         = board.BlackMate;
            WhoseMove         = board.WhoseMove;
            EnPassantPosition = board.EnPassantPosition;
            EnPassantColor    = board.EnPassantColor;

            ZobristHash = board.ZobristHash;

            Score = board.Score;

            LastMove = new MoveContent(board.LastMove);

            MoveCount = board.MoveCount;
        }
Esempio n. 16
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;
        }
Esempio n. 17
0
        //Copy Constructor
        internal Board(Board board)
        {
            Squares = new Square[64];

            for (byte x = 0; x < 64; x++)
            {
                if (board.Squares[x].Piece != null)
                {
                    Squares[x] = new Square(board.Squares[x].Piece);
                }
            }
            EndGamePhase = board.EndGamePhase;

            FiftyMove = board.FiftyMove;
            RepeatedMove = board.RepeatedMove;

            WhiteCastled = board.WhiteCastled;
            BlackCastled = board.BlackCastled;

            BlackCheck = board.BlackCheck;
            WhiteCheck = board.WhiteCheck;
            StaleMate = board.StaleMate;
            WhiteMate = board.WhiteMate;
            BlackMate = board.BlackMate;
            WhoseMove = board.WhoseMove;
            EnPassantPosition = board.EnPassantPosition;
            EnPassantColor = board.EnPassantColor;

            ZobristHash = board.ZobristHash;

            Score = board.Score;

            LastMove = new MoveContent(board.LastMove);

            MoveCount = board.MoveCount;
        }
Esempio n. 18
0
        internal Board()
        {
            Squares = new Square[64];

            for (byte i = 0; i < 64; i++)
            {
                Squares[i] = new Square();
            }

            LastMove = new MoveContent();
        }
Esempio n. 19
0
        internal MoveContent MovePiece(byte srcPosition, byte dstPosition, ChessPieceType promoteToPiece)
        {
            Piece piece = Squares[srcPosition].Piece;

            //Record my last move
            LastMove = new MoveContent();



            if (piece.PieceColor == ChessPieceColor.Black)
            {
                MoveCount++;
                //Add One to FiftyMoveCount to check for tie.
                FiftyMove++;
            }

            //En Passant
            if (EnPassantPosition > 0)
            {
                LastMove.EnPassantOccured = SetEnpassantMove(srcPosition, dstPosition, piece.PieceColor);
            }

            if (!LastMove.EnPassantOccured)
            {
                Square sqr = Squares[dstPosition];

                if (sqr.Piece != null)
                {
                    LastMove.TakenPiece = new PieceTaken(sqr.Piece.PieceColor, sqr.Piece.PieceType, sqr.Piece.Moved, dstPosition);
                    FiftyMove           = 0;
                }
                else
                {
                    LastMove.TakenPiece = new PieceTaken(ChessPieceColor.White, ChessPieceType.None, false, dstPosition);
                }
            }

            LastMove.MovingPiecePrimary = new PieceMoving(piece.PieceColor, piece.PieceType, piece.Moved, srcPosition, dstPosition);

            //Delete the piece in its source position
            Squares[srcPosition].Piece = null;

            //Add the piece to its new position
            piece.Moved                = true;
            piece.Selected             = false;
            Squares[dstPosition].Piece = piece;

            //Reset EnPassantPosition
            EnPassantPosition = 0;

            //Record En Passant if Pawn Moving
            if (piece.PieceType == ChessPieceType.Pawn)
            {
                FiftyMove = 0;
                RecordEnPassant(piece.PieceColor, piece.PieceType, srcPosition, dstPosition);
            }

            WhoseMove = WhoseMove == ChessPieceColor.White ? ChessPieceColor.Black : ChessPieceColor.White;

            KingCastle(piece, srcPosition, dstPosition);

            //Promote Pawns
            if (PromotePawns(piece, dstPosition, promoteToPiece))
            {
                LastMove.PawnPromotedTo = promoteToPiece;
            }
            else
            {
                LastMove.PawnPromotedTo = ChessPieceType.None;
            }

            if (FiftyMove >= 50)
            {
                StaleMate = true;
            }

            return(LastMove);
        }
Esempio n. 20
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 (OpeningBook.TryGetMove(ChessBoard, ref bestMove) == false || ChessBoard.FiftyMove > 45 || ChessBoard.RepeatedMove >= 2)
            {
                if (CurrentGameBook.TryGetMove(ChessBoard, ref bestMove) == false || ChessBoard.FiftyMove > 45 || ChessBoard.RepeatedMove >= 2)
                {
                    bestMove = ChessBoard.IterativeSearch(PlyDepthSearched, ref NodesSearched, ref NodesQuiescence, ref pvLine, ref PlyDepthReached, ref RootMovesSearched, CurrentGameBook.MoveList);
                }
            }

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

            RootMovesSearched = (byte)resultBoards.Positions.Count;

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

            ChessBoard.GenerateValidMoves();
            ChessBoard.EvaluateBoardScore();

            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;
        }
Esempio n. 21
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);
        }
Esempio n. 22
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);
        }
Esempio n. 23
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;
        }
Esempio n. 24
0
        internal static MoveContent Execute(Board examineBoard, List <Board> positions, int depth, List <OpeningMove> currentGameBook)
        {
            List <Position> pvChild = new List <Position>();
            int             alpha   = -400000000;
            const int       beta    = 400000000;

            MoveContent bestMove = new MoveContent();

            int nodesSearched   = 0;
            int nodesQuiessence = 0;

            //Can I make an instant mate?
            foreach (Board pos in positions)
            {
                //TODO: Send each (or in packs of few i.e.) board to different process, and finish if any returned bigger value
                int value = -AlphaBeta(pos, 1, -beta, -alpha, ref nodesSearched, ref nodesQuiessence, ref pvChild, true);

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

            int currentBoard = 0;

            alpha = -400000000;

            positions.Sort(Sort);

            depth--;

            int plyDepthReached = ModifyDepth((byte)depth, positions.Count());

            foreach (Board pos in positions)
            {
                currentBoard++;

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

                pvChild = new List <Position>();

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

                if (value >= 32767)
                {
                    pos.LastMove.Score = value;
                    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)
                {
                    alpha          = value;
                    bestMove       = pos.LastMove;
                    bestMove.Score = value;
                }
            }

            plyDepthReached++;
            progress = 100;

            return(bestMove);
        }
Esempio n. 25
0
        internal static MoveContent IterativeSearch(Board examineBoard, byte depth, List <OpeningMove> currentGameBook)
        {
            Intracommunicator comm = Communicator.world;
            int numOfTasks         = comm.Size;

            MoveContent bestMove = new MoveContent();

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

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

            int numOfPositions          = succ.Positions.Count;
            int positionsChunkSizeWhole = numOfPositions / numOfTasks;
            int positionsChunkSizeRest  = numOfPositions - numOfTasks * positionsChunkSizeWhole;


            int[] tasksPosChunkSize = new int[numOfTasks];
            for (int i = 0; i < numOfTasks; i++)
            {
                tasksPosChunkSize[i] = positionsChunkSizeWhole;
                if (positionsChunkSizeRest > 0)
                {
                    tasksPosChunkSize[i] += 1;
                    positionsChunkSizeRest--;
                }
            }

            List <List <Board> > tasksPos = new List <List <Board> >();

            int idx = 0;

            for (int i = 0; i < numOfTasks; i++)
            {
                tasksPos.Add(succ.Positions.GetRange(idx, tasksPosChunkSize[i]));
                idx += tasksPosChunkSize[i];
            }

            List <InterProcessData> dataToSend = new List <InterProcessData>();

            for (int i = 0; i < numOfTasks; i++)
            {
                dataToSend.Add(new InterProcessData
                {
                    pos          = tasksPos[i],
                    depth        = depth,
                    GameBook     = currentGameBook,
                    ExamineBoard = examineBoard
                });
            }

            for (int i = 1; i < numOfTasks; i++)
            {
                comm.Send <InterProcessData>(dataToSend[i], i, 0);
            }

            DateTime startDate = DateTime.Now;

            MoveContent        thisThreadBestMove = Execute(examineBoard, dataToSend[0].pos, dataToSend[0].depth, currentGameBook);
            List <MoveContent> bestMoves          = new List <MoveContent>();

            bestMoves.Add(thisThreadBestMove);

            for (int i = 1; i < numOfTasks; i++)
            {
                bestMoves.Add(comm.Receive <MoveContent>(i, 0));
            }

            DateTime endDate   = DateTime.Now;
            long     msElapsed = (endDate.Ticks - startDate.Ticks) / 10000;

            Console.WriteLine("Elapsed AI search time: " + msElapsed.ToString() + " ms");

            return(bestMoves.OrderByDescending(m => m.Score).First());
        }
Esempio n. 26
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);
        }