/// <summary> /// Given S and B = B(S), verify that B is the best strategy against S. /// Procedure: Verify EV(B', S) is less than EV(B, S) for all other strategies B'. /// </summary> public static void B_Test(PocketRoot root) { number EV; // Calculate Strategy B = B(S) EV = root.BestAgainstS(); // Calculate EV(B', S) for many B' double Min = double.MaxValue; for (int k = 0; k < 10000; k++) { // Pure passive //root.Process(Node.VarB, (n, i) => (number)0); // Pure aggressive //root.Process(Node.VarB, (n, i) => (number)1); // Totally randomize //root.Process(Node.VarB, (n, i) => (number)(Tools.Rnd.NextDouble())); // Random perturbation //root.Process(Node.VarB, (n, i) => n.B[i] + (number)((Tools.Rnd.NextDouble() - .5f) * .1f)); // Random raise root.Process(Node.VarB, (n, i) => n.B[i] + (number)(Tools.Rnd.NextDouble() > .85 ? 1 : 0)); // Random fold //root.Process(Node.VarB, (n, i) => n.B[i] + (number)(Tools.Rnd.NextDouble() > .99 ? -1 : 0)); // Full simulation //number ModdedEV = Simulation(Node.VarB, Node.VarS, root); // Monte Carlo simulation var game = new Game(new StrategyPlayer(Node.VarB), new StrategyPlayer(Node.VarS), Seed: 0); float ModdedEV = (float)game.Round(4999999); Tools.LogPrint("Monte Carlo Simulation EV = {0}", ModdedEV); Min = Math.Min((double)Min, (double)EV - (double)ModdedEV); Tools.LogPrint("Difference = {0}, min = {1}", (double)EV - (double)ModdedEV, Min); } }
public static void Combine_Test(PocketRoot root) { root.Process(Node.VarS, (node, i) => (number)Math.Cos(i)); root.Process(Node.VarB, (node, i) => (number)Math.Sin(i)); root.Process(Node.VarHold, (node, i) => (number)Math.Tan(i)); number h_vs_s = Tests.Simulation(Node.VarHold, Node.VarS, root); number h_vs_b = Tests.Simulation(Node.VarHold, Node.VarB, root); root.CombineStrats((number).5, (number).5); //root.NaiveCombine(Node.VarS, .5, Node.VarB, .5, Node.VarS); number h_vs_mix = Tests.Simulation(Node.VarHold, Node.VarS, root); Tools.LogPrint("vs s = {0}", h_vs_s); Tools.LogPrint("vs b = {0}", h_vs_b); Tools.LogPrint("vs mix = {0}", h_vs_mix); Tools.LogPrint("should = {0}", (number).5 * (h_vs_s + h_vs_b)); }
public static void SaveLoad_Test(PocketRoot root) { Stopwatch stopwatch; root.Process(i => (number)Math.Cos(i)); var hash_saved = root.Hash(Node.VarS); stopwatch = Stopwatch.StartNew(); var file = root.FullSave(); stopwatch.Stop(); Tools.LogPrint("Save done! Time = {0}", stopwatch.Elapsed.TotalSeconds); root.Process(i => 0); var hash_cleared = root.Hash(Node.VarS); stopwatch = Stopwatch.StartNew(); root.FullLoad(file); var hash_loaded = root.Hash(Node.VarS); stopwatch.Stop(); Tools.LogPrint("Load done! Time = {0}", stopwatch.Elapsed.TotalSeconds); Tools.LogPrint("Hash comparison {0} vs {1}. (Sanity check : {2})", hash_saved, hash_loaded, hash_cleared); }
public static number _Simulation(Var S1, Var S2, PocketRoot root) { number EV = 0, TotalMass = 0; for (int p1 = 0; p1 < Pocket.N; p1++) { number PocketEV = 0, PocketTotalMass = 0; for (int p2 = 0; p2 < Pocket.N; p2++) { if (Pocket.Pockets[p1].Overlaps(Pocket.Pockets[p2])) continue; for (int flop = 0; flop < Flop.N; flop++) { if (Pocket.Pockets[p1].Overlaps(Flop.Flops[flop])) continue; if (Pocket.Pockets[p2].Overlaps(Flop.Flops[flop])) continue; for (int turn = 0; turn < Card.N; turn++) { if (Flop.Flops[flop].Contains(turn)) continue; if (Pocket.Pockets[p1].Contains(turn)) continue; if (Pocket.Pockets[p2].Contains(turn)) continue; for (int river = 0; river < Card.N; river++) { if (turn == river) continue; if (Flop.Flops[flop].Contains(river)) continue; if (Pocket.Pockets[p1].Contains(river)) continue; if (Pocket.Pockets[p2].Contains(river)) continue; number ev; if (DerivedSetup.SuitReduce) { // Map all of our cards (community and pockets) using the flop map // (because we are using a suit reduced data structure). var f = Flop.Flops[flop]; int _flop = Flop.IndexOf(f.Representative); int _turn = f.CardMap[turn]; int _river = f.CardMap[river]; int _p1 = f.PocketMap[p1]; int _p2 = f.PocketMap[p2]; ev = root.Simulate(S1, S2, _p1, _p2, _flop, _turn, _river); } else { ev = root.Simulate(S1, S2, p1, p2, flop, turn, river); } TotalMass += 1; EV += ev; PocketTotalMass += 1; PocketEV += ev; } } } } //Tools.LogPrint(" EV(p1 = {0}) = {1}", p1, PocketEV / PocketTotalMass); //Tools.LogPrint(" EV(p1 = {0}) = {1}", Pocket.Pockets[p1], PocketEV / PocketTotalMass); } Assert.IsNum(EV / TotalMass); return EV / TotalMass; }
public static void TestBestAgainstOtherStrategies(PocketRoot root) { number EV; Assert.That(Node.MakeHold); root.Process(Node.VarHold, (n, j) => n.B[j] + (number).01); EV = Simulation(Node.VarHold, Node.VarS, root); Tools.LogPrint("Simulated EV = {0} (perturbed)", EV); root.Process(Node.VarHold, (n, j) => (number).5); EV = Simulation(Node.VarS, Node.VarHold, root); Tools.LogPrint("Simulated EV = {0} (idiot)", EV); root.Process(Node.VarHold, (n, j) => 1); EV = Simulation(Node.VarS, Node.VarHold, root); Tools.LogPrint("Simulated EV = {0} (aggressive)", EV); root.Process(Node.VarHold, (n, j) => 0); EV = Simulation(Node.VarS, Node.VarHold, root); Tools.LogPrint("Simulated EV = {0} (passive)", EV); }
public static number Simulation(Var S1, Var S2, PocketRoot root) { if (BetNode.SimultaneousBetting) { return _Simulation(S1, S2, root); } else { number EV1 = _Simulation(S1, S2, root); number EV2 = -_Simulation(S2, S1, root); number TotalEV = ((number).5) * (EV1 + EV2); Tools.LogPrint("EV = {0} : {1} -> {2}", EV1, EV2, TotalEV); return TotalEV; } }
private static void Initialize() { Tools.LogPrint("Suits x Vals : {0} x {1} = {2} card deck", Card.Suits, Card.Vals, Card.Suits * Card.Vals); Tools.LogPrint("Flop reduced = {0}", DerivedSetup.SuitReduce); Tools.LogPrint("Precision = {0}", #if SINGLE "single"); #elif DOUBLE "double"); #else "decimal"); #endif Tools.LogPrint(); Counting.Test(); Pocket.InitPockets(); Game.InitPocketLookup(); Flop.InitFlops(); Game.InitFlopLookup(); //Node.InitPocketData(); CommunityRoot.Root = new CommunityRoot(); Tools.LogPrint("Lookups initialized."); #if DEBUG Tools.LogPrint("#(Flops) = {0}", Flop.Flops.Count); Tools.LogPrint("#(Unique Flops) = {0}", Flop.Flops.Count(fl => fl.IsRepresentative())); Tools.LogPrint("#(FlopCommunites) = {0}", FlopCommunity.InstanceCount); Tools.LogPrint("#(TurnCommunity) = {0}", TurnCommunity.InstanceCount); Tools.LogPrint("#(RiverCommunity) = {0}", RiverCommunity.InstanceCount); Tools.LogPrint(); #endif PocketRoot.Root = GameRoot = new PocketRoot(); Tools.LogPrint("Data structure initialized."); #if DEBUG Tools.LogPrint("#(FlopRoots) = {0}", FlopRoot.InstanceCount); Tools.LogPrint("#(PocketDatas) = {0}", PocketData.InstanceCount); Tools.LogPrint("#(BetNodes) = {0}", BetNode.InstanceCount); Tools.LogPrint("#(ShowdownNodes) = {0}", ShowdownNode.InstanceCount); Tools.LogPrint(); #endif }