Example #1
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);
        }
Example #2
0
        public static ChanceTree CreateCt(HePocketKind [] pockets, double [] oppCardProbab)
        {
            int n = pockets.Count();

            double[] dealProbab = PocketHelper.GetProbabDistr(pockets);

            int        nodeCount = 1 + n + n * n;
            ChanceTree ct        = new ChanceTree(nodeCount);

            ct.PlayersCount    = 2;
            ct.Nodes[0].Probab = 1;
            ct.SetDepth(0, 0);
            for (int c0 = 0; c0 < n; ++c0)
            {
                int heroNode = 1 + c0 * (n + 1);
                ct.SetDepth(heroNode, 1);
                ct.Nodes[heroNode].Position = 0;
                ct.Nodes[heroNode].Probab   = dealProbab[c0];
                ct.Nodes[heroNode].Card     = c0;

                double[] corrOppProbab = CorrectOpponentProbab(pockets, c0, dealProbab, oppCardProbab);

                for (int c1 = 0; c1 < n; ++c1)
                {
                    int oppNode = heroNode + 1 + c1;
                    ct.SetDepth(oppNode, 2);
                    ct.Nodes[oppNode].Position = 1;
                    ct.Nodes[oppNode].Probab   = ct.Nodes[heroNode].Probab * corrOppProbab[c1];
                    ct.Nodes[oppNode].Card     = c1;
                    PocketEquity.Result pe = PocketEquity.CalculateFast(pockets[c0], pockets[c1]);
                    var potShare           = new double[] { pe.Equity, 1 - pe.Equity };
                    ct.Nodes[oppNode].SetPotShare(3, potShare);
                }
            }
            VerifyChanceTree.VerifyS(ct, 1e-5);
            return(ct);
        }
        void CopyFromTemp(ChanceTree newTree, TempNode tempNode, int depth)
        {
            newTree.SetDepth(_nodeCount, (byte)depth);
            newTree.Nodes[_nodeCount].Card     = tempNode.Card;
            newTree.Nodes[_nodeCount].Probab   = tempNode.Probab;
            newTree.Nodes[_nodeCount].Position = 0;
            _nodeCount++;
            List <int> cards = new List <int>(tempNode.Children.Keys.ToArray());

            cards.Sort();
            foreach (int card in cards)
            {
                CopyFromTemp(newTree, tempNode.Children[card], depth + 1);
            }
        }
Example #4
0
            bool SyncNodes(Node uniTree, object uniNode, byte uniDepth, int uniIt, UFTree ufTree, Int64 ufNode, object userData)
            {
                ChanceTree ct = (ChanceTree)ufTree;

                ct.SetDepth(ufNode, uniDepth);
                ct.Nodes[ufNode].Card     = uniDepth == 0 ? 0 : uniIt - 1;
                ct.Nodes[ufNode].Position = (uniDepth - 1) % PlayersCount;
                if (uniNode is LeafT)
                {
                    // This is a leaf
                    LeafT leaf = (LeafT)uniNode;

                    ct.Nodes[ufNode].Probab = (double)leaf.Count / SamplesCount;
                    double [] potShares = new double[2];
                    potShares[0] = 0.5 * leaf.Result / leaf.Count;
                    potShares[1] = 1 - potShares[0];
                    ct.Nodes[ufNode].SetPotShare(0x11, potShares);
                }
                else
                {
                    ct.Nodes[ufNode].Probab = 0;
                }
                return(true);
            }
Example #5
0
        public static ChanceTree FromTxt(TextReader r)
        {
            int ln = 0;
            int serializationFormat = int.Parse(TextDumpHelper.ReadTag(r, ref ln, "SeralizationFormat"));

            if (serializationFormat > SERIALIZATION_FORMAT)
            {
                throw new ApplicationException(String.Format("Line {0}: serialization format {1} is not supported by this version, max supported {2}",
                                                             ln, serializationFormat, SERIALIZATION_FORMAT));
            }
            string value;

            value = TextDumpHelper.ReadTag(r, ref ln, "Version");

            StringReader sr = new StringReader(value);
            BdsVersion   v;

            XmlSerializerExt.Deserialize(out v, sr);
            Int64      nodesCount  = Int64.Parse(TextDumpHelper.ReadTag(r, ref ln, "NodesCount"));
            int        roundsCount = int.Parse(TextDumpHelper.ReadTag(r, ref ln, "RoundsCount"));
            ChanceTree t           = new ChanceTree(nodesCount);

            t.SetNodesMemory(0); // Clear memory to ensure zeros at unused fields
            t.Version.CopyFrom(v);

            char [] separators = new char[] { ' ', '\t' };
            for (Int64 n = 0; n < nodesCount; ++n)
            {
                Int64 id = Int64.Parse(TextDumpHelper.ReadTag(r, ref ln, "Id"));
                if (id != n)
                {
                    throw new ApplicationException(String.Format("Line {0}: wrong node id '{1}', expected '{2}'", ln, id, n));
                }
                byte depth = byte.Parse(TextDumpHelper.ReadTag(r, ref ln, "D"));
                t.SetDepth(n, depth);
                t.Nodes[n].Position = int.Parse(TextDumpHelper.ReadTag(r, ref ln, "P"));
                t.Nodes[n].Card     = int.Parse(TextDumpHelper.ReadTag(r, ref ln, "C"));
                t.Nodes[n].Probab   = TextDumpHelper.BinStringToDouble(TextDumpHelper.ReadTag(r, ref ln, "Pr"));
                if (depth == t.PlayersCount * roundsCount)
                {
                    double[] potShare          = new double[t.PlayersCount];
                    UInt16[] activePlayerMasks = ActivePlayers.Get(t.PlayersCount, 2, t.PlayersCount);
                    for (int a = 0; a < activePlayerMasks.Length; ++a)
                    {
                        value = TextDumpHelper.ReadTag(r, ref ln, "Ps");
                        string[] parts = value.Split(separators, StringSplitOptions.RemoveEmptyEntries);
                        if (parts.Length != t.PlayersCount + 1)
                        {
                            throw new ApplicationException(
                                      String.Format("Line {0}: wrong number of values: '{1}', expected '{2}'", ln,
                                                    parts.Length, t.PlayersCount + 1));
                        }
                        UInt16 activePlayers = UInt16.Parse(parts[0], NumberStyles.AllowHexSpecifier);
                        for (int i = 1; i < parts.Length; ++i)
                        {
                            potShare[i - 1] = TextDumpHelper.BinStringToDouble(parts[i]);
                        }
                        t.Nodes[n].SetPotShare(activePlayers, potShare);
                    }
                }
            }
            return(t);
        }
