Esempio n. 1
0
    private void Crossover(CarBrain[] brains, List <CarBrain> bestBrainsList, List <CarBrain> weakerBrainsList)
    {
        // Reproduce / clone the best cars in each Species (instead of cross better half of random cars):
        int speciesMaxSize    = brains.Length / speciesList.Count;
        int rest              = brains.Length - speciesMaxSize * speciesList.Count;
        int weakerBrainsIndex = 0;

        for (int speciesIndex = 0; speciesIndex < speciesList.Count; speciesIndex++)
        {
            // Clear carsBrainsList in Species and add again the best car into this list:
            speciesList[speciesIndex].BrainsList.Clear();
            speciesList[speciesIndex].BrainsList.Add(bestBrainsList[speciesIndex]);             // speciesList count is equal to bestCarsBrainsList count.

            // Add weaker cars into the Species and modifiy their Genomes, cloning Genome from the best car:
            bool restAdded = false;
            for (int i = 1; i < speciesMaxSize; i++)
            {
                CarBrain modifiedBrain = weakerBrainsList[weakerBrainsIndex];
                modifiedBrain.Genome.CloneGenome(speciesList[speciesIndex].BrainsList[0].Genome);
                speciesList[speciesIndex].BrainsList.Add(modifiedBrain);
                weakerBrainsIndex++;

                // Add to the list extra car:
                if (!restAdded && rest > 0)
                {
                    i--;
                    rest--;
                    restAdded = true;
                }
            }
        }
    }
    Import()
    {
        Debug.Log("importing phenotypes...");

        if (File.Exists("phenotypes.neat"))
        {
            string json = File.ReadAllText("phenotypes.neat");

            SerializablePhenotypes serializablePhenotypes = JsonUtility.FromJson <SerializablePhenotypes> (json);

            if (serializablePhenotypes.phenotypes.Count != brains.Count)
            {
                Debug.LogError("phenotypes and genomes mismatch error. (" + serializablePhenotypes.phenotypes.Count + " / " + brains.Count + ")");
                return;
            }

            this.phenotypes = serializablePhenotypes.phenotypes;

            for (int i = 0; i < brains.Count; i++)
            {
                CarBrain brain = brains[i];
                brain.AssignPhenotype(phenotypes[i]);
                brain.runOnlyMode = true;
                brain.Reset();
            }

            runOnlyMode = true;
        }
    }
Esempio n. 3
0
 /// <summary>
 /// Initializes the singleton application object.  This is the first line of authored code
 /// executed, and as such is the logical equivalent of main() or WinMain().
 /// </summary>
 public App()
 {
     Microsoft.ApplicationInsights.WindowsAppInitializer.InitializeAsync(
         Microsoft.ApplicationInsights.WindowsCollectors.Metadata |
         Microsoft.ApplicationInsights.WindowsCollectors.Session);
     this.InitializeComponent();
     this.Suspending += OnSuspending;
     brain            = new CarBrain();
 }
Esempio n. 4
0
    /// <summary>
    /// Create new Species which will have reference list to the cars with similar Genome.
    /// </summary>
    public Species(CarBrain firstBrain)
    {
        allCreatedSpeciesSum++;
        speciesNumber = allCreatedSpeciesSum;
        PickColor();

        brainsList.Add(firstBrain);
        bestGenomePattern = new Genome(CarBrain.InNodesNumber, CarBrain.OutNodesNumber);
        bestGenomePattern.CloneGenome(firstBrain.Genome);
    }
Esempio n. 5
0
    private bool CanDrawGenome(CarBrain brain)
    {
        if (Input.GetMouseButtonDown(0))
        {
            lastBrainIsLocked        = true;
            genomeDataText.fontStyle = FontStyles.Underline;
        }

        return(brain != lastBrain && (!lastBrainIsLocked || Input.GetMouseButtonDown(0)));
    }
    SetBestCar(CarBrain newBest)
    {
        if (best != null)
        {
            best.car.doUpdateUI = false;
        }

        annRenderer.UpdateNeural(newBest.Phenotype());
        best = newBest;
        best.car.doUpdateUI = true;
        follower.target     = newBest.transform;
    }
