Exemple #1
0
 public void InitialDealDealer(CardShoe shoe)
 {
     List<int> upCard = shoe.DealCard(1);
     List<int> holeCard = shoe.DealCard(1, false);
     Cards.AddRange(upCard);
     Cards.AddRange(holeCard);
 }
Exemple #2
0
        public BetHandResult BetHand(double betSize, CardShoe shoe)
        {
            // save the True Count before bet
            int trueCountBeforeBet = 0;
            if (shoe.Count != null)
            {
                trueCountBeforeBet = shoe.Count.TrueCount;
            }

            // initial deal
            Hand handPlayer = new Hand();
            handPlayer.InitialDealPlayer(shoe);
            Hand handDealer = new Hand();
            handDealer.InitialDealDealer(shoe);
            int numberOfSplits = 0;

            // play hand
            var betHandResult = new BetHandResult();
            betHandResult.TrueCountBeforeBet = trueCountBeforeBet;
            betHandResult.BetSize = betSize;
            PlayHandOutcome playHandOutcome = PlayHand(handPlayer, handDealer, betSize, shoe, ref numberOfSplits);

            // update bet hand results
            betHandResult.NumberOfSplits = numberOfSplits;
            betHandResult.BetTotal = playHandOutcome.BetTotal;
            var payoff = PayoffHand(playHandOutcome, handDealer, shoe);
            betHandResult.Payoff = payoff;

            // update count with the hole card revealed
            shoe.Count.Update(handDealer.Cards[1], shoe.LeftPacksCount);

            return betHandResult;
        }
Exemple #3
0
        public static void CreateShoe()
        {
            var sampleConfiguration = new Configuration
            {
                GameRules = new GameRules
                {
                    DoubleAfterSplit = true,
                    MaxNumberOfSplits = 10
                },

                SimulationParameters = new SimulationParameters
                {
                    UnitBetSizeBase = 5,
                    TotalPacksCount = 4,
                    InitialWealth = 10000,
                    BetSizeTrueCountScale = new List<TrueCountBet>
                    {
                       new TrueCountBet
                       {
                           BetRatio = 0.2,
                           TrueCount = 10
                       },
                       new TrueCountBet
                       {
                           BetRatio = 0.1,
                           TrueCount = 20
                       },
                       new TrueCountBet
                       {
                           BetRatio = 0.3,
                           TrueCount = 30
                       }
                    },
                    CountSystem = new List<CountSystemBit>
                    {
                       new CountSystemBit
                       {
                           Card = 1,
                           Count = -1
                       },
                       new CountSystemBit
                       {
                           Card = 2,
                           Count = 1
                       },
                       new CountSystemBit
                       {
                           Card = 3,
                           Count = 1
                       },
                       new CountSystemBit
                       {
                           Card = 4,
                           Count = 1
                       },
                       new CountSystemBit
                       {
                           Card = 5,
                           Count = 1
                       },
                       new CountSystemBit
                       {
                           Card = 6,
                           Count = 1
                       },
                       new CountSystemBit
                       {
                           Card = 7,
                           Count = 0
                       },
                       new CountSystemBit
                       {
                           Card = 8,
                           Count = 0
                       },
                       new CountSystemBit
                       {
                           Card = 9,
                           Count = 0
                       },
                       new CountSystemBit
                       {
                           Card = 10,
                           Count = -1
                       },
                       new CountSystemBit
                       {
                           Card = 11,
                           Count = 1
                       },
                       new CountSystemBit
                       {
                           Card = 12,
                           Count = 1
                       },
                       new CountSystemBit
                       {
                           Card = 13,
                           Count = 1
                       }
                    }
                }
            };

            CardShoe shoe = new CardShoe(sampleConfiguration, new Random());
            var cards = shoe.DealCard(2);
        }
Exemple #4
0
 public void InitialDealPlayer(CardShoe shoe)
 {
     List<int> hitCards = shoe.DealCard(2);
     Cards.AddRange(hitCards);
 }
Exemple #5
0
 public void Hit(CardShoe shoe)
 {
     List<int> hitCards = shoe.DealCard(1);
     Cards.AddRange(hitCards);
 }
Exemple #6
0
        public List<Hand> Split(CardShoe shoe)
        {
            if (!IsPair())
            {
                return null;
            }

            var splitHands = new List<Hand>();
            var hand = new Hand(Cards[0], BetSize);
            hand.Hit(shoe);
            splitHands.Add(hand);
            hand = new Hand(Cards[1], BetSize);
            hand.Hit(shoe);
            splitHands.Add(hand);

            return splitHands;
        }
Exemple #7
0
        public void Run(ProgressBarSetValue progressBarSetValue = null)
        {
            var simulationCount = Configuration.SimulationParameters.SimulationCount;
            var shoe = new CardShoe(Configuration, Random);
            double betSize;
            BetHandResult betHandResult;
            int indexFinished = 0;
            int ratioFinishedPrevious = 0;
            int ratioFinishedRound;
            double ratioFinished;
            double wealth;

            var stopwatch = Stopwatch.StartNew();
            var resultsUtils = new ResultsUtils(Configuration);

            var message = String.Format("Simulating {0} of played hands...", simulationCount);
            TraceWrapper.LogInformation(message);
            var penetrationThreshold = Configuration.SimulationParameters.PenetrationThreshold;
            for (long i = 0; i < simulationCount; i++)
            {
                wealth = resultsUtils.Statistics.WealthStatistics.WealthValue;
                betSize = GetBetSize(wealth, shoe);

                betHandResult = BetHand(betSize, shoe);

                resultsUtils.Update(betHandResult);

                if (shoe.Penetration > penetrationThreshold)
                {
                    shoe.Reinitiate();
                }

                ratioFinished = (double)i / (double)simulationCount * 100;
                ratioFinishedRound = (int)Math.Round(ratioFinished);
                if (progressBarSetValue != null && ratioFinishedRound > ratioFinishedPrevious)
                {
                    progressBarSetValue(ratioFinishedRound);
                    ratioFinishedPrevious = ratioFinishedRound;
                }
                if ((int)Math.Truncate(ratioFinished / 5.0) > indexFinished)
                {
                    indexFinished++;
                    TraceWrapper.LogInformation("Blackjack simulation: Finished {0}% in {1}.",
                        ratioFinished, stopwatch.Elapsed);
                }
            }

            resultsUtils.FinalizeAll();

            stopwatch.Stop();
            TraceWrapper.LogInformation("Blackjack simulation: FINISHED in {0}.", stopwatch.Elapsed);

            var outputFolder = Configuration.SimulationParameters.OutputFolderSpecific;
            var filePath = Path.Combine(outputFolder, "BlackjackSim_Configuration.xml");
            XmlUtils.SerializeToFile<Configuration>(Configuration, filePath);
        }
Exemple #8
0
        public PlayHandOutcome PlayHand(Hand handPlayer, Hand handDealer, double betSize, CardShoe shoe,
            ref int numberOfSplits)
        {
            int trueCount = 0;
            if (shoe.Count != null)
            {
                trueCount = shoe.Count.TrueCount;
            }
            bool surrenderDone = false;
            bool splitDone = numberOfSplits > 0;
            var playHandOutcome = new PlayHandOutcome();
            handPlayer.BetSize = betSize;

            // consider insurance first
            double insuranceBet = 0;
            if (Configuration.GameRules.InsuranceAllowed && handDealer.IsAce(0) && !splitDone)
            {
                bool takeInsurance = Strategy.GetInsuranceDecision(handDealer, trueCount);
                if (takeInsurance)
                {
                    insuranceBet = 0.5 * betSize;
                }
            }

            // player's hand play
            bool continuePlay = true;
            while (handPlayer.Value() < 21 && !surrenderDone && !handDealer.IsBlackjack() && continuePlay)
            {
                Permits permits = new Permits(handPlayer, Configuration, numberOfSplits);
                if (shoe.Count != null)
                {
                    trueCount = shoe.Count.TrueCount;
                }
                StrategyDecisionType decision = Strategy.GetDecision(handPlayer, handDealer, trueCount, permits, Random);

                switch (decision)
                {
                    case StrategyDecisionType.STAND:
                        continuePlay = false;
                        break;

                    case StrategyDecisionType.HIT:
                        handPlayer.Hit(shoe);
                        break;

                    case StrategyDecisionType.DOUBLE:
                        handPlayer.DoubleDone = true;
                        betSize *= 2;
                        handPlayer.Hit(shoe);
                        continuePlay = false;
                        break;

                    case StrategyDecisionType.SPLIT:
                        var splitHands = handPlayer.Split(shoe);
                        numberOfSplits++;

                        var playHandOutcomeSplit1 = PlayHand(splitHands[1], handDealer, betSize, shoe, ref numberOfSplits);
                        var playHandOutcomeSplit2 = PlayHand(splitHands[0], handDealer, betSize, shoe, ref numberOfSplits);

                        playHandOutcome.AddHands(playHandOutcomeSplit1.HandsPlayed);
                        playHandOutcome.AddHands(playHandOutcomeSplit2.HandsPlayed);

                        double betTotal = playHandOutcomeSplit1.BetTotal + playHandOutcomeSplit2.BetTotal +
                            insuranceBet;

                        playHandOutcome.BetTotal = betTotal;
                        playHandOutcome.InsuranceBet = insuranceBet;

                        return playHandOutcome;

                    case StrategyDecisionType.SURRENDER:
                        surrenderDone = true;
                        break;

                    case StrategyDecisionType.NA:
                        throw new Exception("Strategy decision was not determined!");
                }
            }

            // return outcome
            playHandOutcome.HandsPlayed.Add(handPlayer);
            playHandOutcome.BetTotal = betSize + insuranceBet;
            playHandOutcome.InsuranceBet = insuranceBet;
            playHandOutcome.SurrenderDone = surrenderDone;

            return playHandOutcome;
        }
Exemple #9
0
        public double PayoffHand(PlayHandOutcome playHandOutcome, Hand handDealer, CardShoe shoe)
        {
            var insurancePayoff = PayoffInsurance(handDealer, playHandOutcome.InsuranceBet);

            int handsTotal = playHandOutcome.HandsPlayed.Count;
            bool splitDone = handsTotal > 1;
            if (playHandOutcome.SurrenderDone)
            {
                if (handsTotal > 1)
                {
                    throw new Exception("Surrender done while hand has been split - should not happen!");
                }
                var betSize = playHandOutcome.HandsPlayed[0].BetSize;
                return -0.5 * betSize + insurancePayoff;
            }

            // dealer's hand play
            while (((handDealer.Value() <= 16) || (handDealer.Value() == 17 &&
                handDealer.IsSoft() && !Configuration.GameRules.DealerStandsSoft17)) &&
                !playHandOutcome.AllHandBust())
            {
                handDealer.Hit(shoe);
            }
            int dealerTotal = handDealer.Value();

            double payoff = 0;
            foreach (var handPlayed in playHandOutcome.HandsPlayed)
            {
                var betSize = handPlayed.BetSize;
                if (handPlayed.DoubleDone)
                {
                    betSize *= 2;
                }
                int playerTotal = handPlayed.Value();

                if (handPlayed.IsBlackjack() && !handDealer.IsBlackjack() && !splitDone)
                {
                    // blackjack won
                    payoff += 1.5 * betSize;
                }
                else if (playerTotal > 21)
                {
                    // player bust
                    payoff -= betSize;
                }
                else if (dealerTotal > 21)
                {
                    // dealer bust
                    payoff += betSize;
                }
                else if (playerTotal > dealerTotal)
                {
                    // player won
                    payoff += betSize;
                }
                else if (dealerTotal > playerTotal)
                {
                    // dealer won
                    payoff -= betSize;
                }
                else
                {
                    // push
                    payoff += 0;
                }
            }

            return payoff + insurancePayoff;
        }
Exemple #10
0
        public double GetBetSize(double wealth, CardShoe shoe)
        {
            double betSize = 0;
            switch (Configuration.SimulationParameters.BetSizeCalculationType)
            {
                case BetSizeCalculationType.FIXED:
                    betSize = Math.Round(GetBetSizeUnit(wealth));
                    break;

                case BetSizeCalculationType.TRUE_COUNT_VARIABLE:
                    if (shoe.Count == null)
                    {
                        throw new Exception("Count not initiated, cannot scale bet size conditionally on True Count!");
                    }
                    else
                    {
                        var trueCount = shoe.Count.TrueCount;
                        var riskAversionCoefficient = Configuration.SimulationParameters.RiskAversionCoefficient;
                        var betSizeTrueCountScale = Configuration.SimulationParameters.BetSizeTrueCountScale;

                        var trueCountBet = betSizeTrueCountScale.GetTrueCountBet(trueCount);
                        betSize = wealth * trueCountBet.BetRatio * (1.0 / riskAversionCoefficient);

                        betSize = Math.Round(betSize);
                        betSize = Math.Min(Math.Max(betSize, Configuration.SimulationParameters.BetSizeMin),
                            Configuration.SimulationParameters.BetSizeMax);
                        break;
                    }

                case BetSizeCalculationType.TRUE_COUNT_BET_SPREAD:
                    if (shoe.Count == null)
                    {
                        throw new Exception("Count not initiated, cannot scale bet size conditionally on True Count!");
                    }
                    else
                    {
                        var trueCount = shoe.Count.TrueCount;
                        var betSizeTrueCountScale = Configuration.SimulationParameters.BetSizeTrueCountScale;

                        var trueCountBet = betSizeTrueCountScale.GetTrueCountBet(trueCount);
                        var betInUnits = trueCountBet.BetInUnits;
                        var unitBet = GetBetSizeUnit(wealth);

                        betSize = Math.Round(betInUnits * unitBet);
                        betSize = Math.Min(Math.Max(betSize, Configuration.SimulationParameters.BetSizeMin),
                            Configuration.SimulationParameters.BetSizeMax);
                        break;
                    }
            }

            return betSize;
        }