Esempio n. 1
0
    public void UpdateStatistics(EvolutionInformation info)
    {
        Clear();

        // Title
        float  titleSize = 1f / 6f;
        int    fontSize  = 16;
        string titleText = "Evolution Information for Generation " + info.Generation + " (" + info.EvolutionTime + " ms)";

        AddText(titleText, fontSize, Color.black, FontStyle.Bold, 0, 0, 1, titleSize, Container, TextAnchor.MiddleCenter);

        float numColumns = 6;
        int   nRows      = 7;
        float yStep      = 0;

        // Subject numbers
        AddColumn(nRows, yStep, titleSize, yStep + (1 / numColumns), 1, true,
                  new string[] { "# Subjects: " + info.NumSubjects, "# Offsprings: " + info.NumOffsprings, "# Best: " + info.NumBestSubjectsTakenOver, "# Random: " + info.NumRandomSubjectsTakenOver });
        yStep += 1f / numColumns;

        // Species numbers
        AddColumn(nRows, yStep, titleSize, yStep + (1 / numColumns), 1, true,
                  new string[] { "# Species: " + info.NumSpecies, "# Previous: " + info.NumPreviousSpecies, "# New: " + info.NumNewSpecies, "# Eliminated: " + info.NumEliminatedSpecies, "# Empty: " + info.NumEmptySpecies, "Comp. Threshh.: " + info.CompatibilityThreshhold });
        yStep += 1f / numColumns;

        // Fitness numbers
        AddColumn(nRows, yStep, titleSize, yStep + (1 / numColumns), 1, true,
                  new string[] { "Gen " + (info.Generation - 1) + " Fitness", "Max: " + (int)info.MaxFitness, "Average: " + (int)info.AverageFitness });
        yStep += 1f / numColumns;

        // Misc info
        AddColumn(nRows, yStep, titleSize, yStep + (1 / numColumns), 1, true,
                  new string[] { "Misc", "# AdpChecks: " + info.NumSubjectsCheckedForAdoption, "# Immune: " + info.NumImmuneToMutationSubjects, "Rank Limit: " + info.RankLimit, "#Gens <Limit: " + info.GensAllowedBelowLimit, "Takeovers immune: " + info.MutationImmunityForTakeOvers, "Multiple Mut / Genome: " + info.MutationInfo.MultipleMutationsPerGenomeAllowed });
        yStep += 1f / numColumns;

        // Topology mutation numbers
        AddColumn(nRows, yStep, titleSize, yStep + (1 / numColumns), 1, true,
                  new string[] { "# Topology Mutations: " + info.MutationInfo.NumTopologyMutations, "on # Genomes: " + info.MutationInfo.NumTopologyMutatedGenomes, "Chance/G (fac): " + info.MutationInfo.TopologyMutationChancePerGenome.ToString("0.##") + "(" + info.MutationInfo.MutationChanceScaleFactor.ToString("0.##") + ")", "# Con (new): " + info.MutationInfo.NumNewConnectionsMutations + " (" + info.MutationInfo.NumNewUniqueConnectionsMutations + ")", "# Node (new): " + info.MutationInfo.NumNewNodeMutations + " (" + info.MutationInfo.NumNewUniqueNodeMutations + ")" });
        yStep += 1f / numColumns;

        // Weight mutation numbers
        AddColumn(nRows, yStep, titleSize, yStep + (1 / numColumns), 1, true,
                  new string[] { "# Weight Mutations: " + info.MutationInfo.NumWeightMutations, "on # Genomes: " + info.MutationInfo.NumWeightMutatedGenomes, "Chance/G (fac): " + info.MutationInfo.WeightMutationChancePerGenome.ToString("0.##") + "(" + info.MutationInfo.MutationChanceScaleFactor.ToString("0.##") + ")", "# Replaces: " + info.MutationInfo.NumReplaceMutations, "# Shifts: " + info.MutationInfo.NumShiftMutations, "# Scales: " + info.MutationInfo.NumScaleMutations, "# Inverts: " + info.MutationInfo.NumInvertMutations, "# Swaps: " + info.MutationInfo.NumSwapMutations });
        yStep += 1f / numColumns;
    }
