public static GeneticAI Combine(this GeneticAI aI, GeneticAI counterpart, int generation, int index, double mutationChance)
    {
        GeneticAI newAi = new GeneticAI(aI, false, generation, index);

        Dictionary <string, object> settings = new Dictionary <string, object>(newAi.Settings);

        if (random == null)
        {
            random = new Random();
        }

        double randomDouble = random.NextDouble();

        foreach (KeyValuePair <string, object> setting in aI.Settings)
        {
            if (randomDouble < mutationChance)
            {
                settings[setting.Key] = settings[setting.Key].ChangeRandomly(1);
                continue;
            }

            if ((randomDouble - mutationChance) / mutationChance < 0.5)
            {
                settings[setting.Key] = counterpart.Settings[setting.Key];
            }
        }

        return(newAi);
    }
    public void PlayGeneration(bool firstGeneration)
    {
        Console.ForegroundColor = ConsoleColor.Gray;
        Console.Write("\nPlaying");

        for (int i = 0; i < players.Count; ++i)
        {
            if (i % (PLAYERCOUNT / 5) == 0)
            {
                Console.Write(".");
            }

            if (/*players[i].Wins == 0*/ true)
            {
                players[i].Wongames = 0;

                Player opponent = GetOpponent();

                players[i].Game = game;
                opponent.Game   = game;

                game.Player1 = players[i];
                game.Player2 = opponent;

                for (int j = 0; j < GAMECOUNT; ++j)
                {
                    game.Initialize();
                    game.PlayAGame(j % 2 == 0);
                }

                players[i].Wins = players[i].Wongames;
            }
        }

        players = players.OrderBy(ai => ai.Wins).ToList();
        players.Reverse();

        if (firstGeneration)
        {
            bestAI = GetClone(players[0]);
        }
        else if (players[0].Wins > bestAI.Wins)
        {
            bestAI = GetClone(players[0]);
        }

        Console.Clear();
        WriteStats();

        HalfAndMutate(currentGeneration);
    }
    public void HalfAndMutate(int generation)
    {
        int count = players.Count;

        players.RemoveRange(count / 2, count / 2);

        for (int i = 0; i < count / 2; i++)
        {
            GeneticAI newAi = players[i].Combine(players[i != count / 2 - 1 ? i + 1 : 0], generation, currentIndex++, 0.4);

            //if (/*i < count / 3*/ true)
            //{
            //    GeneticAI newAI = new GeneticAI(players[i], true, generation, currentIndex++);
            //    newAI.RandomizeValues(0.7 + 0.6 * (i / ((double)count / 2)));
            //    players.Add(newAI);
            //    continue;
            //}

            players.Add(GetPlayer());
        }
    }
    public GeneticAI(GeneticAI clone, bool clearValue, int generation, int index, bool randomize = false, double exponent = 1)
    {
        Name       = clone.Name;
        Generation = generation;
        Index      = index;

        settingTags = new List <string>();
        foreach (KeyValuePair <string, object> item in Settings)
        {
            settingTags.Add(item.Key);
        }

        if (!clearValue)
        {
            Wins = clone.Wins;
        }

        Settings = clone.Settings;

        if (randomize)
        {
            RandomizeValues(exponent);
        }
    }
 public EnhancedConverted(GeneticAI clone, bool clearValue, int generation, int index, bool randomize = false, double exponent = 1) : base(clone, clearValue, generation, index, randomize, exponent)
 {
 }
 public GeneticAI GetClone(GeneticAI template)
 {
     return(new EnhancedConverted(template, false, currentGeneration, currentIndex++));
 }