public ChanceTree Extract(ChanceTree ct, int position)
        {
            if (position >= ct.PlayersCount)
            {
                throw new ArgumentOutOfRangeException(
                          string.Format("Position {0} is out of range (players count: {1})", position, ct.PlayersCount));
            }
            _position = position;

            WalkUFTreePP <ChanceTree, Context> wt = new WalkUFTreePP <ChanceTree, Context>();

            wt.OnNodeBegin = OnNodeBegin;

            _nodeCount = 0;
            _tempRoot  = new TempNode {
                Card = -1, Probab = 1
            };

            wt.Walk(ct);

            ChanceTree newTree = new ChanceTree(_nodeCount + 1);

            // Reset memory to clear results.
            newTree.SetNodesMemory(0);

            _nodeCount = 0;
            CopyFromTemp(newTree, _tempRoot, 0);

            // Overwrite root position
            newTree.Nodes[0].Position = 1;

            newTree.Version.Description = String.Format("Player {0} chance tree from {1}", position, ct.Version.Description);

            return(newTree);
        }
Example #2
0
        double [,] FlattenStrategy(StrategyTree st, int pos, int cardCount, Dictionary <string, int> actionLabelToId)
        {
            double[,] result = new double[cardCount, actionLabelToId.Count];
            var wt = new WalkUFTreePP <StrategyTree, FlattenStrategyContext>();

            wt.OnNodeBegin = (t, s, d) =>
            {
                Int64 n = s[d].NodeIdx;
                if (d > 0)
                {
                    s[d].ActionLabel = s[d - 1].ActionLabel;
                    s[d].Probab      = s[d - 1].Probab;
                    s[d].Card        = s[d - 1].Card;

                    if (t.Nodes[n].IsDealerAction)
                    {
                        s[d].Card = t.Nodes[n].Card;
                    }
                    else if (d > 2) // Skip blinds
                    {
                        s[d].ActionLabel = s[d].ActionLabel + "/" +
                                           String.Format("{0}p{1}", t.Nodes[n].Position, t.Nodes[n].Amount);
                        if (t.Nodes[n].IsPlayerAction(pos))
                        {
                            s[d].Probab = t.Nodes[n].Probab;
                            double pr = s[d - 1].Probab == 0 ? 0 : s[d].Probab / s[d - 1].Probab;
                            result[s[d].Card, actionLabelToId[s[d].ActionLabel]] = pr;
                        }
                    }
                }
            };
            wt.Walk(st);
            return(result);
        }
        private void VerifyWalk(TestTree tree, UFToUniAdapter adapter)
        {
            List <int> expectedPre  = new List <int>();
            List <int> expectedPost = new List <int>();

            WalkUFTreePP <TestTree, WalkUFTreePPContext> wft =
                new WalkUFTreePP <TestTree, WalkUFTreePPContext>();

            wft.OnNodeBegin = (t, s, d) => expectedPre.Add(tree.Nodes[s[d].NodeIdx].Value);
            wft.OnNodeEnd   = (t, s, d) => expectedPost.Add(tree.Nodes[s[d].NodeIdx].Value);

            wft.Walk(tree);

            List <int> actualPre  = new List <int>();
            List <int> actualPost = new List <int>();

            WalkTreePP <UFToUniAdapter, int, int, AdapterContext> wt = new WalkTreePP <UFToUniAdapter, int, int, AdapterContext>();

            wt.OnNodeBegin = (t, n, s, d) =>
            {
                actualPre.Add(tree.Nodes[n].Value);
                return(true);
            };
            wt.OnNodeEnd = (t, n, s, d) => actualPost.Add(tree.Nodes[n].Value);

            wt.Walk(adapter, 0);

            Assert.AreEqual(expectedPre, actualPre);
            Assert.AreEqual(expectedPost, actualPost);

            int bi, cnt;

            adapter.GetChildrenBeginIdxAndCount(0, out bi, out cnt);
            Assert.AreEqual(4, cnt);
        }
Example #4
0
        private void Calculate()
        {
            WalkUFTreePP <ActionTree, CalculateActionContext> wt = new WalkUFTreePP <ActionTree, CalculateActionContext>();

            wt.OnNodeBegin = Calculate_Action_OnNodeBegin;
            wt.Walk(ActionTree);
        }
Example #5
0
        string[] CreateActionLabels(ActionTree at, int pos)
        {
            var           wt     = new WalkUFTreePP <ActionTree, CreateActionLabelsContext>();
            List <string> labels = new List <string>();

            wt.OnNodeBegin = (t, s, d) =>
            {
                Int64 n = s[d].NodeIdx;
                if (d > 0)
                {
                    s[d].Label = s[d - 1].Label;
                    // Skip blinds
                    if (d > 2)
                    {
                        s[d].Label = s[d].Label + "/" + String.Format("{0}p{1}", t.Nodes[n].Position, t.Nodes[n].Amount);
                        if (t.Nodes[n].Position == pos)
                        {
                            labels.Add(s[d].Label);
                        }
                    }
                }
            };
            wt.Walk(at);
            return(labels.ToArray());
        }
Example #6
0
        void Calculate_Action_OnNodeBegin(ActionTree tree, CalculateActionContext[] stack, int depth)
        {
            CalculateActionContext context = stack[depth];
            Int64 n = context.NodeIdx;

            if (depth == 0)
            {
                context.State = new StrategicState(_playersCount);
            }
            else
            {
                context.State = stack[depth - 1].State.GetNextState(tree.Nodes[n]);
            }

            if (_actionTreeIndex.GetChildrenCount(n) != 0)
            {
                return;
            }
            // This is a leaf
            int round = ActionTree.Nodes[n].Round;

            _chanceDepth       = (byte)(_playersCount * (round + 1));
            _strategicState    = context.State;
            _actionTreeNodeIdx = n;
            WalkUFTreePP <ChanceTree, CalculateChanceContext> wt = new WalkUFTreePP <ChanceTree, CalculateChanceContext>();

            wt.OnNodeBegin = Calculate_Chance_OnNodeBegin;
            wt.Walk(ChanceTree);
        }
