示例#1
0
        /// <summary>
        /// Solves the game by fictitious play and verifies the solution.
        /// </summary>
        /// <param name="snapshotAfter">Number of iterations to make an intermediate snapshot after. -1 for no intermediate snapshot.</param>
        /// <param name="configureSolver"></param>
        private StrategyTree[]  SolveAndVerifyVerifySolution(ActionTree at, ChanceTree ct, double epsilon, bool useLp)
        {
            if (useLp)
            {
                double[]       gv;
                StrategyTree[] st = EqLp.Solve(at, ct, out gv);
                VisStrategyTree.Show(st[0], Path.Combine(_outDir, "st-0.gv"));
                VisStrategyTree.Show(st[1], Path.Combine(_outDir, "st-1.gv"));
                Console.WriteLine("LP gv: {0}, {1}", gv[0], gv[1]);
            }

            FictPlayHelper fp = new FictPlayHelper
            {
                Epsilon        = epsilon,
                VisualizeTrees = true,
                BaseDir        = Path.Combine(_outDir, "fp")
            };

            StrategyTree[] eqStrategies = fp.Solve(at, ct);
            string         error;

            // Verify consistency of strategies
            for (int p = 0; p < 2; ++p)
            {
                Assert.IsTrue(VerifyAbsStrategy.Verify(eqStrategies[p], p, 1e-7, out error), string.Format("Pos {0}: {1}", p, error));
            }

            // Run VerifyEq on the computed strategies.
            Assert.IsTrue(VerifyEq.Verify(at, ct,
                                          eqStrategies, 3 * epsilon, out error), error);

            return(eqStrategies);
        }
示例#2
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));
            }
        }
示例#3
0
        private GameValue Solve(TestParams testParams, bool visualize, ConfigureSolver configureSolver)
        {
            if (visualize)
            {
                VisActionTree.Show(testParams.ActionTree,
                                   Path.Combine(_outDir, String.Format("{0}-at.gv", testParams.Name)));
                VisChanceTree.Show(testParams.ChanceTree,
                                   Path.Combine(_outDir, String.Format("{0}-ct.gv", testParams.Name)));
                for (int p = 0; p < testParams.StrategyTrees.Length; ++p)
                {
                    VisStrategyTree.Show(testParams.StrategyTrees[p],
                                         Path.Combine(_outDir, string.Format("{0}-st-{1}.gv", testParams.Name, p)));
                }
            }

            // Make sure input is correct.
            for (int p = 0; p < testParams.ChanceTree.Nodes[0].Position; ++p)
            {
                string errorText;
                Assert.IsTrue(VerifyAbsStrategy.Verify(testParams.StrategyTrees[p], p, 0.000001, out errorText), errorText);
            }

            GameValue gv = new GameValue {
                ChanceTree = testParams.ChanceTree, ActionTree = testParams.ActionTree, Strategies = testParams.StrategyTrees
            };

            gv.PrepareVis = visualize;

            if (configureSolver != null)
            {
                configureSolver(gv);
            }

            gv.Solve();

            if (visualize)
            {
                for (int p = 0; p < testParams.ChanceTree.PlayersCount; ++p)
                {
                    GameValue.Vis.Show(gv, p, Path.Combine(_outDir, String.Format("{0}-{1}-val.gv", testParams.Name, p)));
                }
            }

            Assert.AreEqual(2, gv.Values.Length);
            for (int p = 0; p < testParams.ChanceTree.PlayersCount; ++p)
            {
                Console.WriteLine("Game value pos {0}: {1}", p, gv.Values[p]);
                Assert.AreEqual(testParams.ExpectedResult[p], gv.Values[p], testParams.Epsilon);
            }
            return(gv);
        }
