Пример #1
0
        /// <summary>
        /// Generates some random hands and verifies the result.
        /// </summary>
        /// <param name="gd"></param>
        /// <param name="repCount"></param>
        void Verify(GameDefinition gd, int playersCount, int repCount)
        {
            int seed = (int)DateTime.Now.Ticks;

            Console.WriteLine("Game: {0}, players: {1}, RNG seed: {2}", gd.Name, playersCount, seed);
            McDealer mcDealer = new McDealer(gd, seed);

            List <bool> isSharedDeal    = new List <bool>();
            int         totalCardsCount = 0;

            for (int r = 0; r < gd.RoundsCount; ++r)
            {
                for (int i = 0; i < gd.PublicCardsCount[r] + gd.PrivateCardsCount[r]; ++i)
                {
                    isSharedDeal.Add(false);
                }
                totalCardsCount += (gd.PublicCardsCount[r] + gd.PrivateCardsCount[r]) * playersCount;

                for (int i = 0; i < gd.SharedCardsCount[r]; ++i)
                {
                    isSharedDeal.Add(true);
                }
                totalCardsCount += gd.SharedCardsCount[r];
            }
            Assert.AreEqual(isSharedDeal.Count, mcDealer.HandSize);
            int [][] hands = new int[playersCount][].Fill(i => new int[isSharedDeal.Count]);
            for (int rep = 0; rep < repCount; ++rep)
            {
                mcDealer.NextDeal(hands);
                HashSet <int> distinctCards = new HashSet <int>();
                for (int d = 0; d < isSharedDeal.Count; ++d)
                {
                    if (isSharedDeal[d])
                    {
                        // Make sure all players has the same card.
                        for (int p = 0; p < playersCount; ++p)
                        {
                            Assert.AreEqual(hands[0][d], hands[p][d]);
                        }
                        Assert.IsFalse(distinctCards.Contains(hands[0][d]));
                        distinctCards.Add(hands[0][d]);
                    }
                    else
                    {
                        // Add cards of each player to the set. If multiple players have
                        // this card or it was dealt before, we will get an error.
                        for (int p = 0; p < playersCount; ++p)
                        {
                            Assert.IsFalse(distinctCards.Contains(hands[p][d]));
                            distinctCards.Add(hands[p][d]);
                        }
                    }
                }
                Assert.AreEqual(totalCardsCount, distinctCards.Count);
            }
        }
Пример #2
0
        void Benchmark(GameDefinition gd, int playersCount, int repCount)
        {
            int      seed     = (int)DateTime.Now.Ticks;
            McDealer mcDealer = new McDealer(gd, seed);

            int[][] hands    = new int[playersCount][].Fill(i => new int[mcDealer.HandSize]);
            int     checksum = 0;

            DateTime startTime = DateTime.Now;

            for (int rep = 0; rep < repCount; ++rep)
            {
                mcDealer.NextDeal(hands);
                checksum += hands[0][0];
            }
            double time = (DateTime.Now - startTime).TotalSeconds;

            Console.WriteLine("Game: {0}, players: {1}, repetitions: {2:0,0}, time: {3:0.000} s, {4:0,0} deals/s",
                              gd.Name, playersCount, repCount, time, repCount / time);
        }
Пример #3
0
        /// <summary>
        /// Now do fictious play repeatedly.
        /// </summary>
        private void DoIterations()
        {
            DateTime start = DateTime.Now;

            // Start from the player with minimal iteration count, if equal, start from 0.
            int minIterCount = int.MaxValue;

            for (int p = 0; p < _playersCount; ++p)
            {
                if (minIterCount > IterationCounts[p])
                {
                    _heroPos     = p;
                    minIterCount = IterationCounts[p];
                }
            }

            for (CurrentIterationCount = 0; ; _heroPos = (_heroPos + 1) % _playersCount)
            {
                if (MaxIterationCount >= 0 && CurrentIterationCount >= MaxIterationCount)
                {
                    break;
                }
                IterationCounts[_heroPos]++;
                CurrentIterationCount++;

                _mcDealer.NextDeal(new int[][] { _hands[_heroPos] });
                DealOppCardsAndCalculateGV();

                BestResponse();

                if (CurrentIterationCount >= _playersCount)
                {
                    // Calculate espsilon as soon as we have done SBR for each player at least once.
                    CurrentEpsilon = 0;
                    for (int p = 0; p < _playersCount; ++p)
                    {
                        CurrentEpsilon += LastBrValues[p];
                    }
                    CurrentEpsilon = Math.Abs(CurrentEpsilon);
                    UpdateEpsilonLog();
                }
                else
                {
                    CurrentEpsilon = Double.MaxValue;
                }

                _iterationTime = (DateTime.Now - start).TotalSeconds;

                if (IsIterationVerbose())
                {
                    PrintIterationStatus(Console.Out);
                }

                if (CheckExitCriteria())
                {
                    break;
                }
            }

            if (IsVerbose)
            {
                PrintIterationStatus(Console.Out);
            }
        }