Example #7
0
        public ChanceTree Create(GameDefinition gd, IChanceAbstraction [] abstractions)
        {
            _abstractions     = abstractions;
            _gameDef          = gd;
            _hands            = new int[gd.MinPlayers][].Fill(i => new int[gd.RoundsCount]);
            _activePlayersOne = ActivePlayers.Get(gd.MinPlayers, 1, 1);
            _activePlayersAll = ActivePlayers.Get(gd.MinPlayers, 1, gd.MinPlayers);
            _maxDepth         = gd.RoundsCount * gd.MinPlayers;

            ChanceTree gdChanceTree = CreateChanceTreeByGameDef.Create(gd);

            WalkUFTreePP <ChanceTree, CreateIntermediateTreeContext> wt1 = new WalkUFTreePP <ChanceTree, CreateIntermediateTreeContext>();

            wt1.OnNodeBegin = CreateIntermediateTree_OnNodeBegin;
            wt1.OnNodeEnd   = CreateIntermediateTree_OnNodeEnd;
            _nodesCount     = 0;
            wt1.Walk(gdChanceTree);

            _abstChanceTree = new ChanceTree(_nodesCount + 1);

            WalkTreePP <IntermediateNode, IntermediateNode, int, CopyTreeContext> wt2 = new WalkTreePP <IntermediateNode, IntermediateNode, int, CopyTreeContext>();

            wt2.OnNodeBegin = CopyTree_OnNodeBegin;
            _nodesCount     = 0;
            wt2.Walk(_intRoot, _intRoot);

            _abstChanceTree.Version.Description = String.Format("Chance tree (gamedef: {0}", gd.Name);
            for (int p = 0; p < gd.MinPlayers; ++p)
            {
                _abstChanceTree.Version.Description += String.Format(", {0}", abstractions[p].Name);
            }
            _abstChanceTree.Version.Description += ")";

            return(_abstChanceTree);
        }
        public unsafe void Benchmark_Walk()
        {
            int      depthLimit         = 25;
            int      expectedNodesCount = (1 << (depthLimit + 1)) - 1;
            TestTree tree = new TestTree(expectedNodesCount);
            int      idx  = 0;

            CreateTestTree(tree, idx, ref idx, 0, depthLimit, 2);

            WalkUFTreePP <TestTree, Context> walker =
                new WalkUFTreePP <TestTree, Context>();

            int nodeCount = 0;

            walker.OnNodeBegin = (t, s, d) => { nodeCount++; };

            DateTime startTime = DateTime.Now;

            walker.Walk(tree);

            double time = (DateTime.Now - startTime).TotalSeconds;

            Assert.AreEqual(expectedNodesCount, nodeCount);

            Console.WriteLine("Node count {0:###,###,###}, {1} s, {2:###,###,###} n/s",
                              nodeCount, time, nodeCount / time);
        }
Example #9
0
        private void CopySolutionToStrategy()
        {
            _varH = 0;
            WalkUFTreePP <StrategyTree, CopySolutionToStrategyContext> wt = new WalkUFTreePP <StrategyTree, CopySolutionToStrategyContext>();

            wt.OnNodeBegin = CopySolutionToStrategy_OnNodeBegin;
            wt.Walk(Strategy, PLAYERS_COUNT);
        }
Example #10
0
        private void PrepareOpp()
        {
            WalkUFTreePP <StrategyTree, PrepareOppContext> wt = new WalkUFTreePP <StrategyTree, PrepareOppContext>();

            wt.OnNodeBegin = PrepareOpp_OnNodeBegin;
            wt.OnNodeEnd   = PrepareOpp_OnNodeEnd;
            wt.Walk(_oppStrategy, PLAYERS_COUNT);
        }
Example #11
0
        void BestResponseFinalize()
        {
            int[] heroAbstrCards = HandToAbstractCards(_hands[_heroPos]);
            var   wt             = new WalkUFTreePP <StrategyTree, BrFinalizeContext>();

            Node[] heroPtExt = _ptExt[_heroPos];

            wt.OnNodeBegin = (t, s, d) =>
            {
                Int64 n = s[d].NodeIdx;
                s[d].ChildBrFound = false;
                if (d > 0)
                {
                    s[d].DealPath       = new List <int>(s[d - 1].DealPath);
                    s[d].ParentBrProbab = s[d - 1].ParentBrProbab;
                }
                if (_pt.Nodes[n].IsDealerAction)
                {
                    s[d].DealPath.Add(_pt.Nodes[n].Card);
                }

                for (int r = 0; r < s[d].DealPath.Count; ++r)
                {
                    if (s[d].DealPath[r] != heroAbstrCards[r])
                    {
                        // This deal paths is not of interest.
                        return;
                    }
                }
                if (n == 0)
                {
                    return;
                }
                long pn = s[d - 1].NodeIdx;
                if (_pt.Nodes[n].IsPlayerAction(_heroPos) && n > _playersCount)
                {
                    int br = 0;
                    if (s[d].ParentBrProbab > 0)
                    {
                        if (heroPtExt[pn].GameValue == heroPtExt[n].GameValue && !s[d - 1].ChildBrFound)
                        {
                            // This was the BR
                            br = 1;
                            s[d - 1].ChildBrFound = true;
                        }
                    }
                    double p = _pt.Nodes[n].Probab * (IterationCounts[_heroPos] - 1);
                    p += br;
                    _pt.Nodes[n].Probab = p / IterationCounts[_heroPos];
                    s[d].ParentBrProbab = br;
                }
            };
            wt.OnNodeEnd = (t, s, d) =>
            {
            };
            wt.Walk(_pt);
        }
Example #12
0
        public void Verify(ChanceTree ct)
        {
            _playersCount     = ct.Nodes[0].Position;
            _areAllPosInvalid = true;
            WalkUFTreePP <ChanceTree, Context> wt = new WalkUFTreePP <ChanceTree, Context>();

            wt.OnNodeBegin = OnNodeBegin;
            wt.OnNodeEnd   = OnNodeEnd;
            wt.Walk(ct);
        }
Example #13
0
        /// <summary>
        /// Set initial strategy.
        /// </summary>
        private void SetInitialStrategy(int pos)
        {
            IterationCounts[pos]++;
            WalkUFTreePP <StrategyTree, SetInitialStrategyContext> wt = new WalkUFTreePP <StrategyTree, SetInitialStrategyContext>();

            wt.OnNodeBegin = (t, s, d) =>
            {
                Int64 n = s[d].NodeIdx;
                s[d].HeroChildren.Clear();
                if (d > 0)
                {
                    s[d].Probab = s[d - 1].Probab;
                }
                if (d > _playersCount)
                {
                    if (t.Nodes[n].IsPlayerAction(pos))
                    {
                        s[d - 1].HeroChildren.Add(n);
#if false
                        // Pure strategy
                        if (s[d].Probab > 0)
                        {
                            t.Nodes[n].Probab = s[d - 1].ChildrenCount == 1 ? 1 : 0;
                        }
                        s[d].Probab = t.Nodes[n].Probab;
#endif
                    }
                }
            };
            wt.OnNodeEnd = (t, s, d) =>
            {
                Int64 n = s[d].NodeIdx;
                if (s[d].HeroChildren.Count > 0)
                {
#if true
                    // Mixed strategy
                    double condProbab = 1.0 / s[d].HeroChildren.Count;
                    foreach (long ch in s[d].HeroChildren)
                    {
                        t.Nodes[ch].Probab = condProbab;
                    }
#endif
                }
            };
            wt.Walk(_pt);
            ConvertCondToAbs.Convert(_pt, pos);
            string error;
            if (!VerifyAbsStrategy.Verify(_pt, pos, out error))
            {
                throw new ApplicationException(String.Format("Initial strategy inconsistent: {0}", error));
            }
        }
Example #14
0
        private void PrepareHero()
        {
            _maxCard          = new int[PLAYERS_COUNT][];
            _chanceIndexSizes = new int[PLAYERS_COUNT][];
            _heroVarsInLeaves = new int[ActionTree.NodesCount][];

            _roundsCount = ChanceTree.CalculateRoundsCount();
            for (int p = 0; p < PLAYERS_COUNT; ++p)
            {
                _maxCard[p]          = new int[_roundsCount].Fill(int.MinValue);
                _chanceIndexSizes[p] = new int[_roundsCount].Fill(int.MinValue);
            }

            for (Int64 n = 1; n < ChanceTree.NodesCount; ++n)
            {
                int round = (ChanceTree.GetDepth(n) - 1) / PLAYERS_COUNT;
                if (_maxCard[ChanceTree.Nodes[n].Position][round] < ChanceTree.Nodes[n].Card)
                {
                    _maxCard[ChanceTree.Nodes[n].Position][round] = ChanceTree.Nodes[n].Card;
                }
            }

            for (int p = 0; p < PLAYERS_COUNT; ++p)
            {
                _chanceIndexSizes[p][0] = _maxCard[p][0] + 1;
                for (int r = 1; r < _roundsCount; ++r)
                {
                    _chanceIndexSizes[p][r] = _chanceIndexSizes[p][r - 1] * (_maxCard[p][r] + 1);
                }
            }

            _actionTreeIndex = new UFTreeChildrenIndex(ActionTree);

            for (Int64 n = 1; n < ActionTree.NodesCount; ++n)
            {
                if (_actionTreeIndex.GetChildrenCount(n) == 0)
                {
                    // This is a leaf
                    int round = ActionTree.Nodes[n].Round;
                    _heroVarsInLeaves[n] = new int[_chanceIndexSizes[HeroPosition][round]].Fill(-1);
                }
            }

            // Create hero variables
            WalkUFTreePP <StrategyTree, PrepareHeroVarsContext> wt = new WalkUFTreePP <StrategyTree, PrepareHeroVarsContext>();

            wt.OnNodeBegin = PrepareHero_OnNodeBegin;
            wt.Walk(Strategy, PLAYERS_COUNT);
        }
        private StrategyTree CreateValidStrategy(GameDefinition gd)
        {
            StrategyTree st = TreeHelper.CreateStrategyTree(gd, _heroPos);

            _childrenCount = new int[st.NodesCount];
            WalkUFTreePP <StrategyTree, Context> wt = new WalkUFTreePP <StrategyTree, Context>();

            wt.OnNodeBegin = OnNodeBegin;
            _run           = 0;
            wt.Walk(st);

            _run = 1;
            wt.Walk(st);
            return(st);
        }
Example #16
0
        public void Analyze()
        {
            try
            {
                _playersCount   = StrategyTree.PlayersCount;
                _stats          = new List <Stats>(10);
                LeavesCount     = 0;
                ZaspLeavesCount = 0;
                MovesCount      = 0;
                ZaspMovesCount  = 0;

                var walkTree = new WalkUFTreePP <StrategyTree, AnalyzeContext>();

                walkTree.OnNodeBegin = OnNodeBegin;
                walkTree.OnNodeEnd   = OnNodeEnd;
                walkTree.Walk(StrategyTree);

                if (IsVerbose)
                {
                    Output.WriteLine("Analysis of strategy tree: '{0}'", StrategyTree.Version.Description);
                    Output.WriteLine("Players: {0}, nodes: {1:#,#}, leaves: {2:#,#}", StrategyTree.PlayersCount, StrategyTree.NodesCount, LeavesCount);
                    Output.Write("Blinds:");
                    for (int p = 0; p < _playersCount; ++p)
                    {
                        Output.Write(" {0}", StrategyTree.Nodes[p + 1].Amount);
                    }
                    Output.WriteLine();

                    Output.WriteLine("Hero position: {0}, moves: {1:#,#}", HeroPosition, MovesCount);
                    Output.WriteLine("Zero str probab moves of hero: total {0} ({1:0.00%}), leaves: {2} ({3:0.00%})",
                                     ZaspMovesCount, (double)ZaspMovesCount / MovesCount,
                                     ZaspLeavesCount, (double)ZaspLeavesCount / LeavesCount);

                    Output.WriteLine("Action statistics in nodes with non-zero strategic probability:");
                    for (int r = 0; r < _stats.Count; ++r)
                    {
                        Console.WriteLine("Round {0}: nodes {1,10:#,#}, f: {2:0.00000}, c: {3:0.00000}, r: {4:0.00000}", r,
                                          _stats[r].NZaspMovesCount,
                                          _stats[r].SumNZaspFold / _stats[r].NZaspMovesCount,
                                          _stats[r].SumNZaspCall / _stats[r].NZaspMovesCount,
                                          _stats[r].SumNZaspRaise / _stats[r].NZaspMovesCount);
                    }
                }
            }
            finally
            {
            }
        }
Example #17
0
        private void Calculate()
        {
            WalkUFTreePP <StrategyTree, CalculateValuesContext> wt = new WalkUFTreePP <StrategyTree, CalculateValuesContext>();

            wt.OnNodeBegin = CalculateValues_OnNodeBegin;
            wt.OnNodeEnd   = CalculateValues_OnNodeEnd;
            wt.Walk(Strategies[HeroPosition]);

            Value = Strategies[HeroPosition].Nodes[0].Probab;

            WalkUFTreePP <StrategyTree, CalculateBrContext> wt1 = new WalkUFTreePP <StrategyTree, CalculateBrContext>();

            wt1.OnNodeBegin = CalculateBr_OnNodeBegin;
            wt1.OnNodeEnd   = CalculateBr_OnNodeEnd;
            wt1.Walk(Strategies[HeroPosition]);
        }
Example #18
0
        private void DoVerifyChanceTree(ChanceTree ct)
        {
            Assert.AreEqual(ct.PlayersCount, _gd.MinPlayers);

            try
            {
                VerifyChanceTree.VerifyS(ct);
            }
            catch (Exception e)
            {
                Assert.Fail(e.ToString());
            }
            WalkUFTreePP <ChanceTree, Context> wt = new WalkUFTreePP <ChanceTree, Context>();

            wt.OnNodeBegin = OnNodeBegin;
            wt.OnNodeEnd   = OnNodeEnd;
            wt.Walk(ct);
        }
Example #19
0
            public ChanceTree ConvertToChanceTree()
            {
                int depth = PlayersCount * RoundsCount;

                int nodesCount = CountNodes <int> .Count(Root, Root as object);

                ChanceTree ct = new ChanceTree(nodesCount);

                ct.SetNodesMemory(0); // To clear results.

                SyncUniAndUF <int> .Sync(Root, Root as object, ct, SyncNodes);

                WalkUFTreePP <ChanceTree, WalkUFTreePPContext> wt = new WalkUFTreePP <ChanceTree, WalkUFTreePPContext>();

                wt.OnNodeEnd = FinalizeChanceTree_OnNodeEnd;
                wt.Walk(ct);
                ct.PlayersCount        = PlayersCount;
                ct.Version.Description = String.Format("Chance tree (MC:{0:0,0}, {1})", SamplesCount, SourceInfo);
                return(ct);
            }
Example #20
0
        void Prepare()
        {
            _oppPosition = 1 - HeroPosition;

            // Create a strategy for each player. We need both because players can use different abstractions.
            PrepareHeroStrategy();
            ChanceTree pct;

            pct          = ExtractPlayerChanceTree.ExtractS(ChanceTree, _oppPosition);
            _oppStrategy = CreateStrategyTreeByChanceAndActionTrees.CreateS(pct, ActionTree);

            _variables     = new Variables();
            _constraintsLE = new List <Constraint>();
            _constraintsEQ = new List <Constraint>();

            PrepareHero();

            // Create index for the chance tree.
            _chanceTreeNodes = new int[PLAYERS_COUNT][][];
            for (int r = 0; r < _roundsCount; ++r)
            {
                int oppSize = _chanceIndexSizes[_oppPosition][r];
                _chanceTreeNodes[r] = new int[oppSize][];
                int heroSize = _chanceIndexSizes[HeroPosition][r];
                for (int i = 0; i < oppSize; ++i)
                {
                    _chanceTreeNodes[r][i] = new int[heroSize];
                }
            }

            WalkUFTreePP <ChanceTree, PrepareChanceIndexContext> wt1 = new WalkUFTreePP <ChanceTree, PrepareChanceIndexContext>();

            wt1.OnNodeBegin = PrepareChanceIndex_OnNodeBegin;
            wt1.Walk(ChanceTree);

            // This will be the index of v0 variable, because it will be added next.
            _v0 = _variables.Count;

            PrepareOpp();
        }
Example #21
0
        /// <summary>
        /// Converts a chance tree to a dictionary of leaves. This allows to compare trees with different structure easily.
        /// Use a string key of two charachters, this is proven to be very fast. // Todo: use new hash.
        /// </summary>
        static Dictionary <string, IntPtr> ConvertToDict(ChanceTree ct, int maxDepth)
        {
            WalkUFTreePP <ChanceTree, ConvertToDictContext> wt = new WalkUFTreePP <ChanceTree, ConvertToDictContext>();
            Dictionary <string, IntPtr> dict = new Dictionary <string, IntPtr>();
            StringBuilder sb = new StringBuilder();

            wt.OnNodeBegin = (tree, stack, depth) =>
            {
                Int64 n = stack[depth].NodeIdx;
                if (depth > 0)
                {
                    int card = tree.Nodes[n].Card;
                    stack[depth].Key = stack[depth - 1].Key + _cardToString[card];
                }
                if (depth == maxDepth)
                {
                    dict.Add(stack[depth].Key, new IntPtr(tree.Nodes + n));
                }
            };
            wt.Walk(ct);
            return(dict);
        }
Example #22
0
        void OnOppDeal(int [] cards, int param)
        {
            int oppPos = 1 - _heroPos;

            uint[] ranks = new uint[_playersCount];
            GameDef.GameRules.Showdown(GameDef, _hands, ranks);
            double oppShowdown = 0;

            if (ranks[_heroPos] > ranks[oppPos])
            {
                oppShowdown = -1;
            }
            else if (ranks[_heroPos] < ranks[oppPos])
            {
                oppShowdown = 1;
            }
            int[] oppAbstrCards = HandToAbstractCards(_hands[oppPos]);
            var   wt            = new WalkUFTreePP <StrategyTree, CalcOppValuesContext>();

            wt.OnNodeBegin = (t, s, d) =>
            {
                Int64 n = s[d].NodeIdx;
                if (d > 0)
                {
                    s[d].DealPath  = new List <int>(s[d - 1].DealPath);
                    s[d].StrProbab = s[d - 1].StrProbab;
                }
                if (_pt.Nodes[n].IsDealerAction)
                {
                    s[d].DealPath.Add(_pt.Nodes[n].Card);
                }
                else if (_pt.Nodes[n].IsPlayerAction(oppPos) && n > _playersCount)
                {
                    s[d].StrProbab = _pt.Nodes[n].Probab;
                }
            };
            wt.OnNodeEnd = (t, s, d) =>
            {
                Int64 n = s[d].NodeIdx;
                if (s[d].ChildrenCount == 0)
                {
                    // A leaf.
                    for (int r = 0; r < s[d].DealPath.Count; ++r)
                    {
                        if (s[d].DealPath[r] != oppAbstrCards[r])
                        {
                            // This deal paths is not of interest.
                            return;
                        }
                    }
                    uint   atIdx         = _ptExt[oppPos][n].AtIdx;
                    UInt16 activePlayers = _at.Nodes[atIdx].ActivePlayers;
                    UInt16 oppMask       = (UInt16)(1 << oppPos);
                    double gvPS          = _ptExt[oppPos][n].PotFactor * s[d].StrProbab;
                    double gv;
                    if (activePlayers == (activePlayers & (~oppMask)))
                    {
                        // The opp folded and loses its inPot
                        gv = -gvPS;
                    }
                    else if (activePlayers == oppMask)
                    {
                        // The hero. folds: opp wins
                        gv = gvPS;
                    }
                    else
                    {
                        // Showdown (inpots are equal)
                        gv = gvPS * oppShowdown;
                    }
                    _oppGv[atIdx] += gv;
                }
            };
            wt.Walk(_pt);
        }
Example #23
0
        private void CreatePlayerTrees()
        {
            //_pt = StrategyTree.Read<StrategyTree>(_curSnapshotInfo.StrategyFile[heroPos]);
            for (int heroPos = 0; heroPos < _playersCount; ++heroPos)
            {
                if (IsVerbose)
                {
                    Console.WriteLine("Creating player tree for pos {0}", heroPos);
                }

                _ptExt[heroPos] = new Node[_pt.NodesCount];
                var wt = new WalkUFTreePP <StrategyTree, CreatePlayerTreeContext>();
                wt.OnNodeBegin = (t, s, d) =>
                {
                    Int64 n = s[d].NodeIdx;
                    if (d > 0)
                    {
                        s[d].AtIdx = s[d - 1].AtIdx;
                        s[d - 1].InPot.CopyTo(s[d].InPot, 0);
                    }
                    if (!_pt.Nodes[n].IsDealerAction && n > 0)
                    {
                        s[d].InPot[_pt.Nodes[n].Position] += _pt.Nodes[n].Amount;

                        s[d].AtIdx = FindActionTreeNodeIdx(t, n, s[d].AtIdx,
                                                           s[d - 1].ChildrenCount - 1);
                    }
                    _ptExt[heroPos][n].AtIdx = s[d].AtIdx;

                    /*if (d == 0)
                     * {
                     * }
                     * else
                     * {
                     * }
                     * _playerTrees[heroPos].SetDepth(n, (byte) d);
                     * if (d > _init.PlayerTreeMaxDepth[heroPos])
                     *  _init.PlayerTreeMaxDepth[heroPos] = d;
                     * if (st.Nodes[n].IsDealerAction)
                     * {
                     *  _playerTrees[heroPos].Nodes[n].Position = (byte) _playersCount;
                     *  _playerTrees[heroPos].Nodes[n].ChanceId = (UInt32) st.Nodes[n].Card;
                     * }
                     * else if (n > 0)
                     * {
                     *  s[d].AtIdx = FindActionTreeNodeIdx(t, n, s[d].AtIdx,
                     *                                     s[d - 1].ChildrenCount - 1);
                     *
                     *  _playerTrees[heroPos].Nodes[n].Position = (byte) st.Nodes[n].Position;
                     *  if (st.Nodes[n].Position == heroPos)
                     *  {
                     *
                     *      _playerTrees[heroPos].Nodes[s[d - 1].NodeIdx].IsHeroActing = true;
                     *      _playerTrees[heroPos].Nodes[n].SetStrVar(this, st.Nodes[n].Probab);
                     *  }
                     * }
                     * _playerTrees[heroPos].Nodes[n].AtIdx = Node.INVALID_AT_IDX;
                     * if (d == _playersCount + 1)
                     * {
                     *  // Set up the top tree. Do it at the end when the node is initialized
                     *  TopTreeNode ttn = new TopTreeNode(this, heroPos, n);
                     *  _topTrees[heroPos].Nodes.Add(ttn);
                     * }*/
                };
                wt.OnNodeEnd = (t, s, d) =>
                {
                    Int64 n = s[d].NodeIdx;
                    if (s[d].ChildrenCount == 0)
                    {
                        // A leaf
                        Debug.Assert(_playersCount == 2);
                        _ptExt[heroPos][n].PotFactor = Math.Min(s[d].InPot[0], s[d].InPot[1]);
                    }
                };

                wt.Walk(_pt);
            }
        }
Example #24
0
        void BestResponseValuesUp()
        {
            int[] heroAbstrCards = HandToAbstractCards(_hands[_heroPos]);
            var   wt             = new WalkUFTreePP <StrategyTree, BrValuesUpContext>();

            Node[] heroPtExt = _ptExt[_heroPos];

            wt.OnNodeBegin = (t, s, d) =>
            {
                Int64 n = s[d].NodeIdx;
                s[d].OldGv = heroPtExt[n].GameValue;
                if (d > 0)
                {
                    s[d].DealPath = new List <int>(s[d - 1].DealPath);
                }
                if (_pt.Nodes[n].IsDealerAction)
                {
                    s[d].DealPath.Add(_pt.Nodes[n].Card);
                }
            };
            wt.OnNodeEnd = (t, s, d) =>
            {
                Int64 n = s[d].NodeIdx;
                for (int r = 0; r < s[d].DealPath.Count; ++r)
                {
                    if (s[d].DealPath[r] != heroAbstrCards[r])
                    {
                        // This deal paths is not of interest.
                        return;
                    }
                }
                if (s[d].ChildrenCount == 0)
                {
                    // A leaf.
                    // Update game value. Overwrite the old one, because we have calculated
                    // a fully correct value for the current opponent strategy and this hero hand.
                    heroPtExt[n].GameValue = -_oppGv[heroPtExt[n].AtIdx];
                }
                // Now we know the game value of this node.
                if (n == 0)
                {
                    // Update total game values, counting the fact that actually the update is started from iteration 2.
                    // LastBrValues[_heroPos] = heroPtExt[n].GameValue / (IterationCounts[_heroPos] - 1);
                    LastBrValues[_heroPos] = heroPtExt[n].GameValue;
                    return;
                }
                long pn = s[d - 1].NodeIdx;
                if (_pt.Nodes[n].IsPlayerAction(_heroPos) && n > _playersCount)
                {
                    // maximize value
                    if (s[d - 1].ChildrenCount == 1)
                    {
                        heroPtExt[pn].GameValue = heroPtExt[n].GameValue;
                    }
                    else
                    {
                        heroPtExt[pn].GameValue = Math.Max(heroPtExt[pn].GameValue, heroPtExt[n].GameValue);
                    }
                }
                else
                {
                    // Sum values by updating.
                    heroPtExt[pn].GameValue -= s[d].OldGv;
                    heroPtExt[pn].GameValue += heroPtExt[n].GameValue;
                }
            };
            wt.Walk(_pt);
        }
        void DoWalkTest(int startNode, int expectedNodesCount, int depth, int childCount, bool checkPostValue)
        {
            int power      = 1;
            int nodesCount = 0;

            for (int d = 0; d <= depth; ++d)
            {
                nodesCount += power;
                power      *= childCount;
            }
            TestTree tree = new TestTree(nodesCount);
            int      idx  = 0;

            _postValue = 0;
            CreateTestTree(tree, idx, ref idx, 0, 3, 4);

            WalkUFTreePP <TestTree, WalkUFTreePPContext> wt = new WalkUFTreePP <TestTree, WalkUFTreePPContext>();

            int treeBeginCount = 0;
            int treeEndCount   = 0;
            int nodeBeginCount = 0;
            int nodeEndCount   = 0;

            wt.OnNodeBegin = (t, s, d) =>
            {
                Assert.AreEqual(1, treeBeginCount);
                Assert.AreEqual(0, treeEndCount);
                Assert.AreEqual(0, t.Nodes[s[d].NodeIdx].BeginCallCount);
                Assert.AreEqual(0, t.Nodes[s[d].NodeIdx].EndCallCount);
                Assert.AreEqual(nodeBeginCount + startNode, t.Nodes[s[d].NodeIdx].PreValue);
                Assert.AreEqual(0, s[d].ChildrenCount);
                if (d > 0)
                {
                    Assert.IsTrue(s[d - 1].ChildrenCount >= 1);
                    Assert.IsTrue(s[d - 1].ChildrenCount <= 4);
                }
                t.Nodes[s[d].NodeIdx].BeginCallCount++;
                nodeBeginCount++;
            };
            wt.OnNodeEnd = (t, s, d) =>
            {
                Assert.AreEqual(1, treeBeginCount);
                Assert.AreEqual(0, treeEndCount);
                Assert.AreEqual(1, t.Nodes[s[d].NodeIdx].BeginCallCount);
                Assert.AreEqual(0, t.Nodes[s[d].NodeIdx].EndCallCount);
                Assert.AreEqual(t.GetDepth(s[d].NodeIdx), d);
                if (checkPostValue)
                {
                    Assert.AreEqual(nodeEndCount, t.Nodes[s[d].NodeIdx].PostValue);
                }
                int expChildrenCount = d == 3 ? 0 : 4;
                Assert.AreEqual(expChildrenCount, s[d].ChildrenCount);

                nodeEndCount++;
                t.Nodes[s[d].NodeIdx].EndCallCount++;
            };
            wt.OnTreeBegin = (t) =>
            {
                Assert.AreEqual(0, treeBeginCount);
                Assert.AreEqual(0, treeEndCount);
                treeBeginCount++;
            };
            wt.OnTreeEnd = (t) =>
            {
                Assert.AreEqual(1, treeBeginCount);
                Assert.AreEqual(0, treeEndCount);
                treeEndCount++;
            };
            wt.Walk(tree, startNode);
            Assert.AreEqual(1, treeBeginCount);
            Assert.AreEqual(1, treeEndCount);
            Assert.AreEqual(expectedNodesCount, nodeBeginCount);
            Assert.AreEqual(expectedNodesCount, nodeEndCount);
        }
Example #26
0
        private void Prepare()
        {
            _playersCount   = Strategies.Length;
            _maxCard        = new int[_playersCount][];
            _spArrayLengths = new int[_playersCount][];
            _spArrays       = new double[_playersCount][][].Fill(i => new double[ActionTree.NodesCount][]);
            if (PrepareVis)
            {
                _visLeaveValues = new double[_playersCount][][].Fill(i => new double[ActionTree.NodesCount][]);
            }
            _gameValues = new double[_playersCount];

            _roundsCount = ChanceTree.CalculateRoundsCount();
            for (int p = 0; p < _playersCount; ++p)
            {
                _maxCard[p]        = new int[_roundsCount].Fill(int.MinValue);
                _spArrayLengths[p] = new int[_roundsCount].Fill(int.MinValue);
            }

            for (Int64 n = 1; n < ChanceTree.NodesCount; ++n)
            {
                int round = (ChanceTree.GetDepth(n) - 1) / _playersCount;
                if (_maxCard[ChanceTree.Nodes[n].Position][round] < ChanceTree.Nodes[n].Card)
                {
                    _maxCard[ChanceTree.Nodes[n].Position][round] = ChanceTree.Nodes[n].Card;
                }
            }

            for (int p = 0; p < _playersCount; ++p)
            {
                _spArrayLengths[p][0] = _maxCard[p][0] + 1;
                for (int r = 1; r < _roundsCount; ++r)
                {
                    _spArrayLengths[p][r] = _spArrayLengths[p][r - 1] * (_maxCard[p][r] + 1);
                }
            }

            _actionTreeIndex = new UFTreeChildrenIndex(ActionTree);

            for (Int64 n = 1; n < ActionTree.NodesCount; ++n)
            {
                if (_actionTreeIndex.GetChildrenCount(n) == 0)
                {
                    // This is a leaf
                    int round = ActionTree.Nodes[n].Round;
                    for (int p = 0; p < _playersCount; ++p)
                    {
                        _spArrays[p][n] = new double[_spArrayLengths[p][round]];
                        if (PrepareVis)
                        {
                            _visLeaveValues[p][n] = new double[_spArrayLengths[p][round]];
                        }
                    }
                }
            }

            for (_curPlayer = 0; _curPlayer < _playersCount; ++_curPlayer)
            {
                WalkUFTreePP <StrategyTree, PrepareContext> wt = new WalkUFTreePP <StrategyTree, PrepareContext>();
                wt.OnNodeBegin = Prepare_OnNodeBegin;
                wt.Walk(Strategies[_curPlayer]);
            }
        }
        public void Analyze(ChanceTree ct)
        {
            if (!string.IsNullOrEmpty(ZeroNodesLogName))
            {
                _zeroNodesLog = new StreamWriter(ZeroNodesLogName);
            }

            try
            {
                _playersCount = ct.PlayersCount;
                int roundsCount = ct.CalculateRoundsCount();
                _maxDepth  = roundsCount * _playersCount;
                _seenCards = new bool[roundsCount][][];
                for (int r = 0; r < roundsCount; ++r)
                {
                    _seenCards[r] = new bool[_playersCount][].Fill(i => new bool[0]);
                }
                LeavesCount           = 0;
                SumPotShares          = new double[_playersCount];
                ZeroChanceLeavesCount = ZeroPotSharesCount = 0;

                WalkUFTreePP <ChanceTree, AnalyzeContext> walkTree = new WalkUFTreePP <ChanceTree, AnalyzeContext>();

                walkTree.OnNodeBegin = OnNodeBegin;
                walkTree.Walk(ct);

                if (IsVerbose)
                {
                    Output.WriteLine("Analysis of chance tree: '{0}'", ct.Version.Description);
                    Output.WriteLine("Players: {0}, nodes: {1:#,#}, leaves: {2:#,#}", ct.PlayersCount, ct.NodesCount, LeavesCount);
                    Output.WriteLine("Leaves statistics:");
                    double totalPotShares = 0;
                    for (int p = 0; p < _playersCount; ++p)
                    {
                        totalPotShares += SumPotShares[p];
                        Output.WriteLine("Sum pot shares pos {0}: {1:0.000}", p, SumPotShares[p]);
                    }
                    Output.WriteLine("Sum pot shares total: {0:0.000}", totalPotShares);
                    Output.WriteLine("Zero leaves: chance: {0} ({1:0.00%}), pot shares: {2} ({3:0.00%})",
                                     ZeroChanceLeavesCount, (double)ZeroChanceLeavesCount / LeavesCount,
                                     ZeroPotSharesCount, (double)ZeroPotSharesCount / LeavesCount);

                    Output.WriteLine("Seen cards:");
                    for (int r = 0; r < roundsCount; ++r)
                    {
                        Output.WriteLine("Round {0}:", r);
                        for (int p = 0; p < _playersCount; ++p)
                        {
                            Output.Write("Pos {0}:", p);
                            int seenCount = 0;
                            for (int c = 0; c < _seenCards[r][p].Length; ++c)
                            {
                                if (_seenCards[r][p][c])
                                {
                                    seenCount++;
                                    Output.Write(" {0,2}", c);
                                }
                            }
                            Output.WriteLine(" ({0})", seenCount);
                        }
                    }
                }
            }
            finally
            {
                if (_zeroNodesLog != null)
                {
                    _zeroNodesLog.Close();
                    _zeroNodesLog = null;
                }
            }
        }
Example #28
0
        private void Prepare()
        {
            CreateHeroStrategy();

            _playersCount     = Strategies.Length;
            _maxCard          = new int[_playersCount][];
            _chanceIndexSizes = new int[_playersCount][];
            _strategicProbabs = new double[_playersCount][][].Fill(i => new double[ActionTree.NodesCount][]);
            if (PrepareVis)
            {
                _visGameValues = new double[Strategies[HeroPosition].NodesCount];
            }
            else
            {
                _visGameValues = null;
            }

            _roundsCount = ChanceTree.CalculateRoundsCount();
            for (int p = 0; p < _playersCount; ++p)
            {
                _maxCard[p]          = new int[_roundsCount].Fill(int.MinValue);
                _chanceIndexSizes[p] = new int[_roundsCount].Fill(int.MinValue);
            }

            for (Int64 n = 1; n < ChanceTree.NodesCount; ++n)
            {
                int round = (ChanceTree.GetDepth(n) - 1) / _playersCount;
                if (_maxCard[ChanceTree.Nodes[n].Position][round] < ChanceTree.Nodes[n].Card)
                {
                    _maxCard[ChanceTree.Nodes[n].Position][round] = ChanceTree.Nodes[n].Card;
                }
            }

            for (int p = 0; p < _playersCount; ++p)
            {
                _chanceIndexSizes[p][0] = _maxCard[p][0] + 1;
                for (int r = 1; r < _roundsCount; ++r)
                {
                    _chanceIndexSizes[p][r] = _chanceIndexSizes[p][r - 1] * (_maxCard[p][r] + 1);
                }
            }

            _actionTreeIndex = new UFTreeChildrenIndex(ActionTree);

            for (Int64 n = 1; n < ActionTree.NodesCount; ++n)
            {
                if (_actionTreeIndex.GetChildrenCount(n) == 0)
                {
                    // This is a leaf
                    int round = ActionTree.Nodes[n].Round;
                    for (int p = 0; p < _playersCount; ++p)
                    {
                        if (p != HeroPosition)
                        {
                            _strategicProbabs[p][n] = new double[_chanceIndexSizes[p][round]];
                        }
                    }
                }
            }

            // Fill strategic probability for each player except the hero.
            for (_curPlayer = 0; _curPlayer < _playersCount; ++_curPlayer)
            {
                if (_curPlayer == HeroPosition)
                {
                    continue;
                }
                WalkUFTreePP <StrategyTree, PrepareStrategicProbabsContext> wt = new WalkUFTreePP <StrategyTree, PrepareStrategicProbabsContext>();
                wt.OnNodeBegin = PrepareStrategicProbabs_OnNodeBegin;
                wt.Walk(Strategies[_curPlayer]);
            }

            _chanceTreeNodes = new int[_roundsCount][][];

            for (int r = 0; r < _roundsCount; ++r)
            {
                int oppChanceIndexSize = 1;
                for (int p = 0; p < _playersCount; ++p)
                {
                    if (p == HeroPosition)
                    {
                        continue;
                    }
                    oppChanceIndexSize *= _chanceIndexSizes[p][r];
                }
                int size = _chanceIndexSizes[HeroPosition][r];
                _chanceTreeNodes[r] = new int[size][];
                for (int i = 0; i < size; ++i)
                {
                    _chanceTreeNodes[r][i] = new int[oppChanceIndexSize];
                }
            }


            WalkUFTreePP <ChanceTree, PrepareChanceIndexContext> wt1 = new WalkUFTreePP <ChanceTree, PrepareChanceIndexContext>();

            wt1.OnNodeBegin = PrepareChanceIndex_OnNodeBegin;
            wt1.Walk(ChanceTree);
        }