Example #1
0
        public Dictionary <DeckMutationStrategy, double> MutationCounts; // how many times this particular mutation strategy should be applied to this player
        public TournamentPlayer Mutate(Tournament tournament)
        {
            // determine approximately how many mutations we want to do
            double previousNumMutations = 0;

            foreach (KeyValuePair <DeckMutationStrategy, double> entry in this.MutationCounts)
            {
                previousNumMutations += entry.Value;
            }
            // Choose an exponential random number of mutations to actually do, with mean equal to numMutations
            double randFraction        = this.Random.NextDouble();
            double desiredNumMutations = Math.Exp(randFraction * 2 * Math.Log(previousNumMutations));

            if (desiredNumMutations < 2)
            {
                desiredNumMutations = 2;
            }
            // keep track of which mutations are done this time
            Dictionary <DeckMutationStrategy, double> currentMutationCounts = new Dictionary <DeckMutationStrategy, double>(this.MutationCounts.Count);

            foreach (DeckMutationStrategy strategy in this.MutationCounts.Keys)
            {
                currentMutationCounts[strategy] = 0;
            }
            TournamentPlayer player = this.Clone();
            // Now determine which mutations to do
            double numMutations;

            for (numMutations = 0; numMutations < desiredNumMutations; numMutations++)
            {
                // Choose a mutation strategy
                double randomNumber = this.Random.NextDouble() * previousNumMutations;
                foreach (KeyValuePair <DeckMutationStrategy, double> entry in this.MutationCounts)
                {
                    if (randomNumber <= entry.Value)
                    {
                        // mutate using this strategy
                        DeckMutationStrategy strategy = entry.Key;
                        player = strategy.DesignNewDeck(player, tournament);
                        currentMutationCounts[strategy]++;
                        break;
                    }
                    else
                    {
                        // keep looking
                        randomNumber -= entry.Value;
                    }
                }
            }
            // update the mutation counts of the new player so that it knows how it got to its state and it can continue to mutate at a similar rate
            Dictionary <DeckMutationStrategy, double> childMutations = new Dictionary <DeckMutationStrategy, double>();

            foreach (DeckMutationStrategy strategy in currentMutationCounts.Keys)
            {
                // add a little to make sure no strategy gets completely forgotten, and then normalize the counts again
                childMutations[strategy] = (currentMutationCounts[strategy] + 1) * (numMutations / (numMutations + currentMutationCounts.Count()));
            }
            player.MutationCounts = childMutations;
            return(player);
        }
Example #2
0
        public Game NewGame(TournamentPlayer player1, TournamentPlayer player2)
        {
            List <TournamentPlayer> players = new List <TournamentPlayer>();

            players.Add(player1);
            players.Add(player2);
            foreach (ReadableCard card in player1.MainDeck)
            {
                if (player2.MainDeck.Contains(card))
                {
                    Console.WriteLine("Error: two players have the same instance of a card in their deck");
                }
            }
            return(this.NewGame(players));
        }
Example #3
0
        public TournamentPlayer DesignNewDeck(TournamentPlayer player, Tournament Tournament)
        {
            TournamentPlayer newPlayer = player.Clone();
            // Choose a new random card
            IList <ReadableCard> legalCards = player.Referee.LegalCards;
            WritableCard         newCard    = legalCards[player.Random.Next(legalCards.Count)].Clone((WritableCard)null);

            newCard.ID = IDFactory.NewID();

            // replace an existing card with the new card
            newPlayer.RemoveCard(newPlayer.MainDeck.First());
            newPlayer.AddCard(newCard);

            return(newPlayer);
        }
Example #4
0
        public TournamentPlayer Clone()
        {
            TournamentPlayer clone = new TournamentPlayer();

            clone.Random   = this.Random;
            clone.Referee  = this.Referee;
            clone.Strategy = this.Strategy;
            clone.mainDeck = new LinkedList <ReadableCard>();
            foreach (ReadableCard card in this.mainDeck)
            {
                clone.mainDeck.AddLast(card.Clone((WritableCard)null));
            }
            clone.NumWins   = this.NumWins;
            clone.NumLosses = this.NumLosses;
            return(clone);
        }
