/// <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); }
/// <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)); } }
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); }
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); }
/// <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"); } }
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)); } } }
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); }
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); }
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"); } }