Esempio n. 1
0
    private N_CompositionNode RandomComp()
    {
        N_CompositionNode randomComp;
        int randomComposition = UnityEngine.Random.Range(0, 3);

        switch (randomComposition)
        {
        case 0:
            randomComp = new N_Selection();
            break;

        case 1:
            randomComp = new N_Sequence();
            break;

        case 2:
            randomComp = new N_ProbabilitySelector();
            break;

        default:
            randomComp = null;
            Debug.LogError("No comp was chosen for generation of BT.");
            break;
        }
        return(randomComp);
    }
Esempio n. 2
0
    // Sequence for moving by patroling or kiting.
    // If an enemy is spotted, there's a probability of the agent either patroling.
    // or kiting. If no enemy, always patrol.
    // Returns success if path found and started.
    // Returns running if in process of walking towards destination.
    public static Node Tree_PatrolOrKite(N_AgentNode.AgentType agent)
    {
        N_ProbabilitySelector kiteOrPatrol = new N_ProbabilitySelector();

        kiteOrPatrol.AddLast(new N_Kite(agent));
        kiteOrPatrol.AddLast(new N_Patrol(agent));
        //N_DecSuccess kiteOrPatrolSuccess = new N_DecSuccess(kiteOrPatrol);

        N_Sequence enemyThenKiteOrPatrol = new N_Sequence();

        enemyThenKiteOrPatrol.AddLast(new N_IsEnemyVisible(agent));
        enemyThenKiteOrPatrol.AddLast(kiteOrPatrol);

        //N_DecSuccess patrolSuccess = new N_DecSuccess(new N_Patrol(agent));
        N_Selection enemyOrPatrol = new N_Selection();

        enemyOrPatrol.AddLast(enemyThenKiteOrPatrol);
        enemyOrPatrol.AddLast(new N_Patrol(agent));

        enemyOrPatrol.IsSubtree = true;
        return(enemyOrPatrol);
    }
Esempio n. 3
0
    // Assign random mutations to the given tree.
    protected void Mutate(N_Root child)
    {
        // First, check if there'll be any mutation at all.
        float random = UnityEngine.Random.Range(0.0f, 1.0f);

        if (random < mutationRate)
        {
            List <Node> thresholds = TreeOperations.RetrieveNodesOfType(child, typeof(N_Threshold));
            List <Node> probNodes  = TreeOperations.RetrieveNodesOfType(child, typeof(N_ProbabilitySelector));

            // Randomise between whether to change thresholds or probabilities
            random = UnityEngine.Random.Range(0.0f, 1.0f);
            // If no probnode exists, change condition if there are any instead
            if ((random <= 0.25f && thresholds.Count > 0))
            {
                //Debug.Log("Changing threshold!");
                // Get random index within range of list
                int         index  = UnityEngine.Random.Range(0, thresholds.Count);
                N_Threshold thresh = thresholds[index] as N_Threshold;

                // Mutate threshold by random offset
                int offset = UnityEngine.Random.Range(minThresholdOffset, maxTresholdOffset);
                thresh.SetThreshold(thresh.Threshold + offset);
            }
            else if (random > 0.25f && random <= 0.5f && probNodes.Count > 0) // Adjust relative probabilities on a probability selector.
            {
                //Debug.Log("Changing prob!");
                // Get random index within range of list
                int index = UnityEngine.Random.Range(0, probNodes.Count);
                N_ProbabilitySelector probSelect = probNodes[index] as N_ProbabilitySelector;

                // Check so that the probablitySelector has any children.
                if (probSelect.GetChildren().Count <= 0)
                {
                    return;
                }

                // Calculate total probability and retrieve a relative offset based on it.
                float totalProb = 0.0f;
                foreach (Node n in probSelect.GetChildren())
                {
                    totalProb += probSelect.GetProbabilityWeight(n);
                }
                float offset = totalProb * (relativeProbabilityMutation / 100.0f);
                // Also, get a random sign to decide whether to substract or add offset
                // and a random index for which child to be changed.
                float randomSign       = Mathf.Sign(UnityEngine.Random.Range(-1.0f, 1.0f));
                int   randomChildIndex = UnityEngine.Random.Range(0, probSelect.GetChildren().Count);

                // Finally, offset the given childs probability by the random amount.
                probSelect.OffsetProbabilityWeight(probSelect.GetChildren()[randomChildIndex]
                                                   , offset * randomSign);
            }
            else if (random > 0.5f && random <= 0.75f) // Change subtree
            {
                //Debug.Log("Changing subtree!");
                List <Node>       subtrees    = TreeOperations.RetrieveSubtreeNodes(child);
                int               randomIndex = UnityEngine.Random.Range(0, subtrees.Count);
                Node              subtree     = subtrees[randomIndex];
                N_CompositionNode parentComp  = subtree.Parent as N_CompositionNode;

                // Get a random subtree index and replace its position in the tree with
                // a new randomized subtree instead.
                parentComp.ReplaceChild(subtree, RandomSubtree());
            }
            else if (random > 0.75f) // Change composition
            {
                //Debug.Log("Changing composition!");
                List <Node>       comps       = TreeOperations.RetrieveNodesOfType(child, typeof(N_CompositionNode));
                int               randomIndex = UnityEngine.Random.Range(0, comps.Count);
                N_CompositionNode replaceComp = comps[randomIndex] as N_CompositionNode;

                // If parent is null, this comp is the initial comp.
                if (replaceComp.Parent != null)
                {
                    Node        compParent = replaceComp.Parent;
                    List <Node> children   = replaceComp.GetChildren();

                    // Attach old comps children to the new one.
                    N_CompositionNode newComp = RandomComp();
                    // Make sure to keep structure of subtrees
                    if (replaceComp.IsSubtree)
                    {
                        newComp.IsSubtree = true;
                    }

                    foreach (Node c in children)
                    {
                        c.Parent = newComp;
                        newComp.AddLast(c);
                    }

                    // Reattach parent to the new comp
                    if (compParent.GetType().IsSubclassOf(typeof(N_CompositionNode)))
                    {
                        N_CompositionNode compParent_comp = compParent as N_CompositionNode;
                        compParent_comp.ReplaceChild(replaceComp, newComp);
                    }
                    else if (compParent.GetType().IsSubclassOf(typeof(N_Decorator)))
                    {
                        N_Decorator compParent_dec = compParent as N_Decorator;
                        compParent_dec.Child = newComp;
                    }
                }
            }
        }
    }