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