public void Evaluate(List<IPlayer> players, Settings settings, bool champions, int games)
        {
            ResetScores(players);

            var seats = CreateSeats(players, settings.BigBlind * settings.StackSize);

            HandEngine engine = new HandEngine() { AnalyzeHands = true };

            for (int i = 0, handsThisTourney = 0;
                seats.Count > 3 && handsThisTourney < settings.MaxHandsPerTourney;
                i = (i + 1) % seats.Count, handsThisTourney++)
            {
                ulong handNumber;
                handNumber = GamesPlayed++;

                HandHistory history = new HandHistory(seats.ToArray(), GamesPlayed, (uint)seats[i].SeatNumber,
                                                        new double[] { settings.SmallBlind, settings.BigBlind },
                                                        0, BettingStructure.Limit);
                engine.PlayHand(history);

                if (champions)
                    LogHand(settings, history, handNumber > 1);

                RemoveBrokePlayers(settings, seats);
            }

            ScorePlayers(seats);
        }
        public void Evaluate(List<IPlayer> players, Settings settings, bool champions, int games)
        {
            ResetScores(players);
            int[] handsPlayed = new int[players.Count];
            List<int> availablePlayers = new List<int>();
            for (int i = 0; i < players.Count; i++)
                availablePlayers.Add(i);

            double startingChips = settings.BigBlind * settings.StackSize;

            HandEngine engine = new HandEngine() { AnalyzeHands = false };

            int handsThisGeneration = 0;
            while(availablePlayers.Count >= settings.PlayersPerGame)
            {
                ulong handNumber = GamesPlayed++;

                List<int> playerIndices = champions ?
                                            CreateShuffledChampionsList(settings) :
                                            availablePlayers.RandomSubset(settings.PlayersPerGame, random);
                var seats = CreateSeats(players, startingChips, playerIndices);

                HandHistory history = new HandHistory(seats, GamesPlayed, (uint)settings.PlayersPerGame,
                                                        new double[] { settings.SmallBlind, settings.BigBlind },
                                                        0, BettingStructure.Limit);
                engine.PlayHand(history);
                handsThisGeneration++;

                if (champions)
                    LogHand(settings, history, handNumber > 1);

                if (handNumber % 100000 == 0)
                    lock(LogLock)
                        Console.WriteLine("Hand: {0}", handNumber);

                AddScores(startingChips, playerIndices, seats);
                IncrementHandsPlayedAndRemoveDone(games, handsPlayed, availablePlayers, playerIndices, champions);
            }

            //normalize win rates
            for (int i = 0; i < Scores.Count; i++)
            {
                Scores[i] /= (double)handsPlayed[i];
                Scores[i] /= settings.BigBlind;
                if (Scores[i] > 2)
                    Scores[i] = 2;
                else if (Scores[i] < -5)
                    Scores[i] = -5;
            }
        }