Esempio n. 7
0
    //MonoBehaviour callbacks
    private void Start()
    {
        _carBrain = GetComponentInParent <CarBrain>();

        GetComponent <BoxCollider>().isTrigger = true;
        Rigidbody rb = GetComponent <Rigidbody>();

        rb.isKinematic = true;
        rb.useGravity  = false;

        isAtSafeDistance = true;
    }
Esempio n. 8
0
    private void DrawNodesConnections(CarBrain brain, GameObject[] nodesUI)
    {
        int nodesConnectionsNumber = brain.Genome.NodesConnectionsList.Count;

        for (int i = 0; i < nodesConnectionsNumber; i++)
        {
            NodesConnection connection   = brain.Genome.NodesConnectionsList[i];
            GameObject      connectionUI = GetGenomeDataUIElementFromPool(genomeDataNodesConnectionsQueue, genomeDataNodesConnectionPrefab,
                                                                          genomeDataPanelNodesConnections);

            RectTransform   rectTransform        = connectionUI.GetComponent <RectTransform>();
            TextMeshProUGUI connectionNumberText = connectionUI.GetComponentInChildren <TextMeshProUGUI>(true);
            connectionNumberText.text = connection.Weight.ToString("F");

            Vector2 startPoint = Vector2.zero;
            foreach (GameObject nodeUI in nodesUI)
            {
                TextMeshProUGUI nodeNumberText = nodeUI.GetComponentInChildren <TextMeshProUGUI>();
                if (nodeNumberText.text.Equals(connection.InNode.Number.ToString()))
                {
                    startPoint = nodeUI.GetComponent <RectTransform>().anchoredPosition;
                    break;
                }
            }

            Vector2 endPoint = Vector2.zero;
            foreach (GameObject nodeUI in nodesUI)
            {
                TextMeshProUGUI nodeNumberText = nodeUI.GetComponentInChildren <TextMeshProUGUI>();
                if (nodeNumberText.text.Equals(connection.OutNode.Number.ToString()))
                {
                    endPoint = nodeUI.GetComponent <RectTransform>().anchoredPosition;
                    break;
                }
            }

            // Position:
            Vector2 connectionUIPosition = (endPoint + startPoint) / 2;
            rectTransform.anchoredPosition = connectionUIPosition;

            // Rotation:
            Vector2 distance = endPoint - startPoint;
            float   z        = Mathf.Atan2(distance.y, distance.x) * Mathf.Rad2Deg;
            rectTransform.rotation = Quaternion.AngleAxis(z, Vector3.forward);

            // Width:
            rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, distance.magnitude);

            // Color:
            float hsvColorPercent = (connection.Weight + 1) / 2 * 0.32f;         // 0% (min) = red, 16% (mid) = yellow, 32% (max) = green.
            connectionUI.GetComponent <Image>().color = Color.HSVToRGB(hsvColorPercent, 1, 1);
        }
    }
Esempio n. 9
0
    private void DrawGenome(CarBrain brain)
    {
        ClearGenomePanel(false);
        lastBrain = brain;

        Color textColor = brain.CrashedCarMaterial.GetColor("_BaseColor");

        genomeDataText.color = new Color(textColor.r, textColor.g, textColor.b, 1);
        genomeDataTextAnimator.Play("WindowPopUp2", 0, 0);

        GameObject[] nodesUI = DrawNodes(brain);
        DrawNodesConnections(brain, nodesUI);
    }