Пример #4
0
        /// <summary>
        /// Generate an internal chance tree by MC sampling.
        /// </summary>
        /// <param name="chanceAbstractions">An array of chance abstractions</param>
        /// <param name="areAbstractionsEqual">If the absractions are equal,
        /// one MC sample will update multiple nodes of the chance tree.</param>
        /// <param name="samplesCount">Number of samples. If equal absractions are used,
        /// less MC samples will be actually done to reach the specified numbers of updates.</param>
        /// <param name="rngSeed">RNG seed.</param>
        /// <param name="feedback">User feedback callback.</param>
        /// <returns></returns>
        public static Tree Generate(GameDefinition gd, IChanceAbstraction[] chanceAbstractions, bool areAbstractionsEqual, long samplesCount, int rngSeed, FeedbackDelegate feedback)
        {
            if (chanceAbstractions.Length != 2)
            {
                throw new ArgumentOutOfRangeException("Only heads up games are supported now");
            }
            McDealer mcDealer = new McDealer(gd, rngSeed);

            int [][] hands     = new int[chanceAbstractions.Length][].Fill(i => new int[mcDealer.HandSize]);
            int[]    handSizes = gd.GetHandSizes();

            Tree tree = new Tree
            {
                PlayersCount = chanceAbstractions.Length,
                RoundsCount  = gd.RoundsCount,
                SourceInfo   = GetSourceInfo(gd, chanceAbstractions)
            };

            Node root = tree.Root;

            byte[] abstrCards = new byte[gd.RoundsCount * chanceAbstractions.Length];
            uint[] ranks      = new uint[chanceAbstractions.Length];
            Int64  samplesDone;
            int    updateCount = areAbstractionsEqual ? 2 : 1;

            for (samplesDone = 0; samplesDone < samplesCount; samplesDone += updateCount)
            {
                if (feedback != null && (samplesDone % FEEDBACK_PERIOD == 0))
                {
                    if (!feedback(samplesDone))
                    {
                        break;
                    }
                }

                mcDealer.NextDeal(hands);
                gd.GameRules.Showdown(gd, hands, ranks);

                int c = 0;
                for (int r = 0; r < gd.RoundsCount; ++r)
                {
                    for (int p = 0; p < chanceAbstractions.Length; ++p)
                    {
                        int abstrCard = chanceAbstractions[p].GetAbstractCard(hands[p], handSizes[r]);
                        if (abstrCard < byte.MinValue || abstrCard > byte.MaxValue)
                        {
                            throw new ApplicationException(string.Format("Abstract card {0} out of byte range", abstrCard));
                        }
                        abstrCards[c++] = (byte)abstrCard;
                    }
                }

                for (int u = 0; ;)
                {
                    LeafT[] leaves   = tree.GetLeavesByCards(abstrCards);
                    int     lastCard = abstrCards[abstrCards.Length - 1];
                    leaves[lastCard].Update(ranks);

                    if (++u == updateCount)
                    {
                        break;
                    }

                    // If the abstractions are equal, we can update another node
                    // by permuting cards and results
                    // Note: implemented for 2 players only
                    for (c = 0; c < abstrCards.Length; c += 2)
                    {
                        ShortSequence.Swap(ref abstrCards[c], ref abstrCards[c + 1]);
                    }
                    ShortSequence.Swap(ref ranks[0], ref ranks[1]);
                }
            }
            tree.SamplesCount = (UInt64)samplesDone;
            tree.UpdateDescription();
            return(tree);
        }