Exemplo n.º 1
0
        public override ActionType GetBestAction(Game game)
        {
            ActionType a1 = primary.GetBestAction(game);
            ActionType a2 = secondary.GetBestAction(game);

            if (a1 != a2 && !IsDiff)
            {
                List<ActionEv> l1 = primary.GetActions(game);

                Diff = 0.0;

                if (l1 != null)
                {
                    for (int i = 0; i < l1.Count; i++)
                    {
                        if (l1[i].Action == a2)
                        {
                            Diff = l1[0].Ev - l1[i].Ev;
                            break;
                        }
                    }
                }

                IsDiff = true;

            }

            return a1;
        }
Exemplo n.º 2
0
 public override int Bet(Game game)
 {
     if (card_counter.CurrentEV > ev_cutoff)
         return max_bet;
     else
         return game.Rules.MinBet;
 }
        private CardSet GetSeenCards(Game game, bool showdown)
        {
            CardSet seen_cards = new CardSet();

            if (showdown)
            {
                foreach (Card card in game.DealerHand)
                {
                    seen_cards.Add(card);
                }
            }
            else
            {
                seen_cards.Add(game.DealerHand[0]);
            }

            foreach (Hand hand in game.PlayerHandSet)
            {
                if (hand.IsSplit()) continue;

                foreach (Card card in hand)
                {
                    seen_cards.Add(card);
                }
            }

            return seen_cards;
        }
Exemplo n.º 4
0
 public override int Bet(Game game)
 {
     if (cardCounter.CurrentEV > 0.0)
         return max_bet;
     else
         return game.Rules.MinBet;
 }
Exemplo n.º 5
0
        public static bool TakeInsurance(Game game)
        {
            int[] shoe = game.Shoe.Counts;
            shoe[game.DealerHand[1].PointValue - 1]++;

            double insurance_ev = Eval.InsuranceEv(game.Bet, shoe);

            if (insurance_ev >= 0.0)
                return true;
            else
                return false;
        }
Exemplo n.º 6
0
        public override int Bet(Game game)
        {
            // unseen tells how many cards still to come before shuffle
            //int unseen = 84 - (game.Rules.Decks * 52 - game.Shoe.Count);
            //int true_count = (int)Math.Round(((double)running_count / (double)unseen));

            if (card_counter.CurrentEV > ev_cutoff)
            {
                if (betting_system != null)
                {
                    return betting_system.BetSize(card_counter.CurrentEV, current_roll);
                }

                return max_bet;
            }
            else
                return game.Rules.MinBet;
        }
Exemplo n.º 7
0
        public static void Initialize(Game game)
        {
            HandSet playerHands = game.PlayerHandSet;

            List<Hand> active = new List<Hand>();

            active.Add(playerHands.ActiveHand);

            bool allBusted = true;
            int numBusted = 0;

            foreach (Hand hand in game.PlayerHandSet)
            {
                if (!hand.Finished)
                {
                    if (hand != playerHands.ActiveHand) active.Add(hand);
                }
                else
                {
                    if (hand.IsBust())
                    {
                        numBusted++;
                    }
                    else
                    {
                        if (!hand.IsSplit()) allBusted = false;
                    }
                }
            }

            SHand[] shands = new SHand[active.Count];
            for (int i = 0; i < shands.Length; i++)
            {
                shands[i] = new SHand(active[i]);
            }

            int[] shoe = game.Shoe.Counts;
            shoe[game.DealerHand[1].PointValue - 1]++;

            int upcard = game.DealerHand[0].PointValue;

            InitializeEvaluation(shands, shands.Length, allBusted, numBusted, upcard, shoe, game.Bet);
        }
Exemplo n.º 8
0
        public override ActionType GetBestAction(Game game)
        {
            ActionType a1 = primary.GetBestAction(game);
            ActionType a2 = secondary.GetBestAction(game);

            if (a1 != a2 && !IsDiff)
            {
                List<ActionEv> l1 = primary.GetActions(game);
                List<ActionEv> l2 = secondary.GetActions(game);

                int m = 0;
                if (l1 != null) m = l1.Count;
                if (l2 != null && l2.Count > m) m = l2.Count;

                Console.WriteLine("STRATEGY MISMATCH");
                Console.WriteLine();
                Console.WriteLine(game.ToString());

                Console.WriteLine(string.Format("{0,-25}    {1,-25}", primary.GetType(), secondary.GetType()));
                Console.WriteLine();

                Console.WriteLine(string.Format("{0,-25}    {1,-25}", a1, a2));
                Console.WriteLine();

                for (int i = 0; i < m; i++)
                {
                    ActionEv e1 = new ActionEv(), e2 = new ActionEv();

                    if (l1 != null && i < l1.Count) e1 = l1[i];
                    if (l2 != null && i < l2.Count) e2 = l2[i];

                    Console.WriteLine(string.Format("{0,-25}    {1,-25}", e1, e2));
                }

                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
            }

            return a1;
        }
        public override List<ActionEv> GetActions(Game game)
        {
            List<ActionType> allowed_actions = new List<ActionType>();

            if (game.IsValidAction(ActionType.Stand)) allowed_actions.Add(ActionType.Stand);
            if (game.IsValidAction(ActionType.Hit)) allowed_actions.Add(ActionType.Hit);
            if (game.IsValidAction(ActionType.Double)) allowed_actions.Add(ActionType.Double);
            if (game.IsValidAction(ActionType.Split)) allowed_actions.Add(ActionType.Split);
            if (game.IsValidAction(ActionType.Surrender)) allowed_actions.Add(ActionType.Surrender);

            CardSet some_cards = new CardSet();

            //Hand active_hand = game.PlayerHandSet.ActiveHand;

            List<CardSet> player_hands = new List<CardSet>();
            foreach (Hand hand in game.PlayerHandSet)
            {
                player_hands.Add(hand.Cards);
            }

            return agent.GetActions(GetSeenCards(game, false), game.DealerHand[0], player_hands.ToArray(), game.PlayerHandSet.ActiveIndex, allowed_actions);
        }
Exemplo n.º 10
0
        public override List<ActionEv> GetActions(Game game)
        {
            SuperEval.Initialize(game);

            int split_card = game.PlayerHandSet.ActiveHand[0].PointValue;

            List<ActionEv> actions = new List<ActionEv>();

            if (game.IsValidAction(ActionType.Stand))
                actions.Add(new ActionEv() { Action = ActionType.Stand, Ev = SuperEval.StandEv() });
            if (game.IsValidAction(ActionType.Hit))
                actions.Add(new ActionEv() { Action = ActionType.Hit, Ev = SuperEval.HitEv() });
            if (game.IsValidAction(ActionType.Double))
                actions.Add(new ActionEv() { Action = ActionType.Double, Ev = SuperEval.DoubleEv() });
            if (game.IsValidAction(ActionType.Surrender))
                actions.Add(new ActionEv() { Action = ActionType.Surrender, Ev = SuperEval.SurrenderEv() });
            if (game.IsValidAction(ActionType.Split))
                actions.Add(new ActionEv() { Action = ActionType.Split, Ev = SuperEval.SplitEv(split_card, game.Rules.Splits - game.SplitCount) });

            actions.Sort(delegate(ActionEv ae1, ActionEv ae2) { return ae2.Ev.CompareTo(ae1.Ev); });

            return actions;
        }
Exemplo n.º 11
0
        // should +ev in some cases, study
        // insurance should be taken when probability of dealer having
        // blackjack is greater than 1/3 (0.3333333%), i guess because
        // of how the payoff goes
        public override bool TakeInsurance(Game game)
        {
            // the number of seen tens
            int tens_count = card_counter[10];

            // check if newly dealt player hand has tens and add them to the count
            if (game.PlayerHandSet.ActiveHand[0].IsTenValue())
                tens_count++;
            if (game.PlayerHandSet.ActiveHand[1].IsTenValue())
                tens_count++;

            // switch to number of tens still in shoe
            tens_count = game.Rules.Decks * 4 * 4 - tens_count;

            // the +1 comes from the dealer's unknown which has been removed from the shoe
            if (((double)tens_count / (double)(game.Shoe.Count + 1)) + pp_multiplier * 0.0002 > (1.0 / 3.0))
                return true;

            return false;
        }
Exemplo n.º 12
0
        public override void Showdown(Game game)
        {
            // update count
            foreach (Card card in game.DealerHand)
            {
                card_counter.RemoveCard(card.PointValue);
            }

            foreach (Hand hand in game.PlayerHandSet)
            {
                if (hand.IsSplit())
                    continue;

                foreach (Card card in hand)
                {
                    card_counter.RemoveCard(card.PointValue);
                }
            }
        }
Exemplo n.º 13
0
 public override void ResetShoe(Game game)
 {
     card_counter.Reset();
 }
Exemplo n.º 14
0
 public override bool TakeInsurance(Game game)
 {
     return false;
 }
Exemplo n.º 15
0
        public override ActionType GetBestAction(Game game)
        {
            List<ActionEv> actions = GetActions(game);

            return actions[0].Action;
        }
Exemplo n.º 16
0
 // ask for a bet amount in the beginning of the round
 public override int Bet(Game game)
 {
     return primary.Bet(game);
 }
Exemplo n.º 17
0
        static void TestSuper()
        {
            Random random = new NPack.MersenneTwister();

            Rules rules = new Rules { Decks = 8, MinBet = 100, MaxBet = 20000, Splits = 3 };

            int max_bet = 5000;
            double pp_multiplier = 4.0;
            double ev_cutoff = 0.0015;

            SuperOptStrategy b = new SuperOptStrategy(max_bet, ev_cutoff, pp_multiplier);

            //PseudoOptStrategy b = new PseudoOptStrategy();

            Game game = new Game(rules, b, pp_multiplier, random);

            game.PlayerMoney = 0;
            double expected_money = (double)game.PlayerMoney;
            game.Bet = 100; // 1$

            int lowest = game.PlayerMoney, highest = game.PlayerMoney;
            int runs = 0;

            while (true)
            {
                double total_money = (game.PlayerMoney + pp_multiplier * game.PartyPoints) / 100.0;
                if (runs % 10000 == 0)
                {
                    Console.WriteLine("runs: " + runs + " win: " + (double)game.PlayerMoney / 100.0 + "$" + " pp: " + game.party_points);
                    Console.WriteLine("lowest: " + (double)lowest / 100.0 + "$" + " highest: " + (double)highest / 100.0 + "$");
                    Console.WriteLine("total: " + total_money + "$ | expected: " + expected_money / 100.0 + "$");
                    Console.WriteLine();
                }

                game.StartRound();
                game.DealRound();

                expected_money += b.ShoeEV() * game.Bet;

                if (game.PlayerMoney < lowest)
                    lowest = game.PlayerMoney;
                if (game.PlayerMoney > highest)
                    highest = game.PlayerMoney;

                runs++;
            }
        }
Exemplo n.º 18
0
 public override int Bet(Game game)
 {
     return game.Rules.MinBet;
 }
Exemplo n.º 19
0
 public override void ResetShoe(Game game)
 {
     primary.ResetShoe(game);
     secondary.ResetShoe(game);
 }
Exemplo n.º 20
0
        public override List<ActionEv> GetActions(Game game)
        {
            List<ActionEv> actions = new List<ActionEv>();

            int[] shoe = game.Shoe.Counts;
            /*int[] test = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            int test_count = 0;
            foreach (Card card in game.Shoe)
            {
                test[card.PointValue - 1]++;
                test_count++;
            }
            for (int i = 0; i < 10; i++)
            {
                if (test[i] != shoe[i])
                {
                    Console.Write(game.Shoe.Count + "| ");
                    for (int j = 0; j < 10; j++)
                        Console.Write(shoe[j] + " ");
                    Console.WriteLine();
                    Console.Write(test_count + "| ");
                    for (int j = 0; j < 10; j++)
                        Console.Write(test[j] + " ");
                    Console.WriteLine();

                    Console.ReadLine();
                    break;
                }
            }*/
            shoe[game.DealerHand[1].PointValue - 1]++;

            SHand shand;
            int soft_total = game.PlayerHandSet.ActiveHand.SoftTotal();
            if (soft_total <= 21 && game.PlayerHandSet.ActiveHand.HasAce())
            {
                shand.Total = soft_total;
                shand.Soft = true;
            }
            else
            {
                shand.Total = game.PlayerHandSet.ActiveHand.HardTotal();
                shand.Soft = false;
            }

            int upcard = game.DealerHand[0].PointValue;
            int split_card = game.PlayerHandSet.ActiveHand[0].PointValue;

            BjEval.Eval.CacheDealerProbs(upcard, shoe);
            /*
                        for (int i = 0; i < 10; i++)
                            Console.Write(shoe[i] + " ");
                        Console.WriteLine();

                        Console.WriteLine("SHand: " + shand.Total + " soft=" + shand.Soft);
                        */
            if (game.IsValidAction(ActionType.Stand))
                actions.Add(new ActionEv() { Action = ActionType.Stand, Ev = BjEval.Eval.StandEv(shand, upcard, shoe) });
            if (game.IsValidAction(ActionType.Hit))
                actions.Add(new ActionEv() { Action = ActionType.Hit, Ev = BjEval.Eval.HitEv(shand, upcard, shoe) });
            if (game.IsValidAction(ActionType.Double))
                actions.Add(new ActionEv() { Action = ActionType.Double, Ev = BjEval.Eval.DoubleEv(shand, upcard, max_bet, shoe) });
            if (game.IsValidAction(ActionType.Surrender))
                actions.Add(new ActionEv() { Action = ActionType.Surrender, Ev = BjEval.Eval.SurrenderEv() });
            if (game.IsValidAction(ActionType.Split))
                actions.Add(new ActionEv() { Action = ActionType.Split, Ev = BjEval.Eval.SplitEv(split_card, upcard, max_bet, game.Rules.Splits - game.SplitCount, shoe) });

            actions.Sort(delegate(ActionEv ae1, ActionEv ae2) { return ae2.Ev.CompareTo(ae1.Ev); });

            return actions;
        }
Exemplo n.º 21
0
 public override bool TakeInsurance(Game game)
 {
     return SuperEval.TakeInsurance(game);
 }
Exemplo n.º 22
0
        public override bool TakeInsurance(Game game)
        {
            int[] shoe = game.Shoe.Counts;
            shoe[game.DealerHand[1].PointValue - 1]++;

            double insurance_ev = Eval.InsuranceEv(max_bet, shoe);

            if (insurance_ev >= 0.0)
                return true;
            else
                return false;

            /*
            // remember the unseen dealt second dealer card, which is still reduced from shoe!
            // take into account
            int seen_tens = card_counts[9];
            if (game.PlayerHandSet.ActiveHand[0].IsTenValue())
                seen_tens++;
            if (game.PlayerHandSet.ActiveHand[1].IsTenValue())
                seen_tens++;

            // add the dealer's second dealt card to unknown count (+1)
            double bj_prob = (double)(8*4*4-seen_tens) / (double)(game.Shoe.Count + 1);
            double insurance_ev = 1.0*bj_prob-0.5*(1.0-bj_prob);

            // we take insurance
            if (insurance_ev >= 0.0)
                return true;
            else
                return false;*/
        }
Exemplo n.º 23
0
        public override ActionType GetBestAction(Game game)
        {
            /*Console.WriteLine("upcard: " + upcard + " hand: " + game.PlayerHandSet.ActiveHand);
            foreach (ActionEv ae in actions)
                Console.WriteLine(ae.Action + " " + ae.Ev);

            Console.ReadLine();*/

            List<ActionEv> actions = GetActions(game);

            return actions[0].Action;
        }
Exemplo n.º 24
0
        public override ActionType GetBestAction(Game game)
        {
            List<ActionEv> actions = Evaluate(game.Upcard(), game.PlayerHandSet.ActiveHand);

            foreach (ActionEv ae in actions)
            {
                if (game.IsValidAction(ae.Action))
                    return ae.Action;
                else
                {
                    //Console.WriteLine("OMGGG " + ae.Action);
                }
            }
            Console.WriteLine("BIG FUCCCCKKK");

            return ActionType.Split;
        }
Exemplo n.º 25
0
        public override bool TakeInsurance(Game game)
        {
            bool take1 = primary.TakeInsurance(game);
            bool take2 = secondary.TakeInsurance(game);

            if (take1 != take2)
            {
                Console.WriteLine("Insurance mismatch: " + take1 + " <> " + take2);
                Console.WriteLine(game.ToString());
            }

            return take1;
        }
Exemplo n.º 26
0
        /*
        static void PrintGameState(Game game)
        {
            double total_money = (game.PlayerMoney + pp_multiplier * game.PartyPoints) / 100.0;

            Console.WriteLine("runs: " + runs + " win: " + (double)game.PlayerMoney / 100.0 + "$" + " pp: " + game.party_points);
            Console.WriteLine("total: " + total_money + "$ | expected: " + expected_money / 100.0 + "$");
            Console.WriteLine();
        }*/
        static double TotalMoney(Game game)
        {
            double total_money = (game.PlayerMoney + game.TotalPartyPoints) / 100.0;

            return total_money;
        }
Exemplo n.º 27
0
        static void CompareStrategies2()
        {
            Random masterRandom = new NPack.MersenneTwister();

            Rules rules = new Rules { Decks = 8, MinBet = 100, MaxBet = 20000, Splits = 3 };

            int max_bet = 5000;
            double pp_multiplier = 4.0;
            double ev_cutoff = 0.0015;

            SuperOptStrategy b1 = new SuperOptStrategy(max_bet, ev_cutoff, pp_multiplier);
            OptStrategy b2 = new OptStrategy(max_bet, ev_cutoff, pp_multiplier);
            BasicStrategy b3 = new BasicStrategy(max_bet, ev_cutoff, pp_multiplier);

            Game game1 = new Game(rules, b1, pp_multiplier, new NPack.MersenneTwister());
            Game game2 = new Game(rules, b2, pp_multiplier, new NPack.MersenneTwister());
            Game game3 = new Game(rules, b3, pp_multiplier, new NPack.MersenneTwister());

            int runs = 0;
            double expected = 0;

            while (true)
            {
                if (runs % 10000 == 0)
                {
                    double total1 = TotalMoney(game1);
                    double total2 = TotalMoney(game2);
                    double total3 = TotalMoney(game3);

                    Console.WriteLine();
                    Console.WriteLine("Runs:           {0}", runs);
                    Console.WriteLine("Expected total: $ {0:0.00}", expected);
                    Console.WriteLine("SuperOpt total: $ {1:0.00} ({2:0.00} c/hand)", b1.GetType(), total1, total1 * 100.0 / (double)runs);
                    Console.WriteLine("Opt total:      $ {1:0.00} ({2:0.00} c/hand)", b2.GetType(), total2, total2 * 100.0 / (double)runs);
                    Console.WriteLine("Basic total:    $ {1:0.00} ({2:0.00} c/hand)", b3.GetType(), total3, total3 * 100.0 / (double)runs);

                    TextWriter writer = new StreamWriter("compare.txt", true);

                    writer.WriteLine(string.Format("{0} {1} {2} {3} {4}", runs, expected, total1, total2, total3));

                    writer.Close();
                }

                int seed = masterRandom.Next();

                game1.Random = new NPack.MersenneTwister(seed);
                game2.Random = new NPack.MersenneTwister(seed);
                game3.Random = new NPack.MersenneTwister(seed);

                game1.ResetShoe();
                game2.ResetShoe();
                game3.ResetShoe();

                int remove_count = masterRandom.Next(84);

                game1.RemoveCards(remove_count);
                game2.RemoveCards(remove_count);
                game3.RemoveCards(remove_count);

                expected += b1.ShoeEV() * b1.Bet(game1) / 100.0;

                game1.StartRound();
                game2.StartRound();
                game3.StartRound();

                game1.DealRound();
                game2.DealRound();
                game3.DealRound();

                runs++;
            }
        }
Exemplo n.º 28
0
        static void CompareStrategies()
        {
            Random masterRandom = new NPack.MersenneTwister();
            Random random1 = new NPack.MersenneTwister();
            Random random2 = new NPack.MersenneTwister();

            Rules rules = new Rules { Decks = 8, MinBet = 100, MaxBet = 20000, Splits = 3 };

            int max_bet = 5000;
            double pp_multiplier = 4.0;
            double ev_cutoff = 0.0015;

            DiffStrategy b1 = new DiffStrategy(
                new SuperOptStrategy(max_bet, ev_cutoff, pp_multiplier),
                new OptStrategy(max_bet, ev_cutoff, pp_multiplier)
                );
            OptStrategy b2 = new OptStrategy(max_bet, ev_cutoff, pp_multiplier);

            Game game1 = new Game(rules, b1, pp_multiplier, random1);
            Game game2 = new Game(rules, b2, pp_multiplier, random2);

            int runs = 0;
            double expected = 0;
            double expected_diff = 0;
            int diff_count = 0;

            while (true)
            {
                if (runs % 1000 == 0)
                {
                    double total1 = TotalMoney(game1);
                    double total2 = TotalMoney(game2);

                    Console.WriteLine();
                    Console.WriteLine("Runs:                {0}", runs);
                    Console.WriteLine("Expected total:      $ {0:0.00}", expected);
                    Console.WriteLine("SuperOpt total:      $ {1:0.00} ({2:0.00} c/hand)", b1.GetType(), total1, total1 * 100.0 / (double)runs);
                    Console.WriteLine("Opt total:           $ {1:0.00} ({2:0.00} c/hand)", b2.GetType(), total2, total2 * 100.0 / (double)runs);
                    Console.WriteLine("Different choices:   {0:0} ({1:0.00}%)", diff_count, 100.0 * diff_count / (double)runs);
                    Console.WriteLine("Difference:          $ {0:0.00}", total1 - total2);
                    Console.WriteLine("Expected difference: $ {0:0.00}", expected_diff);

                    TextWriter writer = new StreamWriter("compare.txt", true);

                    writer.WriteLine(string.Format("{0} {1} {2} {3}", runs, expected, TotalMoney(game1), TotalMoney(game2)));

                    writer.Close();
                }

                int seed = masterRandom.Next();

                game1.Random = new NPack.MersenneTwister(seed);
                game2.Random = new NPack.MersenneTwister(seed);

                game1.ResetShoe();
                game2.ResetShoe();

                int remove_count = masterRandom.Next(84);

                game1.RemoveCards(remove_count);
                game2.RemoveCards(remove_count);

                expected += b1.ShoeEV() * b1.Bet(game1) / 100.0;

                game1.StartRound();
                game2.StartRound();

                game1.DealRound();
                game2.DealRound();

                if (b1.IsDiff)
                {
                    expected_diff += game1.Bet * b1.Diff / 100.0;
                    diff_count++;
                    b1.IsDiff = false;
                }

                runs++;
            }
        }
Exemplo n.º 29
0
 // called when the round has ended
 public override void Showdown(Game game)
 {
     primary.Showdown(game);
     secondary.Showdown(game);
 }
Exemplo n.º 30
0
        static void MakeTestRun(int run_number, Random random, int targetRuns, double ev_cutoff, BettingSystem betting_system, ResetSystem reset)
        {
            Console.WriteLine(run_number + " - EV cutoff " + ev_cutoff + " " + betting_system);
            TextWriter deal_file = new StreamWriter(string.Format("expected{0}.txt", run_number));
            TextWriter roll_file = new StreamWriter(string.Format("roll{0}.txt", run_number));

            double pp_multiplier = 0;

            Rules rules = new Rules { Decks = 8, MinBet = 100, MaxBet = 20000, Splits = 3 };

            //OptStrategy b = new OptStrategy(10000, ev_cutoff, pp_multiplier);
            BasicStrategy b = new BasicStrategy(20000, ev_cutoff, pp_multiplier, betting_system);

            Game game = new Game(rules, b, pp_multiplier, random);

            int start_roll = 20000 * 100;
            //game.PlayerMoney = 10000000; // 100000$
            game.PlayerMoney = start_roll;
            double expected_money = (double)game.PlayerMoney;
            game.Bet = 100; // 1$

            double lowest = TotalMoney(game), highest = TotalMoney(game);
            int runs = 0;

            double total_big_bet_ev = 0;
            double total_big_bet = 0;
            int num_big_bets = 0;
            int resets = 0;

            int reset_counter = 0;

            bool written_200k = false;

            while (true)
            {
                double total_money = TotalMoney(game);

                if (total_money < lowest) lowest = total_money;
                if (total_money > highest) highest = total_money;

                if (runs % 5000 == 0)
                {
                    Console.WriteLine(runs + " " + (double)game.PlayerMoney / 100.0 + "$" + " pp: " + game.PartyPoints + " expected: " + expected_money / 100.0 + "$");
                    Console.WriteLine("lowest: " + (double)lowest + "$" + " highest: " + (double)highest + "$");
                    Console.WriteLine("Total: ${0}", game.PlayerMoney/100.0);
                    Console.WriteLine("Expected: ${0}", expected_money/100.0);
                    /*Console.WriteLine("Average big bet: {0:0.00} ({1:0.0000})",
                        (total_big_bet / 100.0) / num_big_bets,
                        (total_big_bet_ev / 100.0) / num_big_bets);
                    Console.WriteLine("Resets {0} ({1:0.000}%)", resets, resets / (double)runs);
                    */
                    Console.WriteLine();
                }

                if (game.PlayerMoney <= 0)
                {
                    deal_file.WriteLine(expected_money / 100.0);
                    roll_file.WriteLine(game.PlayerMoney / 100.0);

                    Write200kResult(0);
                    WriteFinalResult(0);

                    break;
                }

                if (runs % 1000 == 0)
                {
                    //file.WriteLine(string.Format("{0} {1} {2} {3} {4} {5}", runs, game.PlayerMoney / 100.0, game.PartyPoints, total_money, lowest, highest));

                    deal_file.WriteLine(expected_money / 100.0);
                    roll_file.WriteLine(game.PlayerMoney / 100.0);

                    if (runs >= targetRuns)
                    {
                        if (!written_200k)
                        {
                            Write200kResult(game.PlayerMoney / 100.0);
                            written_200k = true;
                        }

                        if (game.PlayerMoney >= start_roll)
                        {
                            WriteFinalResult(game.PlayerMoney / 100.0);
                            break;
                        }
                    }

                    //if (game.party_points >= 20000) break;
                }

                if (reset_counter > 0)
                {
                    reset_counter--;
                    runs++;
                    continue;
                }
                if (reset!=null && reset.Reset(52 * game.Rules.Decks - game.Shoe.Count, b.ShoeEV()))
                {
                    resets++;
                    runs++;
                    reset_counter = 1;
                    game.ResetShoe();

                    continue;
                }

                b.CurrentRoll = game.PlayerMoney;

                Shoe shoe = new Shoe(8);
                shoe.Clear();
                shoe.Add(game.Shoe);

                game.StartRound();
                game.DealRound();

                Card p1 = game.PlayerHandSet[0][0],
                     p2 = game.PlayerHandSet[0][1],
                     d = game.DealerHand[0];

                shoe.Remove(p1);
                shoe.Remove(p2);
                shoe.Remove(d);

                BjEval.Eval.CacheDealerProbs(d.PointValue, shoe.ToArray());
                double deal_ev = BjEval.Eval.DealEv(
                    p1.PointValue,
                    p2.PointValue,
                    d.PointValue,
                    shoe.ToArray(),
                    game.Bet);

                //Console.WriteLine("EV: {0} {1} {2} {3} {4}", p1.PointValue, p2.PointValue, d.PointValue, shoe.CardCount, deal_ev);

                expected_money += deal_ev * game.Bet;

                if (game.Bet > 100)
                {
                    total_big_bet += game.Bet;
                    total_big_bet_ev += game.Bet * deal_ev;
                    num_big_bets++;
                }

                runs++;
            }

            deal_file.Close();
            roll_file.Close();

            b.Stop();
        }