Esempio n. 2
0
    public EvolutionInformation EvolveGeneration()
    {
        DateTime       startTimeStamp     = DateTime.Now;
        DateTime       stamp              = DateTime.Now;
        List <Subject> newSubjects        = new List <Subject>();
        int            numPreviousSpecies = Species.Count;

        // Calculate fitness & rank of each subject and species
        GetFitness();
        float averageFitness = Subjects.Average(x => x.Genome.Fitness);
        float maxFitness     = Subjects.Max(x => x.Genome.Fitness);

        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Get Fitness");
        }

        // Eliminate species without improvement for too long
        int numEliminatedSpecies = EliminateBadSpecies(RankNeededToSurvive, GenerationsBelowRankAllowed);

        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Eliminate Bad Species");
        }

        // Take a random representative for each existing species
        CreateSpeciesRepresentatives();
        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Create Representatives");
        }

        int numSubjectsImmuneToMutations = 0;
        // Take over best subjects of each species
        int numBestSubjects = TakeOverBestSubjects(newSubjects, TakeOverBestRatio, AreTakeOversImmuneToMutation);

        if (AreTakeOversImmuneToMutation)
        {
            numSubjectsImmuneToMutations += numBestSubjects;
        }
        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Take over Best Subjects");
        }

        // Take over random lucky subjects of each species
        int numRandomSubjects = TakeOverRandomSubjects(newSubjects, TakeOverRandomRatio, AreTakeOversImmuneToMutation);

        if (AreTakeOversImmuneToMutation)
        {
            numSubjectsImmuneToMutations += numRandomSubjects;
        }
        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Take over Random Subjects");
        }

        // Evaluate which species is allowed to produce how many offsprings
        int numOffsprings = Size - numBestSubjects - numRandomSubjects;

        CalculateOffspringNumberPerSpecies(numOffsprings);
        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Calculate Offspring numbers");
        }

        // Create offsprings with a chance to automatically have the same species as its parents
        List <Subject> toSpeciate = CreateOffsprings(newSubjects);
        int            numSubjectsCheckedForAdoption = toSpeciate.Count;

        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Create Offsprings");
        }

        // Moves subjects from the newSubjects list to the Subjects list (that it also clears)
        ReplaceSubjects(newSubjects);
        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Replace Subjects");
        }

        // Mutate the genomes in all subjects that are not marked immuneToMutation according to chances in the mutatealgorithm
        MutationInformation mutationInfo = MutateAlgorithm.MutatePopulation(this, CurrentMutationChanceScaleFactor, MultipleMutationsPerGenomeAllowed, MutationChanceReductionFactorPerMutation);

        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Mutate Population");
        }

        // Speciate all subjects that haven't gotten a species yet
        int numNewSpecies = Speciator.Speciate(toSpeciate, Species);

        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Speciate unspeciated Subjects");
        }

        // Fill species with new subjects
        foreach (Species s in Species)
        {
            s.Subjects.Clear();
        }
        foreach (Subject subject in Subjects)
        {
            subject.Genome.Species.Subjects.Add(subject);
        }
        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Replace Subjects in Species");
        }

        // Remove empty species
        List <Species> emptySpecies = new List <Species>();

        foreach (Species species in Species)
        {
            if (species.Subjects.Count == 0)
            {
                emptySpecies.Add(species);
            }
        }
        foreach (Species remove in emptySpecies)
        {
            Species.Remove(remove);
        }
        int numEmptySpecies = emptySpecies.Count;

        if (DebugTimestamps)
        {
            stamp = TimeStamp(stamp, "Remove empty Species");
        }

        // Go to next generation
        Generation++;
        if (CurrentMutationChanceScaleFactor > MinMutationChanceFactor)
        {
            CurrentMutationChanceScaleFactor -= MutationChanceFactorReductionPerGeneration;
        }

        // Name the subjects
        for (int i = 0; i < Subjects.Count; i++)
        {
            if (String.IsNullOrEmpty(Subjects[i].Name))
            {
                Subjects[i].Name = Generation + "-" + Subjects[i].Genome.Species.Id + "-" + i;
            }
        }

        if (Subjects.Count != Species.Sum(x => x.Subjects.Count))
        {
            throw new Exception("SPECIATION FAILED. The number of subjects in the species does not match the number of subjects in the population.");
        }

        // Create the evolution information object
        int evolutionTime         = (int)((DateTime.Now - startTimeStamp).TotalMilliseconds);
        EvolutionInformation info = new EvolutionInformation(Generation, evolutionTime,
                                                             AreTakeOversImmuneToMutation, mutationInfo, numBestSubjects, numRandomSubjects, numOffsprings,
                                                             numSubjectsCheckedForAdoption, numSubjectsImmuneToMutations,
                                                             numPreviousSpecies, numEliminatedSpecies, numEmptySpecies, numNewSpecies, Species.Count, SpeciesCompatiblityThreshhold,
                                                             maxFitness, averageFitness,
                                                             RankNeededToSurvive, GenerationsBelowRankAllowed);

        Debug.Log(info.ToString());

        // Reset the species fitness values
        //foreach (Species s in Species) s.CalculateFitnessValues();

        return(info);
    }
