protected override void OnTreeBeginFunc(XmlDocument tree, XmlElement root)
        {
            int nodesCount = tree.SelectNodes("//*").Count;

            StrategyTree = new StrategyTree(nodesCount);
            _nodeId      = 0;
        }
        bool CompareNodes(StrategyTree t0, StrategyTree t1, Int64 n)
        {
            if (t0.Nodes[n].Position != t1.Nodes[n].Position)
            {
                ReportError(n, string.Format("position mismatch: t0:{0} != t1:{1}", t0.Nodes[n].Position, t1.Nodes[n].Position));
            }
            if (n == 0)
            {
                return(true);
            }
            if (t0.Nodes[n].IsDealerAction != t1.Nodes[n].IsDealerAction)
            {
                ReportError(n, "action kind mismatch");
            }
            if (t0.Nodes[n].IsDealerAction)
            {
                if (t0.Nodes[n].Card != t1.Nodes[n].Card)
                {
                    ReportError(n, string.Format("card mismatch: t0:{0} != t1:{1}", t0.Nodes[n].Card, t1.Nodes[n].Card));
                }
                return(true);
            }
            if (t0.Nodes[n].Amount != t1.Nodes[n].Amount)
            {
                ReportError(n, string.Format("amount mismatch: t0:{0} != t1:{1}", t0.Nodes[n].Amount, t1.Nodes[n].Amount));
            }
            int    p          = t0.Nodes[n].Position;
            double probabDiff = Math.Abs(t0.Nodes[n].Probab - t1.Nodes[n].Probab);

            SumProbabDiff[p] += probabDiff;
            MaxProbabDiff[p]  = Math.Max(probabDiff, MaxProbabDiff[p]);
            PlayerNodesCount[p]++;

            return(true);
        }
示例#3
0
        public static void ToTxt(StrategyTree t, TextWriter w)
        {
            w.WriteLine("SeralizationFormat {0}", SERIALIZATION_FORMAT);
            XmlWriterSettings s = new XmlWriterSettings {
                Indent = false, NewLineChars = ""
            };

            w.Write("Version ");
            XmlSerializerExt.Serialize(t.Version, w, s);
            w.WriteLine();
            w.WriteLine("NodesCount {0}", t.NodesCount);
            for (Int64 n = 0; n < t.NodesCount; ++n)
            {
                w.WriteLine("Id {0}", n);
                w.WriteLine("D {0}", t.GetDepth(n));
                w.WriteLine("P {0}", t.Nodes[n].Position);
                if (t.Nodes[n].IsDealerAction)
                {
                    w.WriteLine("C {0}", t.Nodes[n].Card);
                }
                else
                {
                    w.WriteLine("A {0}", TextDumpHelper.DoubleToBinString(t.Nodes[n].Amount));
                    w.WriteLine("Pr {0}", TextDumpHelper.DoubleToBinString(t.Nodes[n].Probab));
                }
            }
        }
示例#4
0
        void PrepareHero_OnNodeBegin(StrategyTree tree, PrepareHeroVarsContext[] stack, int depth)
        {
            PrepareHeroVarsContext context = stack[depth];
            Int64 n = context.NodeIdx;

            if (depth == PLAYERS_COUNT)
            {
                // Skip blinds
                context.ActionTreeIdx = PLAYERS_COUNT;
            }
            else
            {
                context.ActionTreeIdx = stack[depth - 1].ActionTreeIdx;
                context.Round         = stack[depth - 1].Round;
                context.ChanceIdx     = stack[depth - 1].ChanceIdx;
                context.VarH          = stack[depth - 1].VarH;
                context.EqConstr      = null;

                if (tree.Nodes[n].IsDealerAction)
                {
                    context.Round++;
                    context.ChanceIdx += CalculateChanceOffset(context.Round, HeroPosition) * tree.Nodes[n].Card;
                }
                else
                {
                    context.ActionTreeIdx = FindActionTreeNodeIdx(tree, n, context.ActionTreeIdx, stack[depth - 1].ChildrenCount - 1);
                    if (tree.Nodes[n].IsPlayerAction(HeroPosition))
                    {
                        Constraint constr = stack[depth - 1].EqConstr;
                        if (stack[depth - 1].EqConstr == null)
                        {
                            // Create new constraint
                            constr = new Constraint();
                            stack[depth - 1].EqConstr = constr;
                            _constraintsEQ.Add(constr);
                            if (context.VarH == -1)
                            {
                                // This is the very first move of the hero in this tree branch,
                                // add constraint Sum(h_child) = 1
                                constr.RightHandSide = 1;
                            }
                            else
                            {
                                // Add constraint h_prev_move = Sum(h_child)
                                constr.RightHandSide = 0;
                                constr.AddVariable(stack[depth - 1].VarH, -1);
                            }
                        }
                        context.VarH = _variables.Add("h", (int)n);
                        constr.AddVariable(context.VarH, 1);
                    }

                    if (_actionTreeIndex.GetChildrenCount(context.ActionTreeIdx) == 0)
                    {
                        // A leaf.
                        _heroVarsInLeaves[context.ActionTreeIdx][context.ChanceIdx] = context.VarH;
                    }
                }
            }
        }