Esempio n. 10
0
    GameObject Breed(GameObject parent1, GameObject parent2)
    {
        GameObject offspring = Instantiate(botPrefab, startingPos.transform.position, Quaternion.Euler(0, -45f, 0));
        CarBrain   b         = offspring.GetComponent <CarBrain>();

        if (Random.Range(0, 100) == 1) //mutate 1 in 100
        {
            b.Init();
            b.dna.Mutate();
        }
        else
        {
            b.Init();
            b.dna.Combine(parent1.GetComponent <CarBrain>().dna, parent2.GetComponent <CarBrain>().dna);
        }
        return(offspring);
    }
    GetFitnessScores()
    {
        Dictionary <int, float> scores = new Dictionary <int, float> ();

        /*
         * brains.Sort(delegate (CarBrain a, CarBrain b) {
         *  return b.Fitness().CompareTo(a.Fitness());
         * });*/

        for (int i = 0; i < brains.Count; i++)
        {
            CarBrain brain = brains[i];
            scores.Add(brain.genomeID, brain.Fitness());
        }

        return(scores);
    }
Esempio n. 12
0
    private IEnumerator DrawBestGenomeFromSpecies(Species species)
    {
        while (true)
        {
            CarBrain bestBrain = species.BrainsList[0];
            for (int i = 1; i < species.BrainsList.Count; i++)
            {
                if (bestBrain.Fitness < species.BrainsList[i].Fitness)
                {
                    bestBrain = species.BrainsList[i];
                }
            }

            if (bestBrain != lastBrain)
            {
                DrawGenome(bestBrain);
            }
            yield return(new WaitForSeconds(1));
        }
    }
Esempio n. 13
0
    /// <summary>
    /// Update the best Species fitness and Genome pattern.
    /// </summary>
    public void UpdateBestFitness()
    {
        int      bestFitness = int.MinValue;
        CarBrain bestBrain   = null;

        foreach (CarBrain brain in brainsList)
        {
            if (bestFitness < brain.Fitness)
            {
                bestFitness = brain.Fitness;
                bestBrain   = brain;
            }
        }
        this.bestFitness = bestFitness;

        if (bestBrain != null)
        {
            bestGenomePattern.CloneGenome(bestBrain.Genome);
        }
    }
Esempio n. 14
0
    public void CreateBots()
    {
        Time.timeScale = Gamespeed;//Ustawia tempo gry, co moze przyspieszyc dlugi trening
        if (cars != null)
        {
            for (int i = 0; i < cars.Count; ++i)
            {
                GameObject.Destroy(cars[i].gameObject);
            }

            SortNetworks();
        }

        cars = new List <CarBrain>();
        for (int i = 0; i < populationSize; ++i)
        {
            CarBrain car = (Instantiate(prefab, new Vector3(0, 1.6f, -30), new Quaternion(0, 0, 1, 0))).GetComponent <CarBrain>(); //Tworzy pojazdy
            car.network = networks[i];                                                                                             //Przypisuje sieci neuronowe do pojazdow
            cars.Add(car);
        }
    }
    InstantiatePopulation()
    {
        for (int i = 0; i < _params.NumGenomesToSpawn; i++)
        {
            GameObject car   = Instantiate(carPrefab);
            CarBrain   brain = car.GetComponent <CarBrain> ();
            brain.genomeID = population.Genomes()[i].ID();
            brain.AssignPhenotype(population.Genomes()[i].Phenotype());
            brains.Add(brain);

            Car carController = car.GetComponent <Car> ();
            carController.sliderLeft  = sliderLeft;
            carController.sliderRight = sliderRight;
            carController.slowDown    = slowDown;
            carController.progress    = progress;
            carController.avgSpeed    = avgSpeed;
            carController.id.text     = "" + brain.genomeID;

            TrackManager trackMgr = car.GetComponent <TrackManager> ();
            trackMgr.activeTrack = activeTrack;
        }
    }
