public SearchResult Evaluate(IState startState, SearchContext searchContext) { if (startState.Turn == Player.Empty) { throw new EmptyPlayerException(nameof(startState.Turn) + " can't be " + nameof(Player.Empty)); } if (searchContext.CurrentDepth > 0) { var cachedResult = CheckCacheForEvaluation(startState, searchContext); if (cachedResult != null) { return(cachedResult); } } if (searchOptions.Pruners.Any(pruner => pruner.ShouldPrune(startState, searchContext.CurrentDepth, searchContext.StatesUpTillNow))) { var evaluation = startState.Evaluate(searchContext.CurrentDepth, searchContext.StatesUpTillNow, searchOptions); return(new SearchResult(evaluation, startState, true, true, false)); } if (ShouldStop(startState, searchContext)) { var evaluation = startState.Evaluate(searchContext.CurrentDepth, searchContext.StatesUpTillNow, searchOptions); return(new SearchResult(evaluation, new List <IState> { startState }, 1, 0, false, false, false)); } SearchResult result; switch (startState) { case IDeterministicState deterministicState: result = deterministicSearchUtils.EvaluateChildren(deterministicState, searchContext); break; case IProbabilisticState probabilisticState: result = probabilisticSearchUtils.EvaluateChildren(probabilisticState, searchContext); break; default: throw new BadStateTypeException($"State must implement {nameof(IDeterministicState)} or {nameof(IProbabilisticState)}"); } AddResultToCach(startState, searchContext.CurrentDepth, searchContext.StatesUpTillNow, result); return(result); }
public SearchResult EvaluateChildren(IProbabilisticState startState, SearchContext searchContext) { var neighbors = startState.GetNeighbors().ToArray(); if (!neighbors.Any()) { var evaluation = startState.Evaluate(searchContext.CurrentDepth, searchContext.StatesUpTillNow, searchOptions); return(new SearchResult(evaluation, startState)); } var storedStates = new ConcurrentDictionary <IState, double>(); var results = new List <Tuple <double, Task <SearchResult> > >(); foreach (var neighbor in neighbors) { var wrappedState = new ProbablisticStateWrapper(neighbor.Item2, startState); var searchResult = threadManager.Invoke(() => deterministicSearchUtils.EvaluateChildren(wrappedState, searchContext.CloneWithMaxAlphaAndBeta(), storedStates), searchContext.CurrentDepth); results.Add(new Tuple <double, Task <SearchResult> >(neighbor.Item1, searchResult)); } return(Reduce(results, startState)); }