示例#4
0
        private void Solve(TestParams testParams, bool visualize, ConfigureSolver configureSolver)
        {
            if (visualize)
            {
                VisActionTree.Show(testParams.ActionTree,
                                   Path.Combine(_outDir, String.Format("{0}-at.gv", testParams.Name)));
                VisChanceTree.Show(testParams.ChanceTree,
                                   Path.Combine(_outDir, String.Format("{0}-ct.gv", testParams.Name)));
            }

            StrategyTree [] eqStrategies = new StrategyTree[testParams.ChanceTree.PlayersCount];

            string error;

            for (int heroPos = 0; heroPos < testParams.ChanceTree.PlayersCount; ++heroPos)
            {
                // Create and configure EqLp solver
                EqLp solver = new EqLp
                {
                    HeroPosition = heroPos,
                    ChanceTree   = testParams.ChanceTree,
                    ActionTree   = testParams.ActionTree,
                };

                if (configureSolver != null)
                {
                    configureSolver(solver);
                }

                // Solve EqLp
                solver.Solve();
                eqStrategies[heroPos] = solver.Strategy;

                if (visualize)
                {
                    VisStrategyTree.Show(solver.Strategy,
                                         Path.Combine(_outDir, string.Format("{0}-eq-{1}.gv", testParams.Name, heroPos)));
                }

                // Verify the eq value and strategy
                Assert.AreEqual(testParams.ExpectedResult[heroPos], solver.Value, testParams.Epsilon, "Wrong eq value");
                Assert.IsTrue(VerifyAbsStrategy.Verify(solver.Strategy, solver.HeroPosition, 1e-7, out error), error);
            }
            // Verify eq, use another (better) epsilon because EqLp and VerifyEq have better precision
            // than most of the reference game solvers like OCFR.
            Assert.IsTrue(VerifyEq.Verify(testParams.ActionTree, testParams.ChanceTree, eqStrategies, 1e-7, out error), error);
        }
示例#5
0
        /// <summary>
        /// Solves the game by fictitious play and verifies the solution.
        /// </summary>
        /// <param name="snapshotAfter">Number of iterations to make an intermediate snapshot after. -1 for no intermediate snapshot.</param>
        /// <param name="configureSolver"></param>
        private void SolveAndVerifyVerifySolution(TestParams testParams, bool visualize, bool trace, int[] iterCounts, ConfigureSolver configureSolver)
        {
            int playersCount = testParams.ChanceTree.PlayersCount;

            StrategyTree eqStrategy = RunSolver(testParams, visualize, trace, iterCounts, configureSolver);
            string       error;

            // Verify consistency of strategies
            for (int p = 0; p < 2; ++p)
            {
                Assert.IsTrue(VerifyAbsStrategy.Verify(eqStrategy, p, 1e-7, out error), string.Format("Pos {0}: {1}", p, error));
            }

            // Run VerifyEq on the computed strategies.
            StrategyTree[] strategies = new StrategyTree[] { eqStrategy, eqStrategy };
            Assert.IsTrue(VerifyEq.Verify(testParams.ActionTree, testParams.ChanceTree,
                                          strategies, 3 * testParams.Epsilon, out error), error);

            //
            // Do a redundant test with EqLp
            //

            // Find game values for our solution
            GameValue gv = new GameValue
            {
                ActionTree = testParams.ActionTree,
                ChanceTree = testParams.ChanceTree,
                Strategies = new StrategyTree[] { eqStrategy, eqStrategy }
            };

            gv.Solve();

            // Solve eq with EqLp
            double[]       expEqValues;
            StrategyTree[] expStrategies = EqLp.Solve(testParams.ActionTree, testParams.ChanceTree, out expEqValues);

            // Verify the eq value and strategy
            for (int p = 0; p < 2; ++p)
            {
                if (visualize)
                {
                    Console.WriteLine("Expected eq value pos {0}: {1}", p, expEqValues[p]);
                }
                Assert.AreEqual(expEqValues[p], gv.Values[p], testParams.Epsilon, "Eq value differs from EqLp solution");
            }
        }