示例#5
0
        void CalculateBr_OnNodeBegin(StrategyTree tree, CalculateBrContext[] stack, int depth)
        {
            CalculateBrContext context = stack[depth];
            Int64 n = context.NodeIdx;

            if (depth > 0)
            {
                context.IsBr = stack[depth - 1].IsBr;
            }

            if (tree.Nodes[n].IsPlayerAction(HeroPosition))
            {
                // Hero made a move
                Int64 pn = stack[depth - 1].NodeIdx;
                if (tree.Nodes[n].Probab == tree.Nodes[pn].Probab && context.IsBr)
                {
                    tree.Nodes[n].Probab  = 1;
                    tree.Nodes[pn].Probab = double.MinValue;
                    context.IsBr          = true;
                }
                else
                {
                    context.IsBr         = false;
                    tree.Nodes[n].Probab = 0;
                }
            }
        }
示例#6
0
 public static void ToTxt(StrategyTree t, string fileName)
 {
     using (TextWriter w = new StreamWriter(File.Open(fileName, FileMode.Create, FileAccess.Write, FileShare.Write)))
     {
         ToTxt(t, w);
     }
 }
示例#7
0
        void CalculateValues_OnNodeBegin(StrategyTree tree, CalculateValuesContext[] stack, int depth)
        {
            CalculateValuesContext context = stack[depth];
            Int64 n = context.NodeIdx;

            // We'll use the probability to store game values temporarily.
            // Initialize with an unique value works both for summing and maximization.
            tree.Nodes[n].Probab = double.MinValue;

            if (depth == 0)
            {
                context.ActionTreeIdx = 0;
                context.State         = new StrategicState(_playersCount);
            }
            else
            {
                context.ActionTreeIdx = stack[depth - 1].ActionTreeIdx;
                context.Round         = stack[depth - 1].Round;
                context.HeroChanceIdx = stack[depth - 1].HeroChanceIdx;

                if (tree.Nodes[n].IsDealerAction)
                {
                    context.Round++;
                    context.HeroChanceIdx += CalculateChanceOffset(context.Round, HeroPosition) * tree.Nodes[n].Card;
                    context.State          = stack[depth - 1].State;
                }
                else
                {
                    context.ActionTreeIdx = FindActionTreeNodeIdx(tree, n, context.ActionTreeIdx, stack[depth - 1].ChildrenCount - 1);
                    context.State         = stack[depth - 1].State.GetNextState(ActionTree.Nodes[context.ActionTreeIdx]);
                }
            }
        }
示例#8
0
        /// <summary>
        /// Copies data from src to dst.
        /// Returns true if everything is OK. If something went wrong, an exception is thrown.
        /// </summary>
        public static void Merge(StrategyTree dst, StrategyTree src, int pos)
        {
            Comparer comparer = new Comparer();

            comparer.Position = pos;
            if (comparer.Compare(dst, src, comparer.CopyNode))
            {
                return;
            }
            string message;

            switch (comparer.Result)
            {
            case ICompareUFTreesDefs.ResultKind.StructureDiffers:
                message = string.Format("Strategies have different structures at node: {0}", comparer.DiffersAt);
                break;

            case ICompareUFTreesDefs.ResultKind.ValueDiffers:
                message = string.Format("Position or node type mismatch at node: {0}", comparer.DiffersAt);
                break;

            default:
                message = string.Format("Unknown error at node: {0}", comparer.DiffersAt);
                break;
            }
            throw new ApplicationException(message);
        }