Esempio n. 16
0
    private void Selection(CarBrain[] brains, out List <CarBrain> bestBrainsList, out List <CarBrain> weakerBrainsList)
    {
        // Find the best CarBrain in each Species:
        bestBrainsList = new List <CarBrain>();
        for (int speciesIndex = 0; speciesIndex < speciesList.Count; speciesIndex++)
        {
            CarBrain bestBrain = speciesList[speciesIndex].BrainsList[0];
            for (int brainIndex = 1; brainIndex < speciesList[speciesIndex].BrainsList.Count; brainIndex++)
            {
                CarBrain nextBrain = speciesList[speciesIndex].BrainsList[brainIndex];
                if (bestBrain.Fitness < nextBrain.Fitness)
                {
                    bestBrain = nextBrain;
                }
            }
            bestBrainsList.Add(bestBrain);
        }

        // Get the weaker cars and set them into temporary list (later they Genomes will be modified):
        weakerBrainsList = new List <CarBrain>();
        for (int i = 0; i < brains.Length; i++)
        {
            bool isBestBrain = false;
            for (int j = 0; j < bestBrainsList.Count; j++)
            {
                if (brains[i] == bestBrainsList[j])
                {
                    isBestBrain = true;
                    break;
                }
            }

            if (!isBestBrain)
            {
                weakerBrainsList.Add(brains[i]);
            }
        }
    }
Esempio n. 17
0
    /// <summary>
    /// Reset the genomeDataPanel view. Disable the Nodes and NodesConnections UI elements and add them to the pool.
    /// </summary>
    public void ClearGenomePanel(bool unlockLastBrain)
    {
        // Deactivate NodesConnection weight, reset the panel colors and lastBrain data:
        NodesConnectionUIListener.DeactivateLastShowedInfo();
        genomeDataText.color       = Color.white;
        genomeDataPanelImage.color = new Color(1, 1, 1, 0.39f);

        lastBrain            = null;
        nodesActivationTexts = null;
        if (unlockLastBrain)
        {
            lastBrainIsLocked        = false;
            genomeDataText.fontStyle = FontStyles.Normal;
            StopDrawBestGenomeFromSpeciesCoroutine();
        }

        // Add Nodes to the pool:
        genomeDataNodesQueue.Clear();
        int childrenNumberInPanel = genomeDataPanelNodes.childCount;

        for (int i = 0; i < childrenNumberInPanel; i++)
        {
            GameObject child = genomeDataPanelNodes.GetChild(i).gameObject;
            child.SetActive(false);
            genomeDataNodesQueue.Enqueue(child);
        }

        // Add NodesConnections to the pool:
        genomeDataNodesConnectionsQueue.Clear();
        childrenNumberInPanel = genomeDataPanelNodesConnections.childCount;

        for (int i = 0; i < childrenNumberInPanel; i++)
        {
            GameObject child = genomeDataPanelNodesConnections.GetChild(i).gameObject;
            child.SetActive(false);
            genomeDataNodesConnectionsQueue.Enqueue(child);
        }
    }
Esempio n. 18
0
 private void Start()
 {
     carBrain = GetComponent <CarBrain>();
     carMover = GetComponent <CarMover>();
     GetComponent <Renderer>().material.color = UnityEngine.Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f);
 }