Esempio n. 3
0
    // Update is called once per frame
    void Update()
    {
        switch (SimulationPhase)
        {
        case SimulationPhase.MatchesReady:
            //Debug.Log("Starting matchround " + Population.Generation + "." + (MatchesPlayed + 1));
            SimulationUI.TitleText.text = "Match Round " + Population.Generation + "." + (MatchesPlayed + 1);
            foreach (Match m in Matches)
            {
                if (m.Visual)
                {
                    SimulationUI.gameObject.SetActive(false);
                    VisualMatch = m;
                    m.StartMatch(VisualPlayer, VisualMinion, VisualBoardHeight, MatchUI);
                }
                else
                {
                    m.StartMatch();
                }
            }
            SimulationPhase = SimulationPhase.MatchesRunning;
            break;

        case SimulationPhase.MatchesRunning:
            foreach (Match m in Matches)
            {
                m.Update();
            }
            if (Matches.TrueForAll(x => x.Phase == MatchPhase.GameEnded))
            {
                MatchesPlayed++;
                SimulationPhase = SimulationPhase.MatchesFinished;
                if (VisualMatch != null)
                {
                    VisualMatch = null;
                    SimulationUI.gameObject.SetActive(true);
                }
            }
            break;

        case SimulationPhase.MatchesFinished:

            // Update Stats
            UpdateStatistics();

            if (MatchesPlayed >= MatchesPerGeneration)
            {
                // Init Human vs AI game if gen is finished
                if (SimulationUI.PlayGame.isOn)
                {
                    SimulationUI.PlayGame.isOn = false;
                    Matches.Clear();

                    // Create match
                    Match   match       = new Match();
                    Player  player1     = new HumanPlayer(match);
                    Subject bestSubject = Population.Subjects.OrderByDescending(x => x.Wins).First();
                    Player  player2     = new AIPlayer(match, bestSubject);
                    match.InitGame(player1, player2, StartHealth, StartCardOptions, MinCardOptions, MaxCardOptions, MaxMinions, MaxMinionsPerType, FatigueDamageStartTurn, true, false);

                    // Start match
                    Matches.Add(match);
                    VisualMatch = match;
                    SimulationUI.gameObject.SetActive(false);
                    match.StartMatch(VisualPlayer, VisualMinion, VisualBoardHeight, MatchUI);
                    SimulationPhase = SimulationPhase.MatchesReady;
                }

                else
                {
                    SimulationPhase = SimulationPhase.GenerationFinished;
                }
            }
            else
            {
                GenerateMatches();
                SimulationPhase = SimulationPhase.MatchesReady;
            }
            break;

        case SimulationPhase.GenerationFinished:

            // Reset stats
            ResetStatistics();
            MatchesPlayed = 0;

            // Evolve and Update UI
            EvolutionInformation info = Population.EvolveGeneration();
            SimulationUI.EvoStats.UpdateStatistics(info);
            SimulationUI.SpeciesScoreboard.UpdateScoreboard(Population);

            // Generate first match round
            GenerateMatches();
            SimulationPhase = SimulationPhase.MatchesReady;
            break;
        }
    }