示例#6
0
        public void Test_Convert()
        {
            GameDefinition gd = XmlSerializerExt.Deserialize <GameDefinition>(
                Props.Global.Expand("${bds.DataDir}ai.pkr.metastrategy/kuhn.gamedef.xml"));

            StrategyTree st = TreeHelper.CreateStrategyTree(gd, 0);

            st.Nodes[4].Probab = 0.4;
            st.Nodes[9].Probab = 0.6;
            st.Nodes[7].Probab = 0.3;
            st.Nodes[8].Probab = 0.7;

            st.Nodes[13].Probab = 0.5;
            st.Nodes[18].Probab = 0.5;
            st.Nodes[16].Probab = 0.1;
            st.Nodes[17].Probab = 0.9;

            st.Nodes[22].Probab = 0.2;
            st.Nodes[27].Probab = 0.8;
            st.Nodes[25].Probab = 0.5;
            st.Nodes[26].Probab = 0.5;

            string error;

            Assert.IsTrue(VerifyCondStrategy.Verify(st, 0, out error), error);

            ConvertCondToAbs.Convert(st, 0);

            Assert.IsTrue(VerifyAbsStrategy.Verify(st, 0, 1e-7, out error), error);

            Assert.AreEqual(0.4, st.Nodes[4].Probab, 1e-7);
            Assert.AreEqual(0.6, st.Nodes[9].Probab, 1e-7);
            Assert.AreEqual(0.12, st.Nodes[7].Probab, 1e-7);
            Assert.AreEqual(0.28, st.Nodes[8].Probab, 1e-7);

            Assert.AreEqual(0.5, st.Nodes[13].Probab, 1e-7);
            Assert.AreEqual(0.5, st.Nodes[18].Probab, 1e-7);
            Assert.AreEqual(0.05, st.Nodes[16].Probab, 1e-7);
            Assert.AreEqual(0.45, st.Nodes[17].Probab, 1e-7);

            Assert.AreEqual(0.2, st.Nodes[22].Probab, 1e-7);
            Assert.AreEqual(0.8, st.Nodes[27].Probab, 1e-7);
            Assert.AreEqual(0.1, st.Nodes[25].Probab, 1e-7);
            Assert.AreEqual(0.1, st.Nodes[26].Probab, 1e-7);
        }
        public void Test_Leduc()
        {
            GameDefinition gd = XmlSerializerExt.Deserialize <GameDefinition>(
                Props.Global.Expand("${bds.DataDir}ai.pkr.metastrategy/leduc-he.gamedef.xml"));

            for (_heroPos = 0; _heroPos < gd.MinPlayers; ++_heroPos)
            {
                StrategyTree st = CreateValidStrategy(gd);

                string fileName = Path.Combine(_outDir, string.Format("{0}-{1}.gv", gd.Name, _heroPos));
                VisStrategyTree.Show(st, fileName);

                string errorText;
                Assert.IsTrue(VerifyAbsStrategy.Verify(st, _heroPos, out errorText));

                // Now make some errors.
                if (_heroPos == 0)
                {
                    st.Nodes[339].Probab += 0.1;
                    Assert.IsFalse(VerifyAbsStrategy.Verify(st, _heroPos, out errorText));
                    string expTextBegin = string.Format("Node {0},", 342);
                    Assert.AreEqual(expTextBegin, errorText.Substring(0, expTextBegin.Length));
                    st.Nodes[339].Probab -= 0.1;

                    st.Nodes[348].Probab += 0.1;
                    Assert.IsFalse(VerifyAbsStrategy.Verify(st, _heroPos, out errorText));
                    expTextBegin = string.Format("Node {0},", 345);
                    Assert.AreEqual(expTextBegin, errorText.Substring(0, expTextBegin.Length));
                }
                else
                {
                    st.Nodes[435].Probab += 0.1;
                    Assert.IsFalse(VerifyAbsStrategy.Verify(st, _heroPos, out errorText));
                    string expTextBegin = string.Format("Node {0},", 439);
                    Assert.AreEqual(expTextBegin, errorText.Substring(0, expTextBegin.Length));
                    st.Nodes[435].Probab -= 0.1;

                    st.Nodes[432].Probab += 0.1;
                    Assert.IsFalse(VerifyAbsStrategy.Verify(st, _heroPos, out errorText));
                    expTextBegin = string.Format("Node {0},", 429);
                    Assert.AreEqual(expTextBegin, errorText.Substring(0, expTextBegin.Length));
                }
            }
        }
示例#8
0
        static int Main(string[] args)
        {
            if (!Parser.ParseArgumentsWithUsage(args, _cmdLine))
            {
                return(1);
            }

            if (_cmdLine.DebuggerLaunch)
            {
                Debugger.Launch();
            }

            StrategyTree st = StrategyTree.Read <StrategyTree>(_cmdLine.StrategyTree);

            if (_cmdLine.Verify)
            {
                string error = "";
                bool   isOk  = true;
                if (_cmdLine.IsAbsolute)
                {
                    Console.Write("Verifying absolute strategy ...");
                    isOk = VerifyAbsStrategy.Verify(st, _cmdLine.HeroPosition, 1e-7, out error);
                }
                else
                {
                    Console.Write("Verifying conditional strategy ...");
                    isOk = VerifyCondStrategy.Verify(st, _cmdLine.HeroPosition, 1e-7, out error);
                }
                if (isOk)
                {
                    Console.WriteLine(" OK");
                }
                else
                {
                    Console.WriteLine(" Verification failed: {0}", error);
                    return(1);
                }
            }

            AnalyzeStrategyTree.AnalyzeS(st, _cmdLine.IsAbsolute, _cmdLine.HeroPosition);

            return(0);
        }