Esempio n. 19
0
    private GameObject[] DrawNodes(CarBrain brain)
    {
        int     nodesNumber         = brain.Genome.NodesList.Count;
        Vector2 genomeDataPanelSize = genomeDataPanel.GetComponent <RectTransform>().rect.size;

        #region Calculate the offset for UI Nodes in the genomeDataPanel:
        // Input Nodes:
        float inNodesOffsetY          = genomeDataPanelSize.y / (CarBrain.InNodesNumber + 1); // +1 because of Bias Node.
        int   inNodesOffsetMultiplier = 1;

        // Output Nodes:
        float outNodesOffsetY          = genomeDataPanelSize.y / CarBrain.OutNodesNumber;
        int   outNodesOffsetMultiplier = 1;

        // Hidden Nodes:
        int   hiddenLayersNumber        = brain.Genome.MaxNodeLayer - 2;
        int[] hiddenNodesNumberInLayers = new int[hiddenLayersNumber];
        for (int i = 0; i < nodesNumber; i++)
        {
            Node node = brain.Genome.NodesList[i];
            if (node.Layer != 1 && node.Layer != brain.Genome.MaxNodeLayer)
            {
                hiddenNodesNumberInLayers[node.Layer - 2]++;
            }
        }

        float[] hiddenNodesOffsetsY          = new float[hiddenLayersNumber];
        int[]   hiddenNodesOffsetMultipliers = new int[hiddenLayersNumber];       // Different multiplier for each hidden layer.
        for (int i = 0; i < hiddenLayersNumber; i++)
        {
            hiddenNodesOffsetsY[i]          = genomeDataPanelSize.y / hiddenNodesNumberInLayers[i];
            hiddenNodesOffsetMultipliers[i] = 1;
        }

        float hiddenNodeOffsetX = genomeDataPanelSize.x / brain.Genome.MaxNodeLayer;
        #endregion Calculate the offset for UI Nodes in the genomeDataPanel.

        GameObject[] nodesUI = new GameObject[nodesNumber];
        nodesActivationTexts = new TextMeshProUGUI[nodesNumber];
        for (int i = 0; i < nodesNumber; i++)
        {
            Node       node   = brain.Genome.NodesList[i];
            GameObject nodeUI = GetGenomeDataUIElementFromPool(genomeDataNodesQueue, genomeDataNodePrefab, genomeDataPanelNodes);
            nodesUI[i] = nodeUI;

            RectTransform     rectTransform = nodeUI.GetComponent <RectTransform>();
            TextMeshProUGUI[] nodeTexts     = nodeUI.GetComponentsInChildren <TextMeshProUGUI>();
            nodeTexts[0].text       = node.Number + "";
            nodeTexts[1].text       = node.Activation.ToString("F");
            nodesActivationTexts[i] = nodeTexts[1];

            if (node.Layer == 1)            // Draw Nodes in the first layer.
            {
                float x = 10;
                float y = (CarBrain.InNodesNumber > 1) ? -inNodesOffsetY * inNodesOffsetMultiplier + inNodesOffsetY / 2 : inNodesOffsetY / 2;
                rectTransform.anchoredPosition = new Vector2(x, y);
                inNodesOffsetMultiplier++;
            }
            else if (node.Layer == brain.Genome.MaxNodeLayer)            // Draw Nodes in the last layer.
            {
                float x = genomeDataPanelSize.x - 10;
                float y = (CarBrain.OutNodesNumber > 1) ? -outNodesOffsetY * outNodesOffsetMultiplier + outNodesOffsetY / 2 : outNodesOffsetY / 2;
                rectTransform.anchoredPosition = new Vector2(x, y);
                outNodesOffsetMultiplier++;
            }
            else             // Draw Nodes in the hidden layers.
            {
                float x = hiddenNodeOffsetX / 2 + hiddenNodeOffsetX * (node.Layer - 1);
                float y;
                if (hiddenNodesNumberInLayers[node.Layer - 2] > 1)
                {
                    y = -hiddenNodesOffsetsY[node.Layer - 2] * hiddenNodesOffsetMultipliers[node.Layer - 2] + hiddenNodesOffsetsY[node.Layer - 2] / 2;
                }
                else
                {
                    y = -hiddenNodesOffsetsY[node.Layer - 2] / 2;
                }

                rectTransform.anchoredPosition = new Vector2(x, y);
                hiddenNodesOffsetMultipliers[node.Layer - 2]++;               // Hidden layers are beginning from 2 layer so "[node.Layer-2]".
            }
        }

        return(nodesUI);
    }
