예제 #1
0
        // this method will determine the amount to bet on the next
        // hand
        public virtual void DetermineBet(StatisticsMgr stats)
        {
            int bet = Bet;

            // likelihood of a win or lose streak greater than 1 is 66%.  As the
            // streak continues, the chance of another win/lose inside the streak
            // is about 40%.
            if (stats.WinStreak == 1)
            {
                bet = 2000;
            }
            else if (stats.WinStreak == 2)
            {
                bet = 1000;
            }
            else if (stats.WinStreak > 2)
            {
                bet -= (int)(bet * .42);
            }
            else if (stats.LosingStreak == 1)
            {
                bet = 100;
            }
            else if (stats.LosingStreak > 2)
            {
                bet += (int)(bet * .42);
            }

            bet = Math.Max(bet, 100);
            bet = Math.Min(bet, 100000);
            Bet = bet;
        }
예제 #2
0
        static void Main(string[] args)
        {
            StatisticsMgr stats = new StatisticsMgr();

            // turning off a couple of time-consuming features
            stats.Features.HasCalculateWinSequenceLengths = false;
            stats.Features.HasTrackLastFewCards = false;

            PlayModifiedBetting play = new PlayModifiedBetting();

            play.PlayHands(5000000, stats);

            stats.CalculateDerivedStatistics();
            stats.ReportStatistics();
        }
예제 #3
0
        // this is logic to determine if the player should split the hand
        public virtual bool DetermineSplit(HouseHand dealerHand, Hand playerHand, StatisticsMgr stats)
        {
            // don't do anything special if it's not likely to work
            if (
                stats.WinStreak > 4
                ||
                (stats.LosingStreak > 0 && stats.LosingStreak < 3) ||
                !playerHand.IsSplittable
                )
            {
                return(false);
            }

            // split a pair of aces
            if (playerHand.SumCards == 2)
            {
                return(true);
            }

            // avoid pair of 4s, pair of 5s
            if (
                // more likely to have 18 or 20 in these cases, so don't  split
                (
                    stats.TensIndex < 5 &&
                    (playerHand.SumCards == 8 || playerHand.SumCards == 10)
                )
                )
            {
                return(false);
            }

            if (Math.Min(dealerHand.CardShowing.Face, (byte)10) >= playerHand.Cards[0].Face)
            {
                return(false);
            }

            if (dealerHand.CardShowing.Face == 1)
            {
                return(false);
            }

            return(true);
        }
예제 #4
0
        public Dealer(StatisticsMgr stats)
        {
            Statistics = stats;
            _shoe      = new List <Card>();

            for (int i = 0; i < 6; i++)
            {
                for (byte x = 1; x < 14; x++)
                {
                    _shoe.Add(new Card(0, x));
                    _shoe.Add(new Card(1, x));
                    _shoe.Add(new Card(2, x));
                    _shoe.Add(new Card(3, x));
                }
            }

            _nextshoe = _shoe.ToArray();
            Extensions.Shuffle(_shoe);
        }
예제 #5
0
        public override void PlayHands(int iterations, StatisticsMgr stats)
        {
            Dealer dlr = new Dealer(stats);

            while (--iterations >= 0)
            {
                var hands = dlr.DealHands(new NaiveHand());

                hands.Item1.Hit(dlr);

                if (!hands.Item1.IsBust)
                {
                    hands.Item2.Hit(dlr);
                }

                if (hands.Item1.IsBust)
                {
                    stats.Losses++;
                }
                else if (hands.Item1.IsBlackJack && !hands.Item2.IsBlackJack)
                {
                    stats.Wins++;
                }
                else if (hands.Item2.IsBust)
                {
                    stats.Wins++;
                    stats.WinsByBust++;
                }
                else if (hands.Item1.SumCards > hands.Item2.SumCards)
                {
                    stats.Wins++;
                }
                else if (hands.Item2.SumCards > hands.Item1.SumCards)
                {
                    stats.Losses++;
                }
            }
        }
예제 #6
0
        // return true = should doubledown
        public virtual bool DetermineDoubleDown(HouseHand dealerHand, Hand playerHand, StatisticsMgr stats)
        {
            if (stats.WinStreak > 3 ||
                !playerHand.IsDoubleDownable)
            {
                // just don't
                return(false);
            }

            // if the dealer's shown card is not a 10 pt or ace, continue
            if (dealerHand.CardShowing.Face == 1 ||
                (dealerHand.CardShowing.Face > 9 && stats.TensIndex > 2))
            {
                return(false);
            }

            if (playerHand.HasAce && playerHand.SumCards < 14 && stats.TensIndex > 4)
            {
                return(true);
            }

            // if the card sum is between 9 and 12
            if (playerHand.SumCards < 12 &&
                playerHand.SumCards >= 9)
            {
                if (dealerHand.CardShowing.Face < 9)
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #7
0
 public virtual void PlayHands(int iterations, StatisticsMgr stats)
 {
 }
        // this method will play a series of hands, using a specific behavior
        public override void PlayHands(int iterations, StatisticsMgr stats)
        {
            Dealer          dlr     = new Dealer(stats);
            BettingBehavior betting = new BettingBehavior();

            // this is done like this to avoid re-allocating hands
            ModifiedBettingHand bettingHand = new ModifiedBettingHand();

            // doing this here to avoid allocations
            Hand[] playerHands = new Hand[2];

            while (--iterations >= 0)
            {
                betting.DetermineBet(stats);

                bettingHand.Reset();

                dlr.DealHands(bettingHand);

                // tweak the stats before the doubledown bet
                foreach (Card playerCard in dlr.PlayerHand.Cards)
                {
                    // this records the card displayed, emulating a user that is
                    // counting the last 12 cards or so.  Counting more cards would
                    // result in better performance.
                    stats.DiscardCard(playerCard);
                }
                stats.DiscardCard(dlr.DealerHand.Cards[1]);
                stats.BlackJacks += (dlr.PlayerHand.IsBlackJack) ? 1 : 0;

                // apply the hit logic to the player's hand.  This will also
                // split if necessary
                dlr.PlayerHand.Hit(dlr, betting);

                // dealer only hits if the player doesn't go bust
                if (!dlr.PlayerHand.IsBust ||
                    (dlr.PlayerSplitHand != null && !dlr.PlayerSplitHand.IsBust))
                {
                    dlr.DealerHand.Hit(dlr);
                }

                if (iterations % 1000000 == 0)
                {
                    Debug.WriteLine("\tProfits:  {0}  Bet: {1}", stats.Profit, betting.Bet);
                }


                playerHands[0] = dlr.PlayerHand;
                if (null != dlr.PlayerSplitHand)
                {
                    // if the hand was split, add the split hand results as well
                    playerHands[1] = dlr.PlayerSplitHand;
                }
                else
                {
                    playerHands[1] = null;
                }

                foreach (var playerHand in playerHands)
                {
                    if (null == playerHand)
                    {
                        continue;
                    }

                    // keep track of the total amount bet since it's dynamic
                    stats.CumulativeBet += playerHand.Bet;

                    if (playerHand.IsBust)
                    {
                        stats.Profit -= playerHand.Bet;
                        stats.RecordLoss();
                        stats.LossesByBust++;
                        if (playerHand.IsDoubledDown)
                        {
                            stats.LossesByDoubleDown++;
                        }
                        if (playerHand.IsSplit)
                        {
                            stats.LossesBySplit++;
                        }
                    }
                    else if (playerHand.IsBlackJack && !dlr.DealerHand.IsBlackJack)
                    {
                        //  blackjack pays 3 to 2
                        stats.Profit += (int)(1.5 * playerHand.Bet);
                        stats.RecordWin(iterations);
                        if (playerHand.IsSplit)
                        {
                            stats.WinsBySplit++;
                        }
                    }
                    else if (!playerHand.IsBlackJack && dlr.DealerHand.IsBlackJack)
                    {
                        stats.Profit -= playerHand.Bet;
                        stats.RecordLoss();
                        if (playerHand.IsDoubledDown)
                        {
                            stats.LossesByDoubleDown++;
                        }
                        if (playerHand.IsSplit)
                        {
                            stats.LossesBySplit++;
                        }
                    }
                    else if (dlr.DealerHand.IsBust)
                    {
                        stats.Profit += playerHand.Bet;
                        stats.RecordWin(iterations);
                        stats.WinsByBust++;
                        if (playerHand.IsDoubledDown)
                        {
                            stats.WinsByDoubleDown++;
                        }
                        if (playerHand.IsSplit)
                        {
                            stats.WinsBySplit++;
                        }
                    }
                    else if (playerHand.SumCards > dlr.DealerHand.SumCards)
                    {
                        stats.Profit += playerHand.Bet;
                        stats.RecordWin(iterations);
                        if (playerHand.IsDoubledDown)
                        {
                            stats.WinsByDoubleDown++;
                        }
                        if (playerHand.IsSplit)
                        {
                            stats.WinsBySplit++;
                        }
                    }
                    else if (dlr.DealerHand.SumCards > playerHand.SumCards)
                    {
                        stats.Profit -= playerHand.Bet;
                        stats.RecordLoss();
                        if (playerHand.IsDoubledDown)
                        {
                            stats.LossesByDoubleDown++;
                        }
                        if (playerHand.IsSplit)
                        {
                            stats.LossesBySplit++;
                        }
                    }
                }

                // now keep track of the last few discarded cards from both players
                int index = 0;
                foreach (Card dlrCard in dlr.DealerHand.Cards)
                {
                    // skip the card that was initially shown because it was counted
                    // earlier
                    if (index++ == 1)
                    {
                        continue;
                    }

                    stats.DiscardCard(dlrCard);
                }
            }
        }