示例#9
0
            protected override void CustomizeNodeAttributes(UFToUniAdapter aTree, int n, List <Context> stack, int depth, NodeAttributeMap attr)
            {
                Context      context = stack[depth];
                StrategyTree tree    = (StrategyTree)aTree.UfTree;

                base.CustomizeNodeAttributes(aTree, n, stack, depth, attr);
                string nodeLabel = attr.label;

                nodeLabel += string.Format("\\ngv:{0:0.000}", Solver._ptExt[Position][n].GameValue);
                if (!tree.Nodes[n].IsDealerAction && n > 0)
                {
                    nodeLabel += string.Format("\\ns:{0:0.0000}", tree.Nodes[n].Probab);
                }
                if (tree.Nodes[n].IsDealerAction)
                {
                    nodeLabel += string.Format("\\nc:{0}", tree.Nodes[n].Card);
                }
                if (context.IsLeaf)
                {
                    nodeLabel += string.Format("\\npf:{0:0.0000}", Solver._ptExt[Position][n].PotFactor);
                    nodeLabel += string.Format("\\nati:{0}", Solver._ptExt[Position][n].AtIdx);
                }
                if (n == 0)
                {
                    nodeLabel += string.Format("\\nGV:{0:0.000}", Solver.LastBrValues[Position]);
                }
                attr.label = nodeLabel;
            }
示例#10
0
        /// <summary>
        /// Sets fields of the context. Override to customize view or call it in an overriden OnNodeBegin.
        /// </summary>
        protected virtual void SetContext(UFToUniAdapter aTree, int aNode, List <ContextT> stack, int depth)
        {
            ContextT     context = stack[depth];
            StrategyTree tree    = (StrategyTree)(aTree.UfTree);

            context.Tree = tree;

            if (depth == 0)
            {
                context.Round = -1;
            }
            else
            {
                context.Round = stack[depth - 1].Round;
            }
            // Deal action => new round.
            if (tree.Nodes[aNode].IsDealerAction)
            {
                context.Round++;
            }
            context.Id             = aNode.ToString();
            context.IsDealerAction = tree.Nodes[aNode].IsDealerAction;
            context.Position       = tree.Nodes[aNode].Position;
            context.Probab         = tree.Nodes[aNode].IsDealerAction ? 0 : tree.Nodes[aNode].Probab;
            context.ActionLabel    = depth == 0 ? "" : tree.Nodes[aNode].ToStrategicString(CardNames);
        }
示例#11
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);
        }
        /// <summary>
        /// Compares trees verbose.
        /// </summary>
        public static void CompareS(StrategyTree st0, StrategyTree st1)
        {
            CompareStrategyTrees comparer = new CompareStrategyTrees {
                IsVerbose = true
            };

            comparer.Compare(st0, st1);
        }
示例#13
0
        protected override void OnTreeBeginFunc(UFToUniAdapter aTree, int aRoot)
        {
            StrategyTree tree = (StrategyTree)(aTree.UfTree);

            GraphAttributes.label    = tree.Version.Description;
            GraphAttributes.fontsize = 20;
            base.OnTreeBeginFunc(aTree, aRoot);
        }
示例#14
0
        /// <summary>
        /// Runs the analysis in verbose mode.
        /// </summary>
        public static void AnalyzeS(StrategyTree st, bool isAbsolute, int position)
        {
            AnalyzeStrategyTree analyzer = new AnalyzeStrategyTree {
                IsVerbose = true, StrategyTree = st, IsAbsolute = isAbsolute, HeroPosition = position
            };

            analyzer.Analyze();
        }
示例#15
0
        public static StrategyTree CreateStrategyTree(GameDefinition gd, int pos)
        {
            ChanceTree   ct  = CreateChanceTreeByGameDef.Create(gd);
            ChanceTree   pct = ExtractPlayerChanceTree.ExtractS(ct, 0);
            ActionTree   at  = CreateActionTreeByGameDef.Create(gd);
            StrategyTree st  = CreateStrategyTreeByChanceAndActionTrees.CreateS(pct, at);

            return(st);
        }
示例#16
0
        void CalculateBr_OnNodeEnd(StrategyTree tree, CalculateBrContext[] stack, int depth)
        {
            CalculateBrContext context = stack[depth];
            Int64 n = context.NodeIdx;

            if (tree.Nodes[n].IsDealerAction || tree.Nodes[n].Position != HeroPosition)
            {
                tree.Nodes[n].Probab = 0;
            }
        }
示例#17
0
 public static void Show(StrategyTree t, string fileName)
 {
     using (TextWriter w = new StreamWriter(File.Open(fileName, FileMode.Create)))
     {
         VisStrategyTree <VisStrategyTreeContext> vis = new VisStrategyTree <VisStrategyTreeContext> {
             Output = w
         };
         vis.Show(t);
     }
 }