Esempio n. 20
0
 public void UpdateView(CarBrain car)
 {
     SteeringIndicator.value = car.SteeringDecision;
     ThrottleIndicator.value = car.ThrottleDecision;
     BrakeIndicator.value    = car.BrakingDecision;
 }
    Update()
    {
        if (!initalized)
        {
            return;
        }

        if (runningSimulation || runOnlyMode)
        {
            bool keepRunning = false;
            for (int i = 0; i < brains.Count; i++)
            {
                CarBrain brain = brains[i];
                if (brain.isAlive)
                {
                    keepRunning = true;
                    if (brain.Fitness() > best.Fitness() || !best.isAlive)
                    {
                        SetBestCar(brain);
                    }
                }
            }

            if (!keepRunning)
            {
                if (runOnlyMode)
                {
                    for (int i = 0; i < brains.Count; i++)
                    {
                        CarBrain brain = brains[i];
                        brain.Reset();
                    }
                }
                else
                {
                    // If all genomes are dead we stop the simulation.
                    runningSimulation = false;
                }
            }
        }

        if (!runningSimulation && !runOnlyMode)
        {
            generationCount++;

            // Keep track of the all time best phenotype
            if (best.Fitness() > population.BestFitness())
            {
                bestPhenotype = best.Phenotype();
            }

            /*
             * Using the genetic algorithm try to improve the brains for each
             * genome in the hope that it will perform better.
             */
            phenotypes = population.Epoch(GetFitnessScores());

            // TODO: clean up the mess below
            Dictionary <int, CGenome> genomeIDs = new Dictionary <int, CGenome>();
            foreach (CGenome genome in population.Genomes())
            {
                genomeIDs.Add(genome.ID(), genome);
            }

            List <CarBrain> brainsToBeAssigned = new List <CarBrain> (brains);

            for (int i = brainsToBeAssigned.Count - 1; i >= 0; i--)
            {
                int oldGenomeID = brainsToBeAssigned[i].genomeID;
                if (genomeIDs.ContainsKey(oldGenomeID) && genomeIDs[oldGenomeID].Phenotype() != null)
                {
                    brainsToBeAssigned[i].AssignPhenotype(genomeIDs[oldGenomeID].Phenotype());
                    genomeIDs.Remove(oldGenomeID);
                    brainsToBeAssigned[i].GetComponent <Car>().id.text = "" + brains[i].genomeID;
                    brainsToBeAssigned[i].Reset();
                    brainsToBeAssigned.RemoveAt(i);
                }
            }

            for (int i = 0; i < brainsToBeAssigned.Count; i++)
            {
                brainsToBeAssigned[i].genomeID = genomeIDs.ElementAt(0).Key;
                brainsToBeAssigned[i].AssignPhenotype(genomeIDs.ElementAt(0).Value.Phenotype());
                genomeIDs.Remove(genomeIDs.ElementAt(0).Key);

                brainsToBeAssigned[i].GetComponent <Car>().id.text = "" + brains[i].genomeID;
                brainsToBeAssigned[i].Reset();
            }

            generation.text  = "Generation:\t" + generationCount;
            bestFitness.text = string.Format("Best fitness:\t{0:#.0000}", population.BestFitness());

            Dictionary <int, int> allSpecies = new Dictionary <int, int> ();
            CSpecies theBestSpecies          = null;
            float    bestSpeciesFitness      = -1;

            for (int i = 0; i < population.Species().Count; i++)
            {
                CSpecies species = population.Species()[i];
                allSpecies.Add(species.ID(), species.NumMembers());
                if (species.BestFitness() > bestSpeciesFitness)
                {
                    bestSpeciesFitness = species.BestFitness();
                    theBestSpecies     = species;
                }

                if (species.Leader() == null)
                {
                    continue;
                }
            }

            numSpecies.text           = "Num species:\t" + allSpecies.Count;
            bestSpecies.text          = "Best species:\t" + theBestSpecies.ID();
            numMembers.text           = "Num members:\t" + theBestSpecies.NumMembers();
            speciesAge.text           = "Species age:\t" + theBestSpecies.Age();
            gensWithoutImproving.text = "Gens no impr:\t" + theBestSpecies.GensNoImprovement();

            bar.UpdateBar(allSpecies);

            runningSimulation = true;
        }
    }