public void Test_GetHandSizes()
        {
            string         testResourcesPath = UTHelper.GetTestResourceDir(Assembly.GetExecutingAssembly());
            GameDefinition gd =
                XmlSerializerExt.Deserialize <GameDefinition>(Path.Combine(testResourcesPath, "gamedef-test.xml"));

            int[] handSizes = gd.GetHandSizes();
            Assert.AreEqual(new int [] { 2, 5, 6, 7 }, handSizes);
        }
示例#2
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);
        }