Example #1
0
    // train the neural networks environment
    IEnumerator Train()
    {
        bool complexify = true;
        int  index      = 0;

        // Create the initial neural networks
        generationNetworks = ga.CreateNetworks();
        raceManager.Reset();

        FitnessTracker.totLength = 0;
        for (int i = 0; i < LoadTrackManager.instance.selectedTrackNames.Count; i++)
        {
            trackManagers.Add(Instantiate(trackPrefab).GetComponent <TrackManager>());
            trackManagers[i].Initialize(LoadTrackManager.instance.selectedTrackNames[i]);
            trackManagers[i].gameObject.SetActive(false);
        }
        TrackManager.SetTotalLength();

        // Training loop. Keep the training running as long as desired.
        while (true)
        {
            // This pauses the training
            yield return(StartCoroutine(Pause()));

            fitnesses.Clear();
            float sum = 0;

            // add all new networks to the networks list
            raceManager.ResetPlayers();
            for (int individual = 0; individual < generationNetworks.Count; individual++)
            {
                raceManager.AddAIPlayer(individual.ToString(), generationNetworks[individual], individual);
            }
            raceManager.FinishPlayers(generationNetworks.Count);
            yield return(StartCoroutine(raceManager.StartRace(true, trackManagers, false)));

            // Get the fitnesses of the networks and calculate the sum of all fitnesses
            fitnesses = raceManager.GetFitnesses();
            int  bestRacerIndex = 0;
            bool updateTime     = false;
            for (int i = 0; i < fitnesses.Count; i++)
            {
                if (fitnesses[i] >= bestFitnessSoFar)
                {
                    bestFitnessSoFar = fitnesses[i];
                    bestRacerIndex   = i;
                    updateTime       = true;
                    bestGeneration   = curGeneration;
                }

                if (fitnesses[i] < 0)
                {
                    fitnesses[i] = 0;
                }
                sum += fitnesses[i];
            }
            float currentBestFitness = 0;
            for (int i = 0; i < fitnesses.Count; i++)
            {
                if (fitnesses[i] >= currentBestFitness)
                {
                    currentBestFitness = fitnesses[i];
                }
            }

            curGeneration++;

            // Restart the simulation if non of the cars has a fitness higher than 0
            if (sum == 0)
            {
                curGeneration = 0;
                InitializeNetworks();
                generationNetworks = ga.CreateNetworks();
                continue;
            }
            float totalTime = raceManager.GetCurrentCompetingCars()[bestRacerIndex].totalTime;
            if (raceManager.GetCurrentCompetingCars()[bestRacerIndex].GetFitnessTracker().finished != LoadTrackManager.instance.selectedTrackNames.Count)
            {
                totalTime = -1;
            }

            // Update the best and average fitness on the UI
            UIController.instance.UpdateUI(bestFitnessSoFar, currentBestFitness, sum / ga.populationSize, curGeneration, totalTime, updateTime);

            // Determine the population for the next generation based on the fitnesses of the current networks
            generationNetworks = ga.DoGeneration(fitnesses, complexify);

            index++;
            if (index > 50)
            {
                index = 0;
                if (complexify && Random.Range(0f, 1f) < 0.3f)
                {
                    complexify = !complexify;
                }
                else if (!complexify)
                {
                    complexify = true;
                }
            }
        }
    }