示例#18
0
        /// <summary>
        /// Runs FictitiousPlay with the specified parameters.
        /// Some parameters are set by default (e.g. verbosity), the caller has a chance to overwrite them
        /// using Configure delegate.
        /// </summary>
        public StrategyTree[] Solve(ActionTree at, ChanceTree ct)
        {
            int playersCount = 2;

            DirectoryExt.Delete(BaseDir);
            Directory.CreateDirectory(BaseDir);

            string inputDir = Path.Combine(BaseDir, "input");

            Directory.CreateDirectory(inputDir);
            string traceDir = Path.Combine(BaseDir, "trace");

            string chanceTreeFile = Path.Combine(inputDir, "ct.dat");
            string actionTreeFile = Path.Combine(inputDir, "at.dat");

            ct.Write(chanceTreeFile);
            at.Write(actionTreeFile);

            if (VisualizeTrees)
            {
                VisActionTree.Show(at, actionTreeFile + ".gv");
                VisChanceTree.Show(ct, chanceTreeFile + ".gv");
            }

            Solver.ChanceTreeFile     = chanceTreeFile;
            Solver.EqualCa            = false;
            Solver.ActionTreeFile     = actionTreeFile;
            Solver.OutputPath         = BaseDir;
            Solver.SnapshotsCount     = 2;
            Solver.Epsilon            = Epsilon;
            Solver.ThreadsCount       = 6;
            Solver.IsVerbose          = true;
            Solver.IterationVerbosity = 10000;
            Solver.MaxIterationCount  = 1000000000;

            if (Configure != null)
            {
                Configure(Solver);
            }
            Solver.Solve();

            StrategyTree[] eqStrategies = new StrategyTree[playersCount];

            for (int p = 0; p < playersCount; ++p)
            {
                string fileName = Solver.CurrentSnapshotInfo.StrategyFile[p];
                eqStrategies[p] = StrategyTree.Read <StrategyTree>(fileName);
                if (VisualizeTrees)
                {
                    VisStrategyTree.Show(eqStrategies[p], fileName + ".gv");
                }
            }

            return(eqStrategies);
        }
示例#19
0
        public void Test_FindNode()
        {
            GameDefinition gd = XmlSerializerExt.Deserialize <GameDefinition>(
                Props.Global.Expand("${bds.DataDir}ai.pkr.metastrategy/kuhn.gamedef.xml"));
            StrategyTree st = TreeHelper.CreateStrategyTree(gd, 0);

            Assert.AreEqual(3, st.FindNode("0dJ", gd.DeckDescr));
            Assert.AreEqual(11, st.FindNode("0dJ 0p1 1p1", gd.DeckDescr));
            Assert.AreEqual(13, st.FindNode("0dQ 0p0", gd.DeckDescr));
            Assert.AreEqual(16, st.FindNode("0d1 0p0 1p1 0p0", null));
        }
示例#20
0
        private uint FindActionTreeNodeIdx(StrategyTree tree, long sNodeIdx, long aNodeIdx, int hintChildIdx)
        {
            long actionTreeIdx = _at.FindChildByAmount(aNodeIdx, tree.Nodes[sNodeIdx].Amount,
                                                       _init.AtChildrenIndex, hintChildIdx);

            if (actionTreeIdx == -1)
            {
                throw new ApplicationException(String.Format("Cannot find action tree node, strategy node {0}", sNodeIdx));
            }
            return((uint)actionTreeIdx);
        }
示例#21
0
            protected override void CustomizeEdgeAttributes(UFToUniAdapter aTree, int n, int pn, List <Context> stack, int depth, Vis.EdgeAttributeMap attr)
            {
                base.CustomizeEdgeAttributes(aTree, n, pn, stack, depth, attr);
                StrategyTree tree = (StrategyTree)aTree.UfTree;

                if (!tree.Nodes[n].IsDealerAction && tree.Nodes[n].Position == Solver.HeroPosition && tree.Nodes[n].Probab == 1.0)
                {
                    // Hero have chosen this edge - show thick
                    attr.penwidth = 3.0;
                }
            }
示例#22
0
            public static void Show(GameValue solver, int position, string fileName)
            {
                StrategyTree t = solver.Strategies[position];

                using (TextWriter w = new StreamWriter(File.Open(fileName, FileMode.Create)))
                {
                    Vis vis = new Vis {
                        Output = w, Solver = solver, Position = position
                    };
                    vis.Show(t);
                }
            }
示例#23
0
            protected override void OnNodeEndFunc(UFToUniAdapter aTree, int aNode, List <Vis.Context> stack, int depth)
            {
                Context      context = stack[depth];
                StrategyTree tree    = (StrategyTree)aTree.UfTree;

                if (depth > 0)
                {
                    stack[depth - 1].Value += context.Value;
                }

                base.OnNodeEndFunc(aTree, aNode, stack, depth);
            }
        public void Test_LeducHe()
        {
            GameDefinition gd = XmlSerializerExt.Deserialize <GameDefinition>(
                Props.Global.Expand("${bds.DataDir}ai.pkr.metastrategy/leduc-he.gamedef.xml"));

            for (int pos = 0; pos < gd.MinPlayers; ++pos)
            {
                StrategyTree st = TreeHelper.CreateStrategyTree(gd, pos);
                Assert.AreEqual(st.PlayersCount, gd.MinPlayers);
                Assert.AreEqual(723, st.NodesCount);
            }
        }
示例#25
0
            public static void Show(Br solver, string fileName)
            {
                StrategyTree t = solver.Strategies[solver.HeroPosition];

                using (TextWriter w = new StreamWriter(File.Open(fileName, FileMode.Create)))
                {
                    Vis vis = new Vis {
                        Output = w, Solver = solver
                    };
                    vis.Show(t);
                }
            }
示例#26
0
        public virtual string GetCardAttribute(UFToUniAdapter t, List <XmlizeTreeContext <int, int> > s, int d)
        {
            StrategyTree st = (StrategyTree)t.UfTree;

            if (!st.Nodes[s[d].Node].IsDealerAction)
            {
                return("");
            }
            int    card     = st.Nodes[s[d].Node].Card;
            string cardText = DeckDescr != null ? DeckDescr.CardNames[card] : card.ToString();

            return(cardText);
        }
示例#27
0
            protected override void CustomizeNodeAttributes(UFToUniAdapter aTree, int n, List <Context> stack, int depth, Vis.NodeAttributeMap attr)
            {
                base.CustomizeNodeAttributes(aTree, n, stack, depth, attr);
                StrategyTree tree = (StrategyTree)aTree.UfTree;

                if (!tree.Nodes[n].IsDealerAction && tree.Nodes[n].Position == Solver.HeroPosition && tree.Nodes[n].Probab != 1.0)
                {
                    if (IsHtmlColor(attr.fillcolor))
                    {
                        attr.fillcolor = GradientHtmlColor(attr.fillcolor, Color.FromArgb(255, 200, 200, 200), 0.4);
                    }
                }
            }
示例#28
0
        private long FindActionTreeNodeIdx(StrategyTree tree, long sNodeIdx, long aNodeIdx, int hintChildIdx)
        {
            long actionTreeIdx = ActionTree.FindChildByAmount(aNodeIdx,
                                                              tree.Nodes[sNodeIdx].Amount,
                                                              _actionTreeIndex, hintChildIdx);

            if (actionTreeIdx == -1)
            {
                throw new ApplicationException(
                          String.Format("Cannot find action tree node for player {0}, strategy node {1}", _curPlayer, sNodeIdx));
            }
            return(actionTreeIdx);
        }
示例#29
0
            protected override bool OnNodeBeginFunc(UFToUniAdapter aTree, int n, List <Context> stack, int depth)
            {
                Context      context = stack[depth];
                StrategyTree tree    = (StrategyTree)aTree.UfTree;

                // Set default vis-fields
                SetContext(aTree, n, stack, depth);
                if (Solver._visGameValues != null)
                {
                    context.Value = Solver._visGameValues[n];
                }
                return(base.OnNodeBeginFunc(aTree, n, stack, depth));
            }
示例#30
0
        public static StrategyTree 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 tag, 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"));
            StrategyTree t          = new StrategyTree(nodesCount);

            t.SetNodesMemory(0); // Clear memory to ensure zeros at probability for dealer.
            t.Version.CopyFrom(v);
            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));
                }
                t.SetDepth(n, byte.Parse(TextDumpHelper.ReadTag(r, ref ln, "D")));
                t.Nodes[n].Position = int.Parse(TextDumpHelper.ReadTag(r, ref ln, "P"));
                TextDumpHelper.Split(TextDumpHelper.ReadLine(r, ref ln), out tag, out value);
                if (tag == "C")
                {
                    t.Nodes[n].IsDealerAction = true;
                    t.Nodes[n].Card           = int.Parse(value);
                }
                else if (tag == "A")
                {
                    t.Nodes[n].IsDealerAction = false;
                    t.Nodes[n].Amount         = TextDumpHelper.BinStringToDouble(value);
                    t.Nodes[n].Probab         = TextDumpHelper.BinStringToDouble(TextDumpHelper.ReadTag(r, ref ln, "Pr"));
                }
                else
                {
                    throw new ApplicationException(String.Format("Line {0}: wrong tag '{1}', 'C' or 'A'", ln, tag));
                }
            }
            return(t);
        }