Example #1
0
        /// <summary>
        /// Traversal of <see cref="DecisionTree"/> is done by recusrively calling the <see cref="ADecisionNode.TreeTraversal(ADecisionNode)"/>.
        /// </summary>
        public static RefList <AIDecisionTreeChoice> traverseDecisionTree(DecisionTree p_decisionTree)
        {
            RefList <AIDecisionTreeChoice> l_choices = new RefList <AIDecisionTreeChoice>();

            RefList <TraversalStack> l_traversalStacks = new RefList <TraversalStack>();

            l_traversalStacks.Add(TraversalStack.build(p_decisionTree.RootNode));

            while (l_traversalStacks.Count > 0)
            {
                ref TraversalStack l_currentTraversalStack = ref l_traversalStacks.ValueRef(l_traversalStacks.Count - 1);
                //If there if the current node has links
                if (l_currentTraversalStack.DecisionNode.LinkedNodes != null)
                {
                    if (l_currentTraversalStack.LinkIterationCounter < l_currentTraversalStack.DecisionNode.LinkedNodes.Count)
                    {
                        //We traverse the link and go one level deeper
                        ADecisionNode l_nextNode = l_currentTraversalStack.DecisionNode.LinkedNodes[l_currentTraversalStack.LinkIterationCounter];

                        l_currentTraversalStack.LinkIterationCounter += 1;
                        TraversalStack l_oneLevelDepperStack = TraversalStack.build(l_nextNode);
                        l_traversalStacks.AddRef(ref l_oneLevelDepperStack);

                        l_nextNode.TreeTraversal(l_currentTraversalStack.DecisionNode);
                    }
                    else
                    {
                        #region Updating stack

                        l_traversalStacks.RemoveAt(l_traversalStacks.Count - 1);

                        #endregion
                    }
                }
                else // No links have been found, this means that the current node is a leaf node.
                {
                    #region Creating the choice as the current node is a leaf

                    ADecisionNode[] l_choiceNodes = new ADecisionNode[l_traversalStacks.Count];
                    for (int i = 0; i < l_traversalStacks.Count; i++)
                    {
                        l_choiceNodes[i] = l_traversalStacks.ValueRef(i).DecisionNode;
                    }

                    AIDecisionTreeChoice l_choice = AIDecisionTreeChoice.build(l_choiceNodes);
                    l_choices.AddRef(ref l_choice);

                    #endregion

                    l_traversalStacks.RemoveAt(l_traversalStacks.Count - 1);
                }
            }
Example #2
0
        /// <summary>
        /// Picking the best choice between <paramref name="p_choices"/>.
        /// The choice is made by associating a score to every choices. The choice with the highest score is picked.
        /// </summary>
        /// <param name="p_choices"> Compared choices. </param>
        /// <returns> The picked choice </returns>
        public static ref AIDecisionTreeChoice defaultTestPickChoice(RefList <AIDecisionTreeChoice> p_choices, Entity p_calledEntity)
        {
            // Becuase PathScore represents the distance crossed and that we want to minimize movement,
            // we normalize the PathScore by it's potential maxmimum value calculated if the Entity were using all it's ActionPoints to move.
            ActionPoint l_calledEntityActionPoint      = EntityComponent.get_component <ActionPoint>(p_calledEntity);
            float       l_maxPathScoreThatCanBeCrossed = _ActionPoint.Calculations.actionPointToCrossableWorldDistance(l_calledEntityActionPoint.ActionPointData.CurrentActionPoints);


            RefList <AIDecisionScore> l_choiceScores = new RefList <AIDecisionScore>(p_choices.Count);

            for (int i = 0; i < p_choices.Count; i++)
            {
                AIDecisionScore l_choiceScore = AIDecisionScore.build();

                ref AIDecisionTreeChoice l_aIDecisionTreeChoice = ref p_choices.ValueRef(i);

                for (int j = 0; j < l_aIDecisionTreeChoice.DecisionNodesChoiceOrdered.Length; j++)
                {
                    switch (l_aIDecisionTreeChoice.DecisionNodesChoiceOrdered[j])
                    {
                    case MoveToNavigationNodeNode l_moveToNavigationNodeNode:
                    {
                        l_choiceScore.PathScore += math.max(l_maxPathScoreThatCanBeCrossed - l_moveToNavigationNodeNode.PathCost, 0.0f);
                        break;
                    }

                    case AttackNode l_attackNode:
                    {
                        l_choiceScore.DamageScore += l_attackNode.DamageDone;
                        break;
                    }

                    case HealNode l_healNode:
                    {
                        l_choiceScore.HealScore += l_healNode.RecoveredHealth;
                        break;
                    }
                    }
                }

                l_choiceScores.AddRef(ref l_choiceScore);
            }