Example #6
0
        private static void ProcessGameContext(GameContext context)
        {
            int            nodeId = context.Global.NodeId++;
            GameDefinition gd     = context.Global.GameDef;
            ChanceTree     tree   = context.Global.Tree;

            while (!context.GameState.IsGameOver && !context.GameState.IsDealerActing)
            {
                context.GameState.UpdateByAction(PokerAction.c(context.GameState.CurrentActor), gd);
            }

            if (tree != null)
            {
                tree.SetDepth(nodeId, (byte)context.Depth);
                int position = context.GameState.LastActor;
                if (context.Deal != null && context.Deal.SharedCardsPlayer != -1)
                {
                    position = context.Deal.SharedCardsPlayer;
                }
                if (nodeId == 0)
                {
                    position = gd.MinPlayers;
                }
                tree.Nodes[nodeId].Position = position;
                if (context.Deal == null)
                {
                    tree.Nodes[nodeId].Card = -1;
                }
                else
                {
                    // This double-conversion assures that for decks with duplicates
                    // the same index
                    int stableCardIdx = gd.DeckDescr.GetIndex(gd.DeckDescr.CardNames[context.Deal.CardIdx]);
                    tree.Nodes[nodeId].Card = stableCardIdx;
                }
            }

            if (context.GameState.IsGameOver)
            {
                context.CombCountOfLeaves = context.DealCount;
                if (tree != null)
                {
                    tree.Nodes[nodeId].Probab = (double)context.CombCountOfLeaves / context.Global.TotalCombCountOfLeaves;
                    int     playersCount = gd.MinPlayers;
                    uint[]  ranks        = new uint[playersCount];
                    int[][] hands        = new int[playersCount][];
                    for (int p = 0; p < playersCount; ++p)
                    {
                        hands[p] = gd.DeckDescr.GetIndexes(context.GameState.Players[p].Hand);
                    }
                    gd.GameRules.Showdown(gd, hands, ranks);
                    context.GameState.UpdateByShowdown(ranks, gd);
                    double[] potShares = new double[gd.MinPlayers];
                    for (int p = 0; p < playersCount; ++p)
                    {
                        potShares[p] = (context.GameState.Players[p].Result + context.GameState.Players[p].InPot)
                                       / context.GameState.Pot;
                    }
                    tree.Nodes[nodeId].SetPotShare(context.GameState.GetActivePlayers(), potShares);
                }
                return;
            }

            // Deal next cards.
            List <DealT> deals = DealCards(context);

            foreach (DealT d in deals)
            {
                GameContext childContext = new GameContext(context);
                childContext.Depth++;

                childContext.DealtCards.UnionWith(gd.DeckDescr.CardSets[d.CardIdx]);
                if (d.SharedCardsPlayer == -1)
                {
                    // Non-shared deal - update game state and deal count
                    PokerAction a = PokerAction.d(context.GameState.CurrentActor, d.CardName);
                    childContext.GameState.UpdateByAction(a, gd);
                    childContext.DealCount *= d.Count;
                }
                else if (d.SharedCardsPlayer == gd.MinPlayers - 1)
                {
                    // Shared deal for last player - update game state and deal count once for all.
                    PokerAction a = PokerAction.d(-1, context.Deal.CardName);
                    childContext.GameState.UpdateByAction(a, gd);
                    childContext.DealCount *= d.Count;
                }
                childContext.Deal = d;
                ProcessGameContext(childContext);
                context.CombCountOfLeaves += childContext.CombCountOfLeaves;
                context.ChildCount        += childContext.ChildCount + 1;
            }
            if (tree != null)
            {
                tree.Nodes[nodeId].Probab = (double)context.CombCountOfLeaves / context.Global.TotalCombCountOfLeaves;
            }
        }