public Population(List <List <float> > initialWeights = null)
    {
        Individuals           = new List <Individual>();
        ParentGameObject      = new GameObject();
        ParentGameObject.name = "Individuals";

        if (initialWeights != null)
        {
            for (int i = 0; i < initialWeights.Count; i++)
            {
                Individuals.Add(new Individual(new DNA(initialWeights[i])));
                Individuals[i].Index = i;
                Individuals[i].CreateGameObject();
                Individuals[i].GameObject.transform.SetParent(ParentGameObject.transform);
            }
        }
        else
        {
            initialWeights = new List <List <float> >(); //initializes it so it will be 0 on the for statement below
        }

        for (var i = initialWeights.Count; i < ConfigManager.config.geneticAlgorithm.nIndividuals; i++)
        {
            Individuals.Add(new Individual(new DNA(NeuralNetworkHelper.GetWeightsNumberFromConfig())));
            Individuals[i].Index = i;
            Individuals[i].CreateGameObject();
            Individuals[i].GameObject.transform.SetParent(ParentGameObject.transform);
        }
    }
Пример #2
0
        private void StartTraining()
        {
            var(inputData, expectedOutputData) = NeuralNetworkHelper.ReduceDataset(
                humanCar.StateInputMeasurements.ToList(),
                humanCar.StateOutputMeasurements.ToList());

            for (int i = 0; i < inputData.Count(); i++)
            {
                if (inputData[i].All(d => d == 0))
                {
                    inputData.RemoveAt(i);
                    expectedOutputData.RemoveAt(i);

                    i--;
                }
            }

            notificationService.ShowToast(
                ToastType.Info,
                "Training Started...");

            // Right now the training happens so fast, not sure if we need to be reporting progress
            network = NeuralNetworkHelper.GetTrainedNetwork(inputData, expectedOutputData, (c, t) => { });

            notificationService.ShowToast(
                ToastType.Info,
                "Training Complete.");
        }
Пример #3
0
        private void checkEnemies()
        {
            // If the sight range is negative, do nothing.
            if (SightRange <= 0)
            {
                return;
            }

            // Add the passed time to the time since the last check.
            timeSinceLastSightCheck += Time.fixedDeltaTime;

            if (timeSinceLastSightCheck >= TimeBetweenSightChecks)
            {
                // Finds all creature colliders in the area around this creature.
                int seenCreaturesCount = Physics.OverlapSphereNonAlloc(eyeOrigin.position, SightRange, seenColliders, 1 << LayerMask.NameToLayer("Creatures"));

                // Clear the seen enemies list and fill it with all enemies in the colliders collection.
                seenEnemies.Clear();
                for (int i = 0; i < seenCreaturesCount; i++)
                {
                    if (seenColliders[i] != null && seenColliders[i].TryGetComponent(out Creature creature) && creature.Player != Creature.Player)
                    {
                        seenEnemies.Add(new CreatureTarget()
                        {
                            Target             = creature,
                            TargetRigidbody    = creature.GetComponent <Rigidbody>(),
                            TargetCollider     = seenColliders[i],
                            NormalisedDistance = NeuralNetworkHelper.ExpandRangeToNegative(Vector3.Distance(eyeOrigin.position, seenColliders[i].ClosestPoint(eyeOrigin.position)) / SightRange),
                            NormalisedHealth   = NeuralNetworkHelper.ExpandRangeToNegative(creature.Health / maxHealth)
                        });
                    }
                }

                // Sort the enemies based on the score using the mutated filters.
                seenEnemies.Sort((firstEnemy, secondEnemy) =>
                {
                    // Calculate the scores for both enemies.
                    float firstScore  = (float)Math.Tanh(Bias + firstEnemy.NormalisedHealth * HealthWeight + firstEnemy.NormalisedDistance * DistanceWeight);
                    float secondScore = (float)Math.Tanh(Bias + secondEnemy.NormalisedHealth * HealthWeight + secondEnemy.NormalisedDistance * DistanceWeight);

                    // Return the result of the compare function.
                    return(firstScore.CompareTo(secondScore));
                });

                // Set the max concurrent seen creatures if the number of seen creatures is higher than the old value.
                setLifetimeStat("MaxConcurrentSeenCreatures", (uint)Math.Max(LifetimeStats["MaxConcurrentSeenCreatures"], seenEnemies.Count));

                // If enemies were seen, take the last one (the one with the highest score) and set the current target to it, otherwise set the current target to null.
                CurrentTarget = (seenEnemies.Count > 0) ? seenEnemies[seenEnemies.Count - 1] : (CreatureTarget?)null;

                if (seenCreaturesCount == seenColliders.Length)
                {
                    Array.Resize(ref seenColliders, seenColliders.Length + 10);
                }

                // Reset the timer.
                timeSinceLastSightCheck = 0;
            }
        }
