예제 #1
0
 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();
 }
예제 #2
0
        protected AIOption ChooseOption()
        {
            if (UtilityAiBrain == null)
            {
                return(null);
            }
            UtilityAiBrain.GetNodes <EntryNode>().ForEach(node => node.SetContext(this));
            UtilityAiBrain.GetNodes <ActionNode>().ForEach(node => node.SetContext(this));
            // Fill the Ranked Options
            Options = new List <AIOption>();
            UtilityAiBrain.GetNodes <OptionNode>().ForEach(node => Options.AddRange(node.GetOptions()));
            // Remove ImpossibleDecisionValue Ranks
            Options.RemoveAll(option => option.Rank <= 0f);
            if (Options.Count == 0)
            {
                return(null);
            }
            // Get max Rank
            int maxRank = Options.Max(option => option.Rank);

            for (int i = maxRank; i > 0; i--)
            {
                List <AIOption> options = Options.FindAll(utility => utility.Rank == i);
                if (options.Count == 0 || options.Sum(utility => utility.Utility) <= 0)
                {
                    continue;
                }
                // Calculating Weight
                options.ForEach(dualUtility => dualUtility.Weight = dualUtility.Utility / Options.Sum(utility => utility.Utility));
                // Rolling probability on weighted random
                LastProbabilityResult = Random.Range(0f, 1f);
                float weightSum = 0f;
                foreach (AIOption dualUtility in options)
                {
                    weightSum += dualUtility.Weight;
                    if (weightSum >= LastProbabilityResult)
                    {
                        return(dualUtility);
                    }
                }
            }
            return(null);
        }