示例#9
0
        void SolveGame(string runDir, GameDefinition gd, IChanceAbstraction [] chanceAbstractions, double [] brValues)
        {
            ChanceTree ct = CreateChanceTreeByAbstraction.CreateS(gd, chanceAbstractions);
            ActionTree at = CreateActionTreeByGameDef.Create(gd);

            double[]       eqValues;
            StrategyTree[] eqStrategies = EqLp.Solve(at, ct, out eqValues);

            string error;

            for (int p = 0; p < gd.MinPlayers; ++p)
            {
                Assert.IsTrue(VerifyAbsStrategy.Verify(eqStrategies[p], p, 1e-7, out error), error);
            }
            // Verify eq
            Assert.IsTrue(VerifyEq.Verify(at, ct, eqStrategies, 1e-7, out error), error);

            StrategyTree[] brStrategies = new StrategyTree[gd.MinPlayers];

            // Find BR for each position
            for (int heroPos = 0; heroPos < gd.MinPlayers; ++heroPos)
            {
                Br br = new Br
                {
                    HeroPosition = heroPos,
                    ActionTree   = at,
                    ChanceTree   = ct,
                    Strategies   = (StrategyTree[])eqStrategies.Clone()
                };
                br.Solve();
                brStrategies[heroPos] = br.Strategies[heroPos];
                brValues[heroPos]     = br.Value;
            }

            MergeAndSaveStrategies(runDir, "", eqStrategies, chanceAbstractions);
            MergeAndSaveStrategies(runDir, "-br", brStrategies, chanceAbstractions);
        }
示例#10
0
        private void Solve(TestParams testParams, bool visualize, ConfigureSolver configureSolver)
        {
            if (visualize)
            {
                VisActionTree.Show(testParams.ActionTree,
                                   Path.Combine(_outDir, String.Format("{0}-at.gv", testParams.Name)));
                VisChanceTree.Show(testParams.ChanceTree,
                                   Path.Combine(_outDir, String.Format("{0}-ct.gv", testParams.Name)));
                for (int p = 0; p < testParams.StrategyTrees.Length; ++p)
                {
                    VisStrategyTree.Show(testParams.StrategyTrees[p],
                                         Path.Combine(_outDir, string.Format("{0}-st-{1}.gv", testParams.Name, p)));
                }
            }

            // Make sure input is correct.
            for (int p = 0; p < testParams.ChanceTree.Nodes[0].Position; ++p)
            {
                string errorText;
                Assert.IsTrue(VerifyAbsStrategy.Verify(testParams.StrategyTrees[p], p, 0.000001, out errorText), errorText);
            }

            for (int heroPos = 0; heroPos < testParams.ChanceTree.PlayersCount; ++heroPos)
            {
                // Create and configure Br solver
                Br br = new Br
                {
                    HeroPosition = heroPos,
                    ChanceTree   = testParams.ChanceTree,
                    ActionTree   = testParams.ActionTree,
                };
                br.Strategies = new StrategyTree[testParams.ChanceTree.PlayersCount];
                for (int opp = 0; opp < testParams.ChanceTree.PlayersCount; ++opp)
                {
                    if (opp == heroPos)
                    {
                        continue;
                    }
                    br.Strategies[opp] = testParams.StrategyTrees[opp];
                }
                br.PrepareVis = visualize;

                if (configureSolver != null)
                {
                    configureSolver(br);
                }

                // Solve Br
                br.Solve();

                if (visualize)
                {
                    Br.Vis.Show(br, Path.Combine(_outDir, String.Format("{0}-br-{1}.gv", testParams.Name, heroPos)));
                }

                // Verify the Br value and strategy

                Assert.AreEqual(testParams.ExpectedResult[heroPos], br.Value, testParams.Epsilon, "Wrong BR value");

                string error;
                Assert.IsTrue(VerifyAbsStrategy.Verify(br.Strategies[br.HeroPosition], br.HeroPosition, out error),
                              error);

                // Verify Br strategy has the expected value by running an independent GameValue algo on it.
                GameValue gv = new GameValue
                {
                    ActionTree = br.ActionTree,
                    ChanceTree = br.ChanceTree,
                    Strategies = br.Strategies
                };
                gv.Solve();
                Assert.AreEqual(testParams.ExpectedResult[heroPos], gv.Values[br.HeroPosition], testParams.Epsilon, "Wrong GameValue value");
            }
        }