Пример #4
0
    private void FeedForward(int layerIndex)
    {
        var layer = Layers[layerIndex];
        var input = Layers[layerIndex - 1].Select(neuron => neuron.Output).ToArray();

        foreach (var neuron in layer)
        {
            var weightedSum = neuron.InputSynapses
                              .Select((synapse, synapseIndex) => synapse.Weight * input[synapseIndex])
                              .Sum();
            neuron.Output = NeuralNetworkHelper.Sigmoid(weightedSum + neuron.Bias);
        }
        if (layerIndex < Layers.Count - 1)
        {
            FeedForward(layerIndex + 1);
        }
    }
Пример #5
0
        private void handleAttackLogic()
        {
            // Add the elapsed time to the attack timer.
            timeSinceLastAttack += Time.fixedDeltaTime;

            // If the creature has a target, attempt to move towards it.
            if (targetingBehaviour.HasCurrentTarget)
            {
                CreatureTarget creatureTarget = targetingBehaviour.CurrentTarget.Value;

                // Stop moving.
                movementBehaviour.StopMoving();

                // Face the target.
                transform.LookAt(creatureTarget.Transform);

                // If it has been long enough since the last attack, attack again.
                if (timeSinceLastAttack >= AttackInterval && creatureTarget.Target.IsAlive)
                {
                    // Calculate the power of the throw.
                    float power = Mathf.Clamp01(PowerBias + creatureTarget.NormalisedHealth * PowerHealthWeight + creatureTarget.NormalisedDistance * PowerDistanceWeight);

                    // Calculate the pitch of the throw.
                    float pitch = Mathf.Clamp(PitchBias + creatureTarget.NormalisedDistance * PitchDistanceWeight + NeuralNetworkHelper.ExpandRangeToNegative(creatureTarget.TargetRigidbody.velocity.magnitude / 1000) * PitchSpeedWeight
                                              + power * PitchPowerWeight, -1, 1);

                    // Calculate the yaw of the throw.
                    float yaw = Mathf.Clamp(YawBias + creatureTarget.NormalisedDistance * YawDistanceWeight + power * YawPowerWeight
                                            + NeuralNetworkHelper.ExpandRangeToNegative(creatureTarget.TargetRigidbody.velocity.magnitude / 1000) * YawSpeedWeight, -1, 1);

                    // Calcualte the normalised direction to the target, then the angles (in degrees) from that.
                    Vector3 direction = Quaternion.LookRotation((creatureTarget.Transform.position - transform.position).normalized).eulerAngles;
                    direction.y += yaw * Mathf.Clamp(YawDeviation, 0, 180);
                    direction.x += pitch * Mathf.Clamp(PitchDeviation, 0, 180);

                    // Create a new spear.
                    GameObject spearObject = Instantiate(projectilePrefab.gameObject, heldWeapon.position, Quaternion.Euler(direction), Creature.ProjectileContainer);

                    //spearObject.transform.position = heldWeapon.position;
                    spearObject.transform.localScale = Vector3.Scale(heldWeapon.localScale, transform.localScale);

                    // Get the projectile component from the created spear.
                    Projectile spearProjectile = spearObject.GetComponent <Projectile>();

                    spearProjectile.InitialiseProjectile(onProjectileHitEnemy, Creature, creatureTarget.Target, creatureTarget.Transform.position, spearObject.transform.position);

                    // Add the force to the spear.
                    spearProjectile.Rigidbody.AddForce(spearObject.transform.forward * (power + 1) * MaxPower, ForceMode.Impulse);

                    // Increment the thrown shots counter.
                    thrownShots++;

                    // Reset the attack timer.
                    timeSinceLastAttack = 0;
                }
            }
            // Otherwise, just move towards the goal.
            else
            {
                movementBehaviour.SetTarget(Creature.GoalObject);
                movementBehaviour.StoppingDistance = 0;
            }
        }