Exemple #3
0
        static void Main(string[] args)
        {
            HandEngine engine = new HandEngine();

            Console.WriteLine("Loading cached hands");
            List<CachedHand> cachedHands;
            XmlSerializer ser = new XmlSerializer(typeof(CachedHands));
            using (TextReader txt = new StreamReader("test.xml"))
                cachedHands = ((CachedHands)ser.Deserialize(txt)).Hands;

            var seats = new Seat[6];
            seats[0] = new Seat(1, "AlwaysRaise", 100000, new AlwaysRaisePlayer());
            seats[1] = new Seat(2, "AwaysCall", 100000, new AlwaysCallPlayer());
            seats[2] = new Seat(3, "AwaysCall2", 100000, new AlwaysCallPlayer());
            seats[3] = new Seat(4, "AwaysCall3", 100000, new AlwaysCallPlayer());
            seats[4] = new Seat(5, "AwaysCall4", 100000, new AlwaysCallPlayer());
            seats[5] = new Seat(6, "AwaysCall5", 100000, new AlwaysCallPlayer());
            var blinds = new double[] { 1, 2 };
            uint handNumber = 0;
            double maxDifference = 0;
            Console.WriteLine("Starting simulation");
            DateTime start = DateTime.Now;
            for (; handNumber < 100; handNumber++)
            {
                HandHistory results = new HandHistory(seats, handNumber, handNumber % (uint)seats.Length + 1, blinds, 0, BettingStructure.NoLimit);
                engine.PlayHand(results, cachedHands[(int)handNumber]);
                double difference = Math.Abs(seats[0].Chips - seats[1].Chips);
                if (difference > maxDifference)
                    maxDifference = difference;
                if (seats[0].Chips == 0 || seats[1].Chips == 0)
                    break;
            }
            int time = DateTime.Now.Subtract(start).Milliseconds;
            Console.WriteLine("Time: {0}", time);
            Console.WriteLine("Hands: {0}", handNumber);
            Console.WriteLine("AlwaysRaise Bankroll: {0}", seats[0].Chips);
            Console.WriteLine("AlwaysCall Bankroll: {0}", seats[1].Chips);
            Console.WriteLine("Max Difference: {0}", maxDifference);
        }
        public void EvaluatePopulation(Population pop, EvolutionAlgorithm ea)
        {
            var count = pop.GenomeList.Count;

            #region Reset the genomes

            for (var i = 0; i < count; i++)
            {
                pop.GenomeList[i].TotalFitness = EvolutionAlgorithm.MIN_GENOME_FITNESS;
                pop.GenomeList[i].EvaluationCount = 0;
                pop.GenomeList[i].Fitness = EvolutionAlgorithm.MIN_GENOME_FITNESS;
            }

            #endregion

            //TODO: Parallelize/Distribute this loop
            //Ideally we should have a distributed method which returns an array of
            //doubles to add to the genome fitnesses of each individual.
            for (var i = 0; i < count; i++)
            {
                Console.WriteLine("Individual #{0}", i + 1);
                var g = pop.GenomeList[i];

                var network = g.Decode(ActivationFunction);
                if (network == null)
                {
                    // Future genomes may not decode - handle the possibility.
                    g.Fitness = EvolutionAlgorithm.MIN_GENOME_FITNESS;
                    g.TotalFitness = g.Fitness;
                    g.EvaluationCount = 1;
                    continue;
                }

                HandEngine engine = new HandEngine();
                //Run multiple hands per individual
                for (var curGame = 0; curGame < GamesPerEvaluation; curGame++)
                {
                    #region Setup the players for this game

                    var field = new List<Seat>();
                    var stacks = GetStacks(PlayersPerGame);
                    var networks = new int[PlayersPerGame];
                    networks[0] = i;
                    IPlayer hero = null;//new NeuralNetworkPlayer(InputGenerator, OutputInterpreter,
                                   //                        network, Rand);
                    field.Add(new Seat(1, "Net_" + i, stacks[0], hero));

                    for (var curPlayer = 1; curPlayer < PlayersPerGame; curPlayer++)
                    {
                        INetwork nextNetwork = null;
                        var next = 0;
                        while (nextNetwork == null)
                        {
                            next = Rand.Next(0, count);
                            nextNetwork = pop.GenomeList[next].Decode(ActivationFunction);
                        }
                        networks[curPlayer] = next;
                        //"NeuralNet" + next, stacks[curPlayer],
                        IPlayer villain = null;// new NeuralNetworkPlayer(InputGenerator,
                                                 //          OutputInterpreter, nextNetwork, Rand);
                        field.Add(new Seat(curPlayer + 1, "Net" + next + "_Seat+ " + (curPlayer+1), stacks[curPlayer], villain));
                    }

                    #endregion

                    //Have the players play a single hand.
                    HandHistory history = new HandHistory(field.ToArray(), (ulong)curGame+1, (uint)(curGame % PlayersPerGame + 1),
                                                            new double[] { 1, 2 }, 0, BettingType);
                    CachedHand hand = CachedHands[Rand.Next(CachedHands.Count)];
                    engine.PlayHand(history);

                    #region Add the results to the players' fitness scores

                    //We'll use the profit as the fitness function.
                    //Alternatively, we could in the future experiment with using profit
                    //as a percentage of the original stacks. Or we could use the square
                    //of the profit (multiplying by -1 if the player lost money).
                    for (var curResult = 0; curResult < PlayersPerGame; curResult++)
                    {
                        var curGenome = pop.GenomeList[networks[curResult]];
                        curGenome.TotalFitness += field[curResult].Chips - stacks[curResult];
                        curGenome.EvaluationCount++;
                    }

                    #endregion

                    if (GamesPlayed % 10000 == 0)
                        using (TextWriter writer = new StreamWriter("game_" + GamesPlayed + ".txt"))
                            writer.WriteLine(history.ToString());

                    //increment the game counter
                    GamesPlayed++;
                }

            }

            //Normalize the fitness scores to use the win-rate
            for (var i = 0; i < count; i++)
            {
                pop.GenomeList[i].Fitness = Math.Max(pop.GenomeList[i].Fitness,
                                                     EvolutionAlgorithm.MIN_GENOME_FITNESS);
                pop.GenomeList[i].TotalFitness = Math.Max(pop.GenomeList[i].Fitness,
                                                     EvolutionAlgorithm.MIN_GENOME_FITNESS);
            }
        }