Example #5
0
        public Writable_GamePlayer(TournamentPlayer source)
        {
            this.Initialize();
            // copy the deck and keep a pointer to the strategy
            LinkedList <ReadableCard> cards = new LinkedList <ReadableCard>();

            foreach (ReadableCard readableCard in source.MainDeck)
            {
                WritableCard writableCard = readableCard.Clone((WritableCard)null);
                writableCard.ControllerID = this.GetID((Readable_GamePlayer)null);
                cards.AddLast(writableCard);
            }
            this.Deck = WritableQueue <ReadableCard> .ShuffledQueue(cards);

            this.sourcePlayer = source;
        }
Example #6
0
        public void Run()
        {
            while (true)
            {
                TournamentPlayer bestPlayer = this.Players[0];
                // play a bunch of games, giving lower-ranked players the opportunity to rise to the top
                for (int i = this.Players.Count - 2; i >= 0; i--)
                {
                    if (this.random.Next(2) == 0)
                    {
                        this.PlayGame(i, i + 1);
                    }
                    else
                    {
                        this.PlayGame(i + 1, i);
                    }
                }
                // If the best players has changed, then print the current best player and continue
                if (this.Players[0] != bestPlayer)
                {
                    Console.WriteLine("Best deck:");
                    foreach (ReadableCard card in this.Players[0].SortedDeck)
                    {
                        Console.WriteLine(card.Name);
                    }
                    bestPlayer = this.Players[0];
                }
                Console.WriteLine("Win ratio: " + bestPlayer.NumWins + "/" + (bestPlayer.NumWins + bestPlayer.NumLosses));

                // Choose a player with rank better than median, make a mutated version, insert the mutated version at the median, and remove the worst-ranked player
                int middleIndex            = this.Players.Count / 2;
                int indexToClone           = this.random.Next(middleIndex);
                TournamentPlayer newPlayer = this.Players[indexToClone].Mutate(this);
                this.Players.Insert(middleIndex, newPlayer);
                this.Players.RemoveAt(this.Players.Count - 1);
            }
        }
Example #7
0
        public void PlayGame(int player1Index, int player2Index)
        {
            List <TournamentPlayer> players = new List <TournamentPlayer>();
            TournamentPlayer        player1 = this.Players[player1Index];
            TournamentPlayer        player2 = this.Players[player2Index];

            players.Add(this.Players[player1Index]);
            players.Add(this.Players[player2Index]);
            Game game = this.referee.NewGame(players);

            if (player1Index == 0 || player2Index == 0)
            {
                game.ShouldPrint = true;
            }
            game.Play();
            if (game.GetWinner() != null)
            {
                TournamentPlayer winner = game.GetWinner().SourcePlayer;
                int winnerIndex, loserIndex;
                TournamentPlayer loser = null;
                if (winner == player1)
                {
                    winnerIndex = player1Index;
                    loserIndex  = player2Index;
                }
                else
                {
                    if (winner == player2)
                    {
                        winnerIndex = player2Index;
                        loserIndex  = player1Index;
                    }
                    else
                    {
                        return;
                    }
                }
                loser = this.Players[loserIndex];
                winner.NumWins++;
                loser.NumLosses++;

                if (winnerIndex > 0)
                {
                    // improve winner's rank by 1
                    this.Players.RemoveAt(winnerIndex);
                    winnerIndex--;
                    this.Players.Insert(winnerIndex, winner);
                    if (winnerIndex == loserIndex)
                    {
                        return;
                    }
                }
                // worsen losers's rank by 1
                if (loserIndex < players.Count - 1)
                {
                    this.Players.RemoveAt(loserIndex);
                    loserIndex++;
                    this.Players.Insert(loserIndex, loser);
                }
            }
        }