/// <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); }
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_Verify() { string [] strFiles = new string[] { "eq-KunhPoker-0-s.xml", "eq-KunhPoker-1-s.xml" }; GameDefinition gd = XmlSerializerExt.Deserialize <GameDefinition>( Props.Global.Expand("${bds.DataDir}ai.pkr.metastrategy/kuhn.gamedef.xml")); StrategyTree[] st = new StrategyTree[gd.MinPlayers]; for (int i = 0; i < gd.MinPlayers; ++i) { string strPath = Path.Combine(_testResDir, strFiles[i]); st[i] = XmlToStrategyTree.Convert(strPath, gd.DeckDescr); } ActionTree at = CreateActionTreeByGameDef.Create(gd); ChanceTree ct = CreateChanceTreeByGameDef.Create(gd); string error; Assert.IsTrue(VerifyEq.Verify(at, ct, st, 0.0000001, out error), error); // Now modify the strategy (with a J: not always fold to a r) st[1].Nodes[10].Probab = 0.5; st[1].Nodes[11].Probab = 0.5; Assert.IsFalse(VerifyEq.Verify(at, ct, st, 0.0000001, out error)); }
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); }