/// <summary>
        /// Computes a preference matrix with preference probability based on maximum of pocket equity
        /// for given pairs (0 or 1). Pocket equity is given by PocketEquity class.
        /// </summary>
        public static double[,] ComputePreferenceMatrixPeMax(HePocketKind [] pockets)
        {
            int n = pockets.Length;

            double[] cardProbabs = PocketHelper.GetProbabDistr(pockets);
            double[,] ptMax = new double[n, n];
            for (int i = 0; i < n; ++i)
            {
                HePocketKind p1 = pockets[i];
                for (int j = 0; j <= i; ++j)
                {
                    HePocketKind        p2 = pockets[j];
                    PocketEquity.Result r  = PocketEquity.CalculateFast(p1, p2);
                    if (i == j || r.Equity == 0.5)
                    {
                        ptMax[i, j] = 0.5;
                    }
                    else
                    {
                        ptMax[i, j] = r.Equity > 0.5 ? 1 : 0;
                    }
                    ptMax[j, i] = 1 - ptMax[i, j];
                }
            }
            return(ptMax);
        }
Beispiel #2
0
        public static Result CalculateFast(HePocketKind p1, HePocketKind p2)
        {
            if (_lut == null)
            {
                LoadLut();
            }
            Precalculated key     = new Precalculated();
            bool          reverse = p1 > p2;

            if (reverse)
            {
                key.PocketKind1 = (byte)p2;
                key.PocketKind2 = (byte)p1;
            }
            else
            {
                key.PocketKind1 = (byte)p1;
                key.PocketKind2 = (byte)p2;
            }
            int    i = Array.BinarySearch(_lut, key, _precalculatedComparer);
            Result r = new Result {
                Count = _lut[i].Count
            };

            if (reverse)
            {
                r.Equity = 1 - _lut[i].Equity;
            }
            else
            {
                r.Equity = _lut[i].Equity;
            }
            return(r);
        }
Beispiel #3
0
 public static HePocketKind[] GetAllPockets()
 {
     HePocketKind[] result = new HePocketKind[169];
     for (int i = 0; i < 169; ++i)
     {
         result[i] = (HePocketKind)i;
     }
     return(result);
 }
Beispiel #4
0
 public void Test_KindToString_StringToKind()
 {
     for (int p = 0; p < (int)HePocketKind.__Count; ++p)
     {
         HePocketKind kind       = (HePocketKind)p;
         string       kindString = HePocket.KindToString(kind);
         HePocketKind kind1      = HePocket.StringToKind(kindString);
         Assert.AreEqual(kind, kind1);
     }
 }
Beispiel #5
0
 public void Test_HsSd_Pockets()
 {
     for (int p = 0; p < HePocket.Count; ++p)
     {
         HePocketKind pk   = (HePocketKind)p;
         int[]        hand = HePocket.KindToHand(pk);
         float[]      hssd = HsSd.Calculate(hand, 1);
         Console.WriteLine("{0} {1:0.0000} {2:0.0000}", HePocket.KindToString(pk),
                           hssd[0], hssd[1]);
     }
 }
        public void Test_Constructor()
        {
            // No preflop bucketing by pocket
            Props p = new string[]
            {
                "SomeProp", "SomeVal"
            };
            PreflopPocketCA pfca = new PreflopPocketCA(p, 4);

            Assert.IsNull(pfca.PocketKindToAbstrCard);

            // Do preflop bucketing by pocket
            p = new string[]
            {
                "Pockets3", "AA KK",
                "Pockets2", "QQ JJ TT",
                "Pockets1", "AKs AKo AQs",
            };
            pfca = new PreflopPocketCA(p, 4);
            Assert.IsNotNull(pfca.PocketKindToAbstrCard);
            Assert.AreEqual((int)HePocketKind.__Count, pfca.PocketKindToAbstrCard.Length);
            for (int i = 0; i < (int)HePocketKind.__Count; ++i)
            {
                HePocketKind pk = (HePocketKind)i;
                switch (pk)
                {
                case HePocketKind._AA:
                case HePocketKind._KK:
                    Assert.AreEqual(3, pfca.PocketKindToAbstrCard[i]);
                    break;

                case HePocketKind._QQ:
                case HePocketKind._JJ:
                case HePocketKind._TT:
                    Assert.AreEqual(2, pfca.PocketKindToAbstrCard[i]);
                    break;

                case HePocketKind._AKs:
                case HePocketKind._AKo:
                case HePocketKind._AQs:
                    Assert.AreEqual(1, pfca.PocketKindToAbstrCard[i]);
                    break;

                default:
                    Assert.AreEqual(0, pfca.PocketKindToAbstrCard[i], pk.ToString());
                    break;
                }
            }
        }
Beispiel #7
0
 public double Equity(int[] range1, int[] range2)
 {
     HePocketKind [] prange1 = new HePocketKind[range1.Length];
     HePocketKind [] prange2 = new HePocketKind[range2.Length];
     for (int i = 0; i < range1.Length; ++i)
     {
         prange1[i] = (HePocketKind)range1[i];
     }
     for (int i = 0; i < range2.Length; ++i)
     {
         prange2[i] = (HePocketKind)range2[i];
     }
     PocketEquity.Result r = PocketEquity.CalculateFast(prange1, prange2);
     return(r.Equity);
 }
        public void Test_CalculateFast_Array()
        {
            HePocketKind[] pockets1 = new HePocketKind[] { HePocketKind._55, HePocketKind._66 };
            HePocketKind[] pockets2 = new HePocketKind[] { HePocketKind._76s, HePocketKind._76o };

            PocketEquity.Result r = PocketEquity.CalculateFast(pockets1, pockets2);
            Assert.AreEqual(0.56058, r.Equity, 0.000005);
            Assert.AreEqual(246571776L / EnumAlgos.CountCombin(48,5), r.Count);

            pockets1 = new HePocketKind[] { HePocketKind._AKs, HePocketKind._AQs };
            pockets2 = new HePocketKind[] { HePocketKind._88, HePocketKind._77 };

            r = PocketEquity.CalculateFast(pockets1, pockets2);
            Assert.AreEqual(0.47681, r.Equity, 0.000005);
            Assert.AreEqual(164381184L / EnumAlgos.CountCombin(48, 5), r.Count);
        }
Beispiel #9
0
        public void Print(TextWriter tw)
        {
            tw.WriteLine("{0}", Name);
            int[] totalCount = new int[_positions.Count];
            for (int pos = 0; pos < _positions.Count; pos++)
            {
                foreach (Record r in _positions[pos])
                {
                    totalCount[pos] += r.count;
                }
            }

            tw.Write("Pos ");
            for (int pos = 0; pos < _positions.Count; pos++)
            {
                tw.Write("                                    {0}", pos);
            }
            tw.WriteLine();

            tw.Write("Poc ");
            for (int pos = 0; pos < _positions.Count; pos++)
            {
                tw.Write("     Count    Result     Av,mb   Freq");
            }
            tw.WriteLine();

            Record [] totalRecord = new Record[_positions.Count].Fill(i => new Record());

            for (HePocketKind pocketKind = 0; pocketKind < HePocketKind.__Count; ++pocketKind)
            {
                Console.Write("{0,-3} ", pocketKind.ToString().Substring(1));
                for (int pos = 0; pos < _positions.Count; pos++)
                {
                    Record r = _positions[pos][(int)pocketKind];
                    totalRecord[pos].result += r.result;
                    totalRecord[pos].count  += r.count;
                    PrintRecord(tw, totalCount[pos], r);
                }
                Console.WriteLine();
            }
            Console.Write("ALL ");
            for (int pos = 0; pos < _positions.Count; pos++)
            {
                PrintRecord(tw, totalCount[pos], totalRecord[pos]);
            }
            Console.WriteLine();
        }
Beispiel #10
0
        /// <summary>
        /// Initializes a class from properties.
        /// For each preflop bucket it expects a a property in the following format:
        /// <para>name: "Pockets7", value: "AA KK QQ JJ TT 99 AKs"</para>
        /// <para>If there is no such properties at all, it is assumed that this CA does
        /// not use preflop pocket bucketizing. In this case the property PocketKindToAbstrCard returns null.</para>
        /// <para>If any such a property exists, than all other in range [1..bucketsCount-1] must be specified,
        /// otherwise an ArgumentException it thrown.</para>
        /// <para>All pockets unspecified in such properties go to bucket 0 (even if its property specifed explicitely).</para>
        /// </summary>
        public PreflopPocketCA(Props parameters, int bucketsCount)
        {
            bool isPreflopPocketBucketizingUsed = false;

            for (int b = bucketsCount - 1; b >= 0; --b)
            {
                string propName = "Pockets" + b.ToString();
                string value    = parameters.Get(propName);
                if (!string.IsNullOrEmpty(value))
                {
                    isPreflopPocketBucketizingUsed = true;
                    break;
                }
            }

            if (!isPreflopPocketBucketizingUsed)
            {
                return;
            }

            PocketKindToAbstrCard = new int[(int)HePocketKind.__Count];

            for (int b = bucketsCount - 1; b >= 0; --b)
            {
                string propName = "Pockets" + b.ToString();
                string value    = parameters.Get(propName);
                if (string.IsNullOrEmpty(value))
                {
                    if (b == 0)
                    {
                        // This can be left out.
                        continue;
                    }
                    throw new ArgumentException(string.Format("Pockets{0} is not specified", b));
                }
                string[] bucketKinds = value.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string kindString in bucketKinds)
                {
                    HePocketKind kind = HePocket.StringToKind(kindString);
                    PocketKindToAbstrCard[(int)kind] = b;
                }
            }
        }
Beispiel #11
0
        static HePocket()
        {
            int[] rangePos = new int[(int)HePocketKind.__Count];
            for (int p = 0; p < (int)HePocketKind.__Count; ++p)
            {
                HePocketKind kind       = (HePocketKind)p;
                string       name       = kind.ToString();
                string       kindString = name.Substring(1);

                _kindToString[p] = kindString;
                _stringToKind.Add(kindString, kind);

                string  c1        = name.Substring(1, 1);
                string  c2        = name.Substring(2, 1);
                string  type      = name.Length == 4 ? name.Substring(3, 1) : "";
                CardSet cs        = new CardSet();
                int     rangeSize = 6;
                if (type == "s")
                {
                    // Suited
                    cs        = StdDeck.Descriptor.GetCardSet(c1 + "c " + c2 + "c");
                    rangeSize = 4;
                }
                else if (type == "o")
                {
                    // Offsuit
                    cs        = StdDeck.Descriptor.GetCardSet(c1 + "c " + c2 + "d");
                    rangeSize = 12;
                }
                else
                {
                    // Pair
                    cs        = StdDeck.Descriptor.GetCardSet(c1 + "c " + c2 + "d");
                    rangeSize = 6;
                }

                _kindToSuitNormalizedCardset[p] = cs;
                _kindToHand[p]          = StdDeck.Descriptor.GetIndexesAscending(cs).ToArray();
                _cardSetToKind[cs]      = kind;
                _kindToRange[(int)kind] = new CardSet[rangeSize];
            }
            CardEnum.Combin(StdDeck.Descriptor, 2, CardSet.Empty, CardSet.Empty, AddPocket, rangePos);
        }
        /// <summary>
        /// Computes a preference matrix with preference probability based on pocket equity
        /// given by PocketEquity class.
        /// </summary>
        public static double[,] ComputePreferenceMatrixPe(HePocketKind[] pockets)
        {
            int n = pockets.Length;

            double[] cardProbabs = PocketHelper.GetProbabDistr(pockets);
            double[,] ptEq = new double[n, n];
            for (int i = 0; i < n; ++i)
            {
                HePocketKind p1 = pockets[i];
                for (int j = 0; j <= i; ++j)
                {
                    HePocketKind        p2 = pockets[j];
                    PocketEquity.Result r  = PocketEquity.CalculateFast(p1, p2);
                    ptEq[i, j] = r.Equity;
                    ptEq[j, i] = 1 - ptEq[i, j];
                }
            }
            return(ptEq);
        }
Beispiel #13
0
        private ChanceTree CreateCt(HePocketKind[] sbCards, HePocketKind[] bbCards)
        {
            int        nodeCount = 1 + sbCards.Length + sbCards.Length * bbCards.Length;
            ChanceTree ct        = new ChanceTree(nodeCount);

            ct.PlayersCount    = 2;
            ct.Nodes[0].Probab = 1;
            ct.SetDepth(0, 0);

            int totalCombSB = 0;

            foreach (HePocketKind p in sbCards)
            {
                totalCombSB += HePocket.KindToRange(p).Length;
            }

            for (int c0 = 0; c0 < sbCards.Length; ++c0)
            {
                int          sbNode   = 1 + c0 * (bbCards.Length + 1);
                HePocketKind sbPocket = sbCards[c0];
                ct.SetDepth(sbNode, 1);
                ct.Nodes[sbNode].Position = 0;
                ct.Nodes[sbNode].Probab   = (double)HePocket.KindToRange(sbPocket).Length / totalCombSB;
                ct.Nodes[sbNode].Card     = c0;

                double[] oppDealProbabCond = PocketHelper.GetProbabDistr(bbCards, HePocket.KindToCardSet(sbPocket));

                for (int c1 = 0; c1 < bbCards.Length; ++c1)
                {
                    int bbNode = sbNode + 1 + c1;
                    ct.SetDepth(bbNode, 2);
                    ct.Nodes[bbNode].Position = 1;
                    ct.Nodes[bbNode].Probab   = ct.Nodes[sbNode].Probab * oppDealProbabCond[c1];
                    ct.Nodes[bbNode].Card     = c1;
                    PocketEquity.Result pe = PocketEquity.CalculateFast(sbPocket, bbCards[c1]);
                    var potShare           = new double[] { pe.Equity, 1 - pe.Equity };
                    ct.Nodes[bbNode].SetPotShare(3, potShare);
                }
            }
            VerifyChanceTree.VerifyS(ct, 1e-5);
            return(ct);
        }
Beispiel #14
0
        public static void PrintPreflopRanges(IChanceAbstraction ca)
        {
            List <HePocketKind>[] abstrRanges = new List <HePocketKind> [0];
            int[] abstrRangesSizes            = new int[0];

            for (int p = 0; p < (int)HePocketKind.__Count; ++p)
            {
                HePocketKind kind      = (HePocketKind)p;
                CardSet      pocketCS  = HePocket.KindToCardSet(kind);
                int []       pocketArr = StdDeck.Descriptor.GetIndexesAscending(pocketCS).ToArray();
                int          abstrCard = ca.GetAbstractCard(pocketArr, pocketArr.Length);

                if (abstrCard >= abstrRanges.Length)
                {
                    Array.Resize(ref abstrRanges, abstrCard + 1);
                    Array.Resize(ref abstrRangesSizes, abstrCard + 1);
                }
                if (abstrRanges[abstrCard] == null)
                {
                    abstrRanges[abstrCard] = new List <HePocketKind>();
                }

                abstrRanges[abstrCard].Add(kind);
                abstrRangesSizes[abstrCard] += HePocket.KindToRange(kind).Length;
            }

            Console.WriteLine("Preflop ranges of CA: {0}", ca.Name);
            int total = 0;

            for (int i = abstrRanges.Length - 1; i >= 0; --i)
            {
                Console.Write("{0,2} ({1,4}):", i, abstrRangesSizes[i]);
                foreach (HePocketKind k in abstrRanges[i])
                {
                    Console.Write(" {0}", HePocket.KindToString(k));
                }
                Console.WriteLine();
                total += abstrRangesSizes[i];
            }
            Console.WriteLine("Total: {0}", total);
        }
Beispiel #15
0
        public void Test_Pockets_Overall()
        {
            Console.WriteLine("Pocket hand strengths:");
            int [] indexes      = new int[2];
            double weighedSumHs = 0;
            int    sumCount     = 0;

            for (int i = 0; i < (int)HePocketKind.__Count; ++i)
            {
                HePocketKind pk    = (HePocketKind)i;
                int[]        hand  = HePocket.KindToHand(pk);
                double       s     = HandStrength.CalculateFast(hand);
                int          count = HePocket.KindToRange(pk).Length;
                Console.WriteLine("{0}  {1:0.0000} {2}", HePocket.KindToString(pk), s, count);
                weighedSumHs += s * count;
                sumCount     += count;
            }
            Console.WriteLine("Weighed sum:  {0:0.0000} {1}", weighedSumHs, sumCount);
            Assert.AreEqual(1326, sumCount);
            Assert.AreEqual(1326 * 0, 5, weighedSumHs, "Overall result must be 0.5 (tie)");
        }
        public void Test_CallKK()
        {
            string outDir = Path.Combine(_outDir, "call-KK");

            Directory.CreateDirectory(outDir);
            HePocketKind[] sbPockets = new HePocketKind[] { HePocketKind._AA, HePocketKind._KK, HePocketKind._AKs };
            HePocketKind[] bbPockets = new HePocketKind[] { HePocketKind._AA, HePocketKind._KK, HePocketKind._QQ, HePocketKind._AKs };

            string     xmlAt = Props.Global.Expand("${bds.DataDir}ai.pkr.holdem.learn/bigcards-pf-1.xml");
            ActionTree at    = XmlToActionTree.Convert(xmlAt);

            VisActionTree.Show(at, Path.Combine(outDir, "at.gv"));

            BigCardsPreflop bc = new BigCardsPreflop();

            bc.Solve(at, sbPockets, bbPockets);

            Console.WriteLine("Game values: {0}, {1}", bc.GameValues[0], bc.GameValues[1]);
            VisChanceTree.Show(bc.Ct, Path.Combine(outDir, "ct.gv"));
            VisStrategyTree.Show(bc.Strategies[0], Path.Combine(outDir, "st-0.gv"));
            VisStrategyTree.Show(bc.Strategies[1], Path.Combine(outDir, "st-1.gv"));
        }
Beispiel #17
0
 public void Update(GameRecord gameRecord)
 {
     for (int pos = 0; pos < gameRecord.Players.Count; ++pos)
     {
         GameRecord.Player player = gameRecord.Players[pos];
         if (player.Name == _hero)
         {
             Allocate(pos);
             foreach (PokerAction action in gameRecord.Actions)
             {
                 if (action.Kind == Ak.d && action.Position == pos)
                 {
                     CardSet      pocket     = StdDeck.Descriptor.GetCardSet(action.Cards);
                     HePocketKind pocketKind = HePocket.CardSetToKind(pocket);
                     _positions[pos][(int)pocketKind].count++;
                     _positions[pos][(int)pocketKind].result += player.Result;
                 }
             }
             break;
         }
     }
 }
Beispiel #18
0
        private Bucket[] CreatePreflopBuckets(int preflopBucketsCount)
        {
            Bucket[] buckets = new Bucket[preflopBucketsCount].Fill(i => new Bucket());

            int totalHands = 0;

            for (int i = 0; i < HePocket.Count; ++i)
            {
                HePocketKind pk = (HePocketKind)i;
                // Use all possible pockets for each pocket kind. This ensures
                // that they occur with the natural frequency in a typical case where
                // a bucket contain pocket kinds with different numbers of pockets (e.g. AA - 6, AKs - 4, AKo - 12).
                CardSet [] range = HePocket.KindToRange(pk);
                foreach (CardSet pocketCs in range)
                {
                    McHand  hand   = new McHand();
                    int[]   pocket = StdDeck.Descriptor.GetIndexesAscending(pocketCs).ToArray();
                    CardSet restCs = StdDeck.Descriptor.FullDeck;
                    restCs.Remove(pocketCs);
                    int[] rest = StdDeck.Descriptor.GetIndexesAscending(restCs).ToArray();
                    Debug.Assert(pocket.Length + rest.Length == 52);

                    pocket.CopyTo(hand.Cards, 0);
                    rest.CopyTo(hand.Cards, 2);
                    hand.Length = 2;

                    int abstrCard = Clusterizer.GetAbstractCard(hand.Cards, hand.Length);
                    buckets[abstrCard].Hands.Add(hand);
                    totalHands++;
                }
            }
            Debug.Assert(totalHands == 1326);
            if (IsVerbose)
            {
                Console.WriteLine("Preflop buckets created, buckets: {0}, hands: {1}", buckets.Length, totalHands);
            }

            return(buckets);
        }
Beispiel #19
0
        public void Test_KindToRange_CardSetToKind_KindToSuiteNormalizedCardSet()
        {
            HashSet <CardSet> uniquePockets = new HashSet <CardSet>();

            for (int p = 0; p < (int)HePocketKind.__Count; ++p)
            {
                HePocketKind kind   = (HePocketKind)p;
                CardSet[]    range  = HePocket.KindToRange(kind);
                CardSet      ncsExp = HePocket.KindToCardSet(kind);
                foreach (CardSet cs in range)
                {
                    Assert.AreEqual(kind, HePocket.CardSetToKind(cs), "Each pocket from range must be of the expected kind.");
                    NormSuit ns  = new NormSuit();
                    CardSet  ncs = ns.Convert(cs);
                    Assert.AreEqual(ncsExp, ncs, "Card set from ranges must transform to same normalized card set");

                    // This will throw an exception if some pockets were duplicated.
                    uniquePockets.Add(cs);
                }
            }
            Assert.AreEqual(1326, uniquePockets.Count);
        }
Beispiel #20
0
 public void Test_HePockets()
 {
     double[] cardProbabs = new double[169];
     for (int i = 0; i < 169; ++i)
     {
         cardProbabs[i] = HePocket.KindToRange((HePocketKind)i).Length / 1326.0;
     }
     double[,] ptEq  = MultiplayerPocketProbability.ComputePreferenceMatrixPe(PocketHelper.GetAllPockets());
     double[,] ptMax = MultiplayerPocketProbability.ComputePreferenceMatrixPeMax(PocketHelper.GetAllPockets());
     double[][] resEq  = new double[10][];
     double[][] resMax = new double[10][];
     for (int pc = 1; pc < 10; ++pc)
     {
         resEq[pc] = MultiplayerPocketProbability.Compute(pc, cardProbabs, ptEq);
         VerifyResult(169, resEq[pc]);
         resMax[pc] = MultiplayerPocketProbability.Compute(pc, cardProbabs, ptMax);
         VerifyResult(169, resMax[pc]);
     }
     Console.WriteLine();
     Console.Write("{0,3} ", "Poc");
     for (int pc = 1; pc < 10; ++pc)
     {
         Console.Write("{0,6} {1,6} ", pc.ToString() + " eq", pc.ToString() + " max");
     }
     Console.WriteLine();
     for (int i = 0; i < 169; ++i)
     {
         HePocketKind p = (HePocketKind)i;
         Console.Write("{0,3} ", HePocket.KindToString(p));
         for (int pc = 1; pc < 10; ++pc)
         {
             Console.Write("{0,6:0.00} {1,6:0.00} ", resEq[pc][i] * 100, resMax[pc][i] * 100);
         }
         Console.WriteLine();
     }
 }
Beispiel #21
0
 public Entry01(HePocketKind pocketKind, CardSet board)
 {
     Key = GetKey((int)pocketKind, board);
     Hs  = Sd3 = SdPlus1 = 0;
 }
Beispiel #22
0
 public static Result Calculate(HePocketKind p1, HePocketKind p2)
 {
     CardSet[] csRange1 = HePocket.KindToRange(p1);
     CardSet[] csRange2 = HePocket.KindToRange(p2);
     return(CalculateNoVerify(csRange1, csRange2));
 }
Beispiel #23
0
 /// <summary>
 /// Returns a single suit-normalized cards set, e.g. AKs -> AcKc, AKo -> AcKd.
 /// </summary>
 public static CardSet KindToCardSet(HePocketKind pocketKind)
 {
     return(_kindToSuitNormalizedCardset[(int)pocketKind]);
 }
Beispiel #24
0
 /// <summary>
 /// Converts a kind to a suit-normalized hand.
 /// </summary>
 public static int[] KindToHand(HePocketKind kind)
 {
     return(_kindToHand[(int)kind]);
 }
        protected int GetPreflopAbstrCard(int[] hand)
        {
            HePocketKind pk = HePocket.HandToKind(hand);

            return(_pfPocketCa.PocketKindToAbstrCard[(int)pk]);
        }
Beispiel #26
0
 public Entry(HePocketKind pocketKind, CardSet board)
 {
     key   = GetKey((int)pocketKind, board);
     value = 0;
 }
Beispiel #27
0
 public static CardSet [] KindToRange(HePocketKind kind)
 {
     return(_kindToRange[(int)kind]);
 }
Beispiel #28
0
 /// <summary>
 /// Converts a kind to a regular string representation, for example KQs.
 /// </summary>
 public static string KindToString(HePocketKind kind)
 {
     return(_kindToString[(int)kind]);
 }
Beispiel #29
0
        private static void MonteCarlo()
        {
            // Create new arrays for preflop values
            for (int pos = 0; pos < 2; ++pos)
            {
                _createPreflopValues.Walk(_neytiri, _neytiri.Positions[pos]);
            }

            DateTime start = DateTime.Now;

            for (int ourPos = 0; ourPos < _neytiri.Positions.Length; ++ourPos)
            {
                Console.WriteLine("Position {0}", ourPos);

                ActionTreeNode        root         = _neytiri.Positions[1 - ourPos];
                List <ActionTreeNode> strategyPath = new List <ActionTreeNode>(100);
                strategyPath.Add(root);
                // Advance to the node where we get cards
                while (strategyPath[strategyPath.Count - 1].State.CurrentActor != ourPos)
                {
                    strategyPath.Add(strategyPath[strategyPath.Count - 1].Children[0]);
                }
                for (HePocketKind pocketKind = 0; pocketKind < HePocketKind.__Count; ++pocketKind)
                {
                    CardSet pocket = HePockets.PocketKindToCardSet(pocketKind);

                    if (_pockets.Count > 0 && !_pockets.Contains(pocket))
                    {
                        // Skip the pocket if command line specifies which pockets to include and it's not there.
                        continue;
                    }

                    Console.Write("{0} ", pocketKind.ToString().Substring(1));

                    MonteCarloStrategyFinder.DoMonteCarlo(_neytiri,
                                                          ourPos, pocket, 0, "",
                                                          strategyPath, _cmdLine.mcCount);

                    WalkTree <ActionTree, ActionTreeNode, int> copyValues =
                        new WalkTree <ActionTree, ActionTreeNode, int>
                    {
                        OnNodeBegin = (t, n, s, d) =>
                        {
                            if (n.State.Round > 0)
                            {
                                return(false);
                            }
                            n.PreflopValues[(int)pocketKind] = n.Value;
                            return(true);
                        }
                    };
                    copyValues.Walk(_neytiri, root);
                }
                Console.WriteLine();
            }
            DateTime finish = DateTime.Now;
            double   sec    = (finish - start).TotalSeconds;

            Console.WriteLine("Done {0} monte-carlo trials for every pocket in each position in {1:0.0} sec",
                              _cmdLine.mcCount, sec);
            Console.WriteLine("Writing Neytiri strategy to {0} ...", _cmdLine.neytiri);
            _neytiri.XmlSerialize(_cmdLine.neytiri, new XmlWriterSettings {
                Indent = false
            });
        }