Пример #1
0
        // ThreadsManager::start_searching() wakes up the main thread sleeping in
        // main_loop() so to start a new search, then returns immediately.
        internal static void start_searching(Position pos, LimitsType limits, List <Move> searchMoves)
        {
            wait_for_search_finished();

            Search.SearchTime.Reset(); Search.SearchTime.Start(); // As early as possible

            Search.SignalsStopOnPonderhit = Search.SignalsFirstRootMove = false;
            Search.SignalsStop            = Search.SignalsFailedLowAtRoot = false;

            Search.RootPosition.copy(pos);
            Search.Limits = limits;
            Search.RootMoves.Clear();

            MList mlist = MListBroker.GetObject(); mlist.pos = 0;

            Movegen.generate_legal(pos, mlist.moves, ref mlist.pos);
            for (int i = 0; i < mlist.pos; i++)
            {
                Move move = mlist.moves[i].move;
                if ((searchMoves.Count == 0) || Utils.existSearchMove(searchMoves, move))
                {
                    Search.RootMoves.Add(new RootMove(move));
                }
            }
            MListBroker.Free();

            main_thread().do_sleep = false;
            main_thread().wake_up();
        }
Пример #2
0
        /// Mate with KX vs K. This function is used to evaluate positions with
        /// King and plenty of material vs a lone king. It simply gives the
        /// attacking side a bonus for driving the defending king towards the edge
        /// of the board, and for keeping the distance between the two kings small.
        /// KXK
        internal static Value Endgame_KXK(Color strongerSide, Position pos)
        {
            Color weakerSide = strongerSide ^ 1;

            Debug.Assert(pos.non_pawn_material(weakerSide) == ValueC.VALUE_ZERO);
            Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.PAWN) == ValueC.VALUE_ZERO);

            // Stalemate detection with lone king
            MList mlist = MListBroker.GetObject(); mlist.pos = 0;
            Movegen.generate_legal(pos, mlist.moves, ref mlist.pos);
            bool any = mlist.pos > 0;
            MListBroker.Free();

            if (pos.sideToMove == weakerSide
                && !pos.in_check()
                && !any)
            {
                return ValueC.VALUE_DRAW;
            }

            Square winnerKSq = pos.king_square(strongerSide);
            Square loserKSq = pos.king_square(weakerSide);

            Value result = pos.non_pawn_material(strongerSide)
                           + pos.piece_count(strongerSide, PieceTypeC.PAWN) * Constants.PawnValueEndgame
                           + MateTable[loserKSq]
                           + DistanceBonus[Utils.square_distance(winnerKSq, loserKSq)];

            if (pos.piece_count(strongerSide, PieceTypeC.QUEEN)!=0
            || pos.piece_count(strongerSide, PieceTypeC.ROOK)!=0
            || pos.bishop_pair(strongerSide))
            {

                result += ValueC.VALUE_KNOWN_WIN;
            }

            return strongerSide == pos.sideToMove ? result : -result;
        }
Пример #3
0
        /// Book::probe() tries to find a book move for the given position. If no move
        /// is found returns MOVE_NONE. If pickBest is true returns always the highest
        /// rated move, otherwise randomly chooses one, based on the move score.
        internal static Move probe(Position pos, string filename, bool pickBest)
        {
#if PORTABLE
            #region DLL book

            if (bookNotExists)
            {
                return(MoveC.MOVE_NONE);
            }

            BookEntry e    = new BookEntry();
            UInt16    best = 0;
            uint      sum  = 0;
            Move      move = MoveC.MOVE_NONE;
            UInt64    key  = book_key(pos);

            try
            {
                System.Reflection.Assembly bookAssembly = System.Reflection.Assembly.Load("PortfishBook");
                using (Stream fs = bookAssembly.GetManifestResourceStream("PortfishBook.book.bin"))
                {
                    UInt64 size = (UInt64)(fs.Length / SIZE_OF_BOOKENTRY);
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                        binary_search(key, size, br);
                        while (Read(ref e, br) && (e.key == key))
                        {
                            best = Math.Max(best, e.count);
                            sum += e.count;

                            // Choose book move according to its score. If a move has a very
                            // high score it has higher probability to be choosen than a move
                            // with lower score. Note that first entry is always chosen.
                            if ((RKiss.rand() % sum < e.count) ||
                                (pickBest && e.count == best))
                            {
                                move = e.move;
                            }
                        }
                    }
                }
            }
            catch (System.IO.FileNotFoundException)
            {
                bookNotExists = true;
                return(MoveC.MOVE_NONE);
            }

            #endregion
#else
            #region File system read

            if (!System.IO.File.Exists(filename))
            {
                return(MoveC.MOVE_NONE);
            }

            BookEntry e    = new BookEntry();
            UInt16    best = 0;
            uint      sum  = 0;
            Move      move = MoveC.MOVE_NONE;
            UInt64    key  = book_key(pos);

            using (FileStream fs = new FileStream(filename, FileMode.Open))
            {
                UInt64 size = (UInt64)(fs.Length / SIZE_OF_BOOKENTRY);
                using (BinaryReader br = new BinaryReader(fs))
                {
                    binary_search(key, size, br);
                    while (Read(ref e, br) && (e.key == key))
                    {
                        best = Math.Max(best, e.count);
                        sum += e.count;

                        // Choose book move according to its score. If a move has a very
                        // high score it has higher probability to be choosen than a move
                        // with lower score. Note that first entry is always chosen.
                        if (((sum != 0) && (RKiss.rand() % sum < e.count)) ||
                            (pickBest && e.count == best))
                        {
                            move = e.move;
                        }
                    }
                    br.Close();
                }
                fs.Close();
            }

            #endregion
#endif

            if (move != 0)
            {
                // A PolyGlot book move is encoded as follows:
                //
                // bit  0- 5: destination square (from 0 to 63)
                // bit  6-11: origin square (from 0 to 63)
                // bit 12-14: promotion piece (from KNIGHT == 1 to QUEEN == 4)
                //
                // Castling moves follow "king captures rook" representation. So in case book
                // move is a promotion we have to convert to our representation, in all the
                // other cases we can directly compare with a Move after having masked out
                // the special Move's flags (bit 14-15) that are not supported by PolyGlot.
                int pt = (move >> 12) & 7;
                if (pt != 0)
                {
                    move = Utils.make_promotion(Utils.from_sq(move), Utils.to_sq(move), (pt + 1));
                }

                // Add 'special move' flags and verify it is legal
                MList mlist = MListBroker.GetObject(); mlist.pos = 0;
                Movegen.generate_legal(pos, mlist.moves, ref mlist.pos);
                for (int i = 0; i < mlist.pos; i++)
                {
                    if (move == (mlist.moves[i].move & 0x3FFF))
                    {
                        Move retval = mlist.moves[i].move;
                        MListBroker.Free();
                        return(retval);
                    }
                }
                MListBroker.Free();
            }

            return(MoveC.MOVE_NONE);
        }
Пример #4
0
        internal static void Warmup()
        {
            // Bench 128 4 17 yields:

            // CheckInfoBroker: 140 (4/32/40/32/32)
            // EvalInfoBroker: 16 (4/4/4/4)
            // SwapListBroker: 16 (4/4/4/4)
            // MovesSearchedBroker: 120 (28/36/28/28)
            // PositionBroker: 32 (8/8/8/8)
            // StateInfoArrayBroker: 16 (4/4/4/4)

            // MListBroker: 20 (4/4/4/4/4)
            // LoopStackBroker: 32 (8/8/8/8)
            // MovePickerBroker: 136 (32/40/32/32)
            // StateInfoBroker: 132 (32/36/32/32)

            // Specific allocation not to overallocate memory for nothing
            int i, brokerSize;

            // Reusing brokers
            brokerSize = 40; for (i = 0; i < brokerSize; i++)
            {
                CheckInfoBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                CheckInfoBroker.Free();
            }
            brokerSize = 4; for (i = 0; i < brokerSize; i++)
            {
                EvalInfoBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                EvalInfoBroker.Free();
            }
            brokerSize = 4; for (i = 0; i < brokerSize; i++)
            {
                SwapListBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                SwapListBroker.Free();
            }
            brokerSize = 36; for (i = 0; i < brokerSize; i++)
            {
                MovesSearchedBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                MovesSearchedBroker.Free();
            }
            brokerSize = 8; for (i = 0; i < brokerSize; i++)
            {
                PositionBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                PositionBroker.Free();
            }
            brokerSize = 4; for (i = 0; i < brokerSize; i++)
            {
                StateInfoArrayBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                StateInfoArrayBroker.Free();
            }
            brokerSize = 4; for (i = 0; i < brokerSize; i++)
            {
                MListBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                MListBroker.Free();
            }
            brokerSize = 36; for (i = 0; i < brokerSize; i++)
            {
                StateInfoBroker.GetObject();
            }
            for (i = 0; i < brokerSize; i++)
            {
                StateInfoBroker.Free();
            }

            // Recycling brokers
            brokerSize = 8; LoopStack[] arrLoopStack = new LoopStack[brokerSize]; for (i = 0; i < brokerSize; i++)
            {
                arrLoopStack[i] = LoopStackBroker.GetObject();
            }
            for (i = brokerSize - 1; i >= 0; i--)
            {
                LoopStackBroker.Free(arrLoopStack[i]);
            }
            brokerSize = 40; MovePicker[] arrMovePicker = new MovePicker[brokerSize]; for (i = 0; i < brokerSize; i++)
            {
                arrMovePicker[i] = MovePickerBroker.GetObject();
            }
            for (i = brokerSize - 1; i >= 0; i--)
            {
                MovePickerBroker.Free(arrMovePicker[i]);
            }
        }