private AIOption ChooseOption(AbstractAIBrain abstractAiBrain) { // Calcul maxWeight and return null if equal to zero int maxWeight = Options[abstractAiBrain].Max(option => option.Weight); if (maxWeight == 0) { return(null); } // Returning best option for no random if (AlwaysPickBestChoice) { return(Options[abstractAiBrain].FirstOrDefault()); } // Rolling probability on weighted random _lastProbabilityResult = Random.Range(0f, 1f); float probabilitySum = 0f; foreach (AIOption dualUtility in Options[abstractAiBrain].FindAll(option => option.Weight == maxWeight)) { probabilitySum += dualUtility.Probability; if (probabilitySum >= _lastProbabilityResult) { return(dualUtility); } } return(null); }
private void CalculateOptions(AbstractAIBrain utilityAiBrain) { if (utilityAiBrain == null) { return; } // Setup Contexts utilityAiBrain.GetNodes <EntryNode>().ForEach(node => node.SetContext(this)); utilityAiBrain.GetNodes <ActionNode>().ForEach(node => node.SetContext(this)); // Add the brain to the option dictionary if (Options.ContainsKey(utilityAiBrain)) { Options[utilityAiBrain].Clear(); } else { Options.Add(utilityAiBrain, new List <AIOption>()); } utilityAiBrain.GetNodes <OptionNode>().ForEach(node => Options[utilityAiBrain] .AddRange(node.GetOptions())); // Return if no option found if (Options[utilityAiBrain].Count == 0) { return; } // Calculate Probability foreach (AIOption aiOption in Options[utilityAiBrain]) { aiOption.Probability = aiOption.Utility / Options[utilityAiBrain] .Where(option => option.Weight == aiOption.Weight) .Sum(option => option.Utility); } // Order by Weight then Utility Options[utilityAiBrain] = Options[utilityAiBrain].OrderByDescending(option => option.Weight).ThenByDescending(option => option.Utility).ToList(); }