Beispiel #1
0
        /*Takes 3 players and generates a new array of Players
         * 50% are derived from first
         * 30% derived from second
         * 20% derived from third
         * any remainder slots are also filled with players derived from first
         */
        private Player[] GenerateBracket(Player first, Player second, Player third)
        {
            Player[] bracket          = new Player[playersPerBracket];
            int      playersGenerated = 0;
            int      firstChildren    = (int)(playersPerBracket * .5); //50% descendents derived from first
            int      secondChildren   = (int)(playersPerBracket * .3); //30% from second
            int      thirdChildren    = (int)(playersPerBracket * .2); //20% from third
            int      remainder        = playersPerBracket - (firstChildren + secondChildren + thirdChildren);

            firstChildren += remainder;//any remaining slots filled with descendents of first

            bracket[0]        = first.Reproduce(0);
            bracket[1]        = second.Reproduce(0);
            playersGenerated += 2;
            for (int i = 1; i < firstChildren; i++)
            {
                bracket[playersGenerated] = first.Reproduce(mutationRate);
                playersGenerated++;
            }
            for (int i = 1; i < secondChildren; i++)
            {
                bracket[playersGenerated] = second.Reproduce(mutationRate);
                playersGenerated++;
            }
            for (int i = 0; i < thirdChildren; i++)
            {
                bracket[playersGenerated] = third.Reproduce(mutationRate);
                playersGenerated++;
            }
            return(bracket);
        }
Beispiel #2
0
        /*creates a bracket of players, has them each play all the others, and
         * creates a new bracket seeded by the top 3.  Repeats iterationsPerTask times.
         */
        public Player PlayAndEvolve(Player seed, CancellationToken cancel)
        {
            Thread.CurrentThread.Priority = ThreadPriority.Lowest;
            Player[] bracket = new Player[playersPerBracket];
            Player   first, second, third;

            first      = seed;
            bracket[0] = seed;
            for (int i = 1; i < playersPerBracket; i++)
            {
                bracket[i] = seed.Reproduce(mutationRate);
            }
            for (int i = 0; i < iterationsPerTask; i++)
            {
                if (cancel.IsCancellationRequested)
                {
                    return(first);
                }
                RunBracket(bracket);
                GetTop3Players(bracket, out first, out second, out third);
                bracket = GenerateBracket(first, second, third);
            }
            return(first);
        }
Beispiel #3
0
        /* Training algorithm
         *
         * Algorithm works as follows:
         * several tasks run the PlayAndEvolve method (# tasks = trainingTasks)
         * PlayAndEvolve takes a seed player, fills an array (size = playersPerBracket) with mutated copies of the seed,
         * and has every player play all the others.  The top 3 are used as seeds for the next iteration.  This process
         * is repeated iterationsPerTask times, and then the top player is returned as the result of the task.
         * Once every training task completes, each player plays all the others, and the one with the most wins
         * becomes the challenger.  The challenger plays the existing champion and, if it wins, becomes the
         * new champion.
         * The process is repeated in an infinite loop
         *
         * cancelAfterGeneration waits for all tasks in simTasks to complete and then computes the champion
         * cancelNow causes all the simTasks to abort before completing all their iterations
         */
        public void Train(CancellationToken cancelNow, CancellationToken cancelAfterGeneration, Player seed)
        {
            generationsSinceNewChampion = 0;
            generations  = 0;
            _gamesPlayed = 0;
            winRecord    = 0;
            champion     = seed;
            Player challenger;
            Task   notifier = Task.Factory.StartNew(() => UpdateStats(cancelAfterGeneration)); //this task updates the trainingStats property at fixed intervals

            Task <Player>[] simTasks = new Task <Player> [trainingTasks];
            Player[]        bracket  = new Player[trainingTasks];
            trainerStatus = "Running. . .";

            //first element is seeded with the champion, the remaining are seeded with mutations of the champion
            simTasks[0] = Task <Player> .Factory.StartNew(() => PlayAndEvolve(champion, cancelAfterGeneration));

            for (int i = 1; i < trainingTasks; i++)
            {
                simTasks[i] = Task <Player> .Factory.StartNew(() => PlayAndEvolve(champion.Reproduce(i + 1), cancelNow));
            }
            while (true)
            {
                /*The main training loop works as follows
                 * Wait for all PlayAndEvolve tasks to complete.
                 * Create a new bracket with the result of each task.
                 * Call RunBracket method to have each of them play all the others
                 * Have the top player from that bracket play against the reigning champion,
                 * and make it the new champion if it wins.
                 * If cancellation token was cancelled, end the training loop.
                 * Else, begin new generation of PlayAndEvolve tasks with the results of the prior generation.
                 */
                Task.WaitAll(simTasks);
                for (int i = 0; i < trainingTasks; i++)
                {
                    bracket[i] = simTasks[i].Result;
                }
                RunBracket(bracket, trainingTasks);
                challenger = GetTopPlayer(bracket);
                champion   = GetWinnerOfGame(challenger, champion);
                generations++;
                if (champion != challenger)
                {
                    generationsSinceNewChampion = 0;
                }
                else
                {
                    generationsSinceNewChampion++;
                    if (generationsSinceNewChampion > winRecord)
                    {
                        winRecord = generationsSinceNewChampion;
                    }
                }
                if (cancelAfterGeneration.IsCancellationRequested)
                {
                    trainerStatus = "Finished";
                    trainingStats = String.Format("{0}\nGeneration: {1}\nGames Played: {2}\nChamp for {3} generations\nRecord is {4} generations",
                                                  trainerStatus, generations, _gamesPlayed, generationsSinceNewChampion, winRecord);
                    UI.Invoke(TrainingFinished);
                    return;
                }
                for (int i = 0; i < trainingTasks; i++)
                {
                    Player p = bracket[i].Reproduce(0);
                    simTasks[i] = Task <Player> .Factory.StartNew(() => PlayAndEvolve(p, cancelNow));
                }
            }
        }