Пример #1
0
        /// <summary>
        /// Analyzes a position until a specified search limit is exhausted.
        /// </summary>
        /// <param name="fen">a FEN</param>
        /// <param name="nodes"></param>
        /// <returns></returns>
        public LC0VerboseMoveStats AnalyzePositionFromFENAndMoves(string startFEN, string movesStr, string endFEN,
                                                                  SearchLimit searchLimit)
        {
            Position positionEnd            = Position.FromFEN(endFEN);
            List <LC0VerboseMoveStat> moves = new List <LC0VerboseMoveStat>();

            UCISearchInfo searchInfo;

            int searchValueMilliseconds = (int)((float)searchLimit.Value * 1000.0f);

            switch (searchLimit.Type)
            {
            case SearchLimitType.NodesPerMove:
                searchInfo = Runner.EvalPositionToNodes(startFEN, movesStr, (int)searchLimit.Value);
                break;

            case SearchLimitType.SecondsPerMove:
                searchInfo = Runner.EvalPositionToMovetime(startFEN, movesStr, searchValueMilliseconds);
                break;

            case SearchLimitType.NodesForAllMoves:
                throw new Exception("NodesForAllMoves not supported for Leela Chess Zero");

            case SearchLimitType.SecondsForAllMoves:
                bool weAreWhite = positionEnd.MiscInfo.SideToMove == SideType.White;

                searchInfo = Runner.EvalPositionRemainingTime(startFEN, movesStr,
                                                              weAreWhite,
                                                              searchLimit.MaxMovesToGo,
                                                              (int)(searchLimit.Value * 1000),
                                                              (int)(searchLimit.ValueIncrement * 1000));
                break;

            default:
                throw new Exception($"Unknown SeachLimit.Type {searchLimit.Type}");
            }

            double elapsed = 0;//engine.EngineProcess.TotalProcessorTime.TotalSeconds - startTime;

            // no more, we now assume  win_percentages is requested     LeelaVerboseMoveStats ret = new LeelaVerboseMoveStats(positionEnd, searchInfo.BestMove, elapsed, searchInfo.Nodes, LZPositionEvalLogistic.CentipawnToLogistic2018(searchInfo.Score));
            float scoreLogistic     = searchInfo.ScoreLogistic;
            LC0VerboseMoveStats ret = new LC0VerboseMoveStats(positionEnd, searchInfo.BestMove, elapsed, searchInfo.Nodes, scoreLogistic, searchInfo);

            searchInfo.Infos.Reverse();
            foreach (string info in searchInfo.Infos)
            {
                if (info.Contains("P:"))
                {
                    moves.Add(new LC0VerboseMoveStat(ret, info));
                }
            }

            ret.SetMoves(moves);

            return(LastAnalyzedPositionStats = ret);
        }
Пример #2
0
        protected override GameEngineSearchResult DoSearch(PositionWithHistory curPositionAndMoves,
                                                           SearchLimit searchLimit,
                                                           List <GameMoveStat> gameMoveHistory, ProgressCallback callback,
                                                           bool verbose)
        {
            DoSearchPrepare();

            bool weAreWhite = curPositionAndMoves.FinalPosition.MiscInfo.SideToMove == SideType.White;

            UCISearchInfo gameInfo;

            switch (searchLimit.Type)
            {
            case SearchLimitType.SecondsPerMove:
                gameInfo = UCIRunner.EvalPositionToMovetime(curPositionAndMoves.FENAndMovesString, (int)(searchLimit.Value * 1000));
                break;

            case SearchLimitType.NodesPerMove:
                gameInfo = UCIRunner.EvalPositionToNodes(curPositionAndMoves.FENAndMovesString, (int)(searchLimit.Value));
                break;

            case SearchLimitType.NodesForAllMoves:
                using (new TimingBlock(new TimingStats(), TimingBlock.LoggingType.None))
                {
                    gameInfo = UCIRunner.EvalPositionRemainingNodes(curPositionAndMoves.FENAndMovesString,
                                                                    weAreWhite,
                                                                    searchLimit.MaxMovesToGo,
                                                                    (int)(searchLimit.Value),
                                                                    (int)(searchLimit.ValueIncrement));
                }

                break;

            case SearchLimitType.SecondsForAllMoves:
                using (new TimingBlock(new TimingStats(), TimingBlock.LoggingType.None))
                {
                    gameInfo = UCIRunner.EvalPositionRemainingTime(curPositionAndMoves.FENAndMovesString,
                                                                   weAreWhite,
                                                                   searchLimit.MaxMovesToGo,
                                                                   (int)(searchLimit.Value * 1000),
                                                                   (int)(searchLimit.ValueIncrement * 1000));
                }

                break;

            default:
                throw new NotSupportedException($"Unsupported MoveType {searchLimit.Type}");
            }

            float q = EncodedEvalLogistic.CentipawnToLogistic(gameInfo.ScoreCentipawns);

            return(new GameEngineSearchResult(gameInfo.BestMove, q, gameInfo.ScoreCentipawns, float.NaN, searchLimit, default, 0, (int)gameInfo.Nodes, gameInfo.Depth));