示例#1
0
 private List <Card> GetCards(FlopBoard flopBoard, HoldingHoles heroHoles)
 {
     return(new List <Card>()
     {
         flopBoard.Flop1, flopBoard.Flop2, flopBoard.Flop3, heroHoles.Hole1, heroHoles.Hole2
     });
 }
示例#2
0
        /// <summary>
        /// PK on a board that has at least three cards of the same suit
        /// </summary>
        /// <param name="heroHoles"></param>
        /// <param name="villainGrid"></param>
        /// <param name="fullBoard"></param>
        /// <param name="suit"></param>
        /// <returns></returns>
        private PkResult PkOnSuitedBoard(HoldingHoles heroHoles, PlayerRangePkGrid villainGrid, List <Card> fullBoard,
                                         SuitEnum suit)
        {
            var heroOffsuitRanks = fullBoard.Select(c => c.Rank).ToList();

            heroOffsuitRanks.Add(heroHoles.Hole1.Rank);
            heroOffsuitRanks.Add(heroHoles.Hole2.Rank);

            var heroSuitedRanks = fullBoard.Where(c => c.Suit == suit).Select(c => c.Rank).ToList();

            if (heroHoles.Hole1.Suit == suit)
            {
                heroSuitedRanks.Add(heroHoles.Hole1.Rank);
            }
            if (heroHoles.Hole2.Suit == suit)
            {
                heroSuitedRanks.Add(heroHoles.Hole2.Rank);
            }

            var   heroOffsuitHand = _offsuitHandFinder.FindBestHand(heroOffsuitRanks);
            var   heroSuitedHand  = _suitedHandFinder.FindBestHand(heroSuitedRanks);
            IHand heroBestHand    = heroSuitedHand == null
                ? heroOffsuitHand
                : (heroSuitedHand.CompareTo(heroOffsuitHand) > 0 ? heroSuitedHand : heroOffsuitHand);

            var pkResult = PkHeroHandOnSuitedBoard(heroBestHand, villainGrid, fullBoard, suit);

            return(pkResult);
        }
示例#3
0
        private PkResult PkV2(HoldingHoles heroHoles, PlayerRangePkGrid villainGrid, List <Card> fullBoard)
        {
            var      pkResult = new PkResult();
            SuitEnum suit;
            int      suitedCount;
            var      boardSuited = FullBoardHasThreeSuitedCards(fullBoard, out suit, out suitedCount);

            IHand bestHeroHand = boardSuited ? FindBestHand(heroHoles, fullBoard, suit) : FindBestOffsuitHand(heroHoles, fullBoard);

            foreach (var villainHoles in _holesEnumerator(villainGrid))
            {
                IHand bestVillainHand = boardSuited
                    ? FindBestHand(villainHoles, fullBoard, suit)
                    : FindBestOffsuitHand(villainHoles, fullBoard);

                var pk = bestHeroHand.CompareTo(bestVillainHand);
                if (pk == 0)
                {
                    pkResult.TiedScenariosCount++;
                }
                else if (pk < 0)
                {
                    pkResult.VillainWinScenariosCount++;
                }
                else if (pk > 0)
                {
                    pkResult.HeroWinScenariosCount++;
                }
            }

            return(pkResult);
        }
示例#4
0
        /// <summary>
        /// PK on a board which doesn't have more than two cards of any suit
        /// </summary>
        /// <param name="heroHoles"></param>
        /// <param name="villainGrid"></param>
        /// <param name="fullBoard"></param>
        /// <returns></returns>
        private PkResult PkOffsuit(HoldingHoles heroHoles, PlayerRangePkGrid villainGrid, List <Card> fullBoard)
        {
            var heroRanks = fullBoard.Select(c => c.Rank).ToList();

            heroRanks.Add(heroHoles.Hole1.Rank);
            heroRanks.Add(heroHoles.Hole2.Rank);
            var heroHand = _offsuitHandFinder.FindBestHand(heroRanks);

            var villainRanks = fullBoard.Select(c => c.Rank).ToList();

            villainRanks.Add(villainGrid.Grid.HighRank);
            villainRanks.Add(villainGrid.Grid.LowRank);
            var villainHand = _offsuitHandFinder.FindBestHand(villainRanks);

            var pk = heroHand.CompareTo(villainHand);

            if (pk > 0)
            {
                return(new PkResult(villainGrid.Grid.AvailableRankCombCount, 0, 0, 0));
            }
            else if (pk == 0)
            {
                return(new PkResult(0, 0, villainGrid.Grid.AvailableRankCombCount, 0));
            }
            else
            {
                return(new PkResult(0, villainGrid.Grid.AvailableRankCombCount, 0, 0));
            }
        }
示例#5
0
        private PkResult Pk(HoldingHoles heroHoles, PlayerRangePkGrid villainGrid)
        {
            var pkResult = new PkResult();

            foreach (var fiveCards in _fiveCardsEnumerator.Invoke())
            {
                if (ConflictsWithVillainGrid(fiveCards, villainGrid.Grid))
                {
                    continue;
                }


                var conflictCards = new List <Card>(fiveCards);
                conflictCards.Add(heroHoles.Hole1);
                conflictCards.Add(heroHoles.Hole2);

                villainGrid.Grid.EliminateConflicts(conflictCards);

                var turnRiverPkResult = PkV2(heroHoles, villainGrid, fiveCards);

                pkResult.Add(turnRiverPkResult);
            }

            return(pkResult);
        }
示例#6
0
        public double CalculateEquity(HoldingHoles heroHoles, PlayerRange villainRange)
        {
            var pkStage  = new PkStage(_fiveCardsEnumerator.Enumerate, Utils.EnumerateAvailableHoles);
            var pkResult = pkStage.Pk(heroHoles, villainRange.CloneToPkRange());

            return((double)pkResult.HeroWinScenariosCount /
                   (pkResult.HeroWinScenariosCount + pkResult.VillainWinScenariosCount + pkResult.TiedScenariosCount));
        }
示例#7
0
        private IHand FindBestOffsuitHand(HoldingHoles holes, List <Card> fullBoard)
        {
            var ranks = fullBoard.Select(c => c.Rank).ToList();

            ranks.Add(holes.Hole1.Rank);
            ranks.Add(holes.Hole2.Rank);

            return(_offsuitHandFinder.FindBestHand(ranks));
        }
示例#8
0
 public HeadsupRiverBettingStrategy(RiverBoard riverBoard, HoldingHoles heroHoles)
 {
     _riverBoard            = riverBoard;
     _riverFolder           = new RiverFolder();
     _probabilityCalculator = new VillainProbabilityCalculator(
         grid => _riverFolder.ShouldAGridFoldToBoardByRank(grid, _riverBoard),
         grid => _riverFolder.ShouldAGridFoldToBoardBySuit(grid, _riverBoard, heroHoles),
         () => DumbEnumerate(_riverBoard));
 }
示例#9
0
        private IHand FindBestHand(HoldingHoles holes, List <Card> fullBoard, SuitEnum suit)
        {
            var bestOffsuitHand = FindBestOffsuitHand(holes, fullBoard);
            var bestSuitedHand  = FindBestSuitedHand(holes, fullBoard, suit);

            return(bestSuitedHand == null
                ? bestOffsuitHand
                : (bestSuitedHand.CompareTo(bestOffsuitHand) > 0 ? bestSuitedHand : bestOffsuitHand));
        }
示例#10
0
        private List <Card> GetCards(TurnBoard turnBoard, HoldingHoles heroHoles)
        {
            var flopBoard = turnBoard.FlopBoard;

            return(new List <Card>()
            {
                flopBoard.Flop1, flopBoard.Flop2, flopBoard.Flop3, turnBoard.TurnCard, heroHoles.Hole1, heroHoles.Hole2
            });
        }
示例#11
0
        private List <Card> GetCards(RiverBoard riverBoard, HoldingHoles heroHoles)
        {
            var flopBoard = riverBoard.TurnBoard.FlopBoard;
            var turnBoard = riverBoard.TurnBoard;

            return(new List <Card>()
            {
                flopBoard.Flop1, flopBoard.Flop2, flopBoard.Flop3, turnBoard.TurnCard, riverBoard.River, heroHoles.Hole1, heroHoles.Hole2
            });
        }
示例#12
0
        public MultiwayRiverCallingStrategy(RiverBoard riverBoard, HoldingHoles heroHoles)
        {
            _riverBoard  = riverBoard;
            _riverFolder = new RiverFolder();
            var fiveCardsEnumerator = new RiverFiveCardsEnumerator(riverBoard);

            _probabilityCalculator = new VillainProbabilityCalculator(
                grid => _riverFolder.ShouldAGridFoldToBoardByRank(grid, _riverBoard),
                grid => _riverFolder.ShouldAGridFoldToBoardBySuit(grid, _riverBoard, heroHoles),
                fiveCardsEnumerator.Enumerate);
        }
        public TurnMultiwayCallingStrategy(TurnBoard turnBoard, HoldingHoles heroHoles)
        {
            _turnBoard  = turnBoard;
            _turnFolder = new TurnFolder();
            var fiveCardsEnumerator = new TurnFiveCardsEnumerator(turnBoard, heroHoles);

            _probabilityCalculator = new VillainProbabilityCalculator(
                grid => _turnFolder.ShouldAGridFoldToBoardByRank(grid, _turnBoard),
                grid => _turnFolder.ShouldAGridFoldToBoardBySuit(grid, _turnBoard, heroHoles),
                fiveCardsEnumerator.Enumerate);
        }
示例#14
0
        public FlopHeadsUpBettingStrategy(FlopBoard flopBoard, HoldingHoles heroHoles)
        {
            _flopBoard  = flopBoard;
            _flopFolder = new FlopFolder();
            var enumerator = new FlopFiveCardsEnumerator(_flopBoard, heroHoles);

            _probabilityCalculator = new VillainProbabilityCalculator(
                grid => _flopFolder.ShouldAGridFoldToBoardByRank(grid, _flopBoard),
                grid => _flopFolder.ShouldAGridFoldToBoardBySuit(grid, _flopBoard, heroHoles),
                enumerator.Enumerate);
        }
示例#15
0
        public bool CanBetForValue(BoardStatus boardStatus, HoldingHoles heroHoles, HoldingHoles villainHoles)
        {
            if (BettingUtils.CompareHoles(heroHoles, villainHoles, boardStatus) <= 0)
            {
                //It's not a value bet if hero's hand is worse than villain's
                return(false);
            }

            var heroRange     = BettingUtils.GetVillainGuessOnHeroRange();
            var villainEquity = _equityCalculator.CalculateEquityAgainstARange(villainHoles, heroRange, boardStatus);

            return(BettingUtils.VillainIsWillingToCall(villainEquity, _potOddsToBet) == true);
        }
示例#16
0
        /// <summary>
        /// Don't call this method if the board is not scary enough for bluffing
        /// or the position/number of alive players doesn't allow a bluffing play
        /// Check those condition prior to calling this method.
        /// </summary>
        /// <param name="boardStatus"></param>
        /// <param name="heroHoles"></param>
        /// <param name="villainHoles"></param>
        /// <returns></returns>
        public bool CanBluff(BoardStatus boardStatus, HoldingHoles heroHoles, HoldingHoles villainHoles)
        {
            if (BettingUtils.CompareHoles(heroHoles, villainHoles, boardStatus) > 0)
            {
                //It's not a bluff bet with a better hand than villain's
                return(false);
            }

            var heroRange     = BettingUtils.GetVillainGuessOnHeroRange();
            var villainEquity = _equityCalculator.CalculateEquityAgainstARange(villainHoles, heroRange, boardStatus);

            return(BettingUtils.VillainIsWillingToCall(villainEquity, _potOddsToBluff) == false);
        }
示例#17
0
        public PkResult Pk(HoldingHoles heroHoles, VillainPkRange villainRange)
        {
            var pkResult = new PkResult();

            Parallel.ForEach(villainRange.Grids.EnumerateMultiDimensionalArray(), playerGrid =>
            {
                var gridPkResult = Pk(heroHoles, playerGrid);
                Logger.Instance.Log($"Pk finished between heroHoles {heroHoles.Hole1.GetStringForCard() + heroHoles.Hole2.GetStringForCard()}" +
                                    $" and {playerGrid.Grid}, result is {gridPkResult}");
                pkResult.Add(gridPkResult);
            });

            return(pkResult);
        }
示例#18
0
        private PkResult Pk(HoldingHoles heroHoles, PlayerRangePkGrid pkGrid, List <Card> fullBoard)
        {
            SuitEnum suit;
            int      suitedCount;

            if (FullBoardHasThreeSuitedCards(fullBoard, out suit, out suitedCount))
            {
                return(PkOnSuitedBoard(heroHoles, pkGrid, fullBoard, suit));
            }
            else
            {
                return(PkOffsuit(heroHoles, pkGrid, fullBoard));
            }
        }
示例#19
0
        private IHand FindBestSuitedHand(HoldingHoles holes, List <Card> fullBoard, SuitEnum suit)
        {
            var suitedRanks = fullBoard.Where(c => c.Suit == suit).Select(c => c.Rank).ToList();

            if (holes.Hole1.Suit == suit)
            {
                suitedRanks.Add(holes.Hole1.Rank);
            }
            if (holes.Hole2.Suit == suit)
            {
                suitedRanks.Add(holes.Hole2.Rank);
            }

            return(_suitedHandFinder.FindBestHand(suitedRanks));
        }
        public double CalculateEquityAgainstARange(HoldingHoles heroHoles, PlayerRange villainPlayerRange, BoardStatus boardStatus)
        {
            var villainGrids = villainPlayerRange.GetAliveGrids();

            int    numOfCombos = 0;
            double equitySum   = 0;

            foreach (var villainGrid in villainGrids)
            {
                foreach (var villainHoles in villainGrid.Grid.EnumerateAllCombos())
                {
                    var handEquity = CalculateEquityAgainstGrid(heroHoles, villainHoles, boardStatus);
                    equitySum   += handEquity * villainGrid.Grid.PossibleCount;
                    numOfCombos += villainGrid.Grid.PossibleCount;
                }
            }

            return(equitySum / numOfCombos);
        }
示例#21
0
        public HolesCompareResult(HoldingHoles heroHoles, HoldingHoles villainHoles, BoardStatus boardStatus)
        {
            HeroHoles    = heroHoles;
            VillainHoles = villainHoles;

            HeroOuts    = new List <Card>();
            VillainOuts = new List <Card>();

            if (boardStatus.Turn == null)
            {
                CompareOnFlop();
            }
            else if (boardStatus.River == null)
            {
                CompareOnTurn();
            }
            else
            {
                CompareOnRiver();
            }
        }
        public VillainProbabilityResult Calculate(HoldingHoles heroHoles, PlayerRoundProfile villainProfile, bool considerFolding = true)
        {
            var pkStage      = new PkStage(_enumerate, Utils.EnumerateUnfoldedHoles);
            var villainRange = villainProfile.PlayerRange.CloneToPkRange();

            var aliveRanges = villainRange.GetAliveGrids();
            int foldCombos = 0, totalCombos = 0;

            foreach (var playerGrid in aliveRanges)
            {
                if (considerFolding)
                {
                    SetFoldToBoard(playerGrid);
                    foldCombos += playerGrid.FoldCombCount;
                }
                totalCombos += playerGrid.AvailableCombCount;
            }

            double villainFoldP = (double)foldCombos / totalCombos;
            double villainCallP = 1 - villainFoldP;

            var pkResult = pkStage.Pk(heroHoles, villainRange);

            int totalGrids = pkResult.HeroWinScenariosCount + pkResult.TiedScenariosCount +
                             pkResult.VillainWinScenariosCount + pkResult.VillainFoldCount;

            double villainCallWinP  = villainCallP * pkResult.VillainWinScenariosCount / totalGrids;
            double villainCallLoseP = villainCallP * pkResult.HeroWinScenariosCount / totalGrids;
            double tieP             = villainCallP * pkResult.TiedScenariosCount / totalGrids;

            return(new VillainProbabilityResult(new Dictionary <ProbabilityEnum, double>()
            {
                { ProbabilityEnum.Fold, villainFoldP },
                { ProbabilityEnum.CallWin, villainCallWinP },
                { ProbabilityEnum.CallTie, tieP },
                { ProbabilityEnum.CallLose, villainCallLoseP }
            },
                                                villainProfile.Name));
        }
示例#23
0
        public BoardHandTypeEnum DetectBoardHand(BoardStatus boardStatus, HoldingHoles holes)
        {
            var boardCards = new List <Card>()
            {
                boardStatus.Flop1, boardStatus.Flop2, boardStatus.Flop3
            };

            if (boardStatus.Turn != null)
            {
                boardCards.Add(boardStatus.Turn);
            }
            if (boardStatus.River != null)
            {
                boardCards.Add(boardStatus.River);
            }

            var holesCards = new List <Card>()
            {
                holes.Hole1, holes.Hole2
            };

            return(DetectBoardHand(boardCards, holesCards));
        }
示例#24
0
        public Decision MakeDecision(PreflopStatusSummary statusSummary, HoldingHoles holes)
        {
            Logger.Instance.Log($"ChartPreflopStrategy to make decision. HeroHoles={holes.Hole1.GetStringForCard()},{holes.Hole2.GetStringForCard()}");

            var raiseMoves = FilterRaiseMoves(statusSummary.PreflopRaiseMoves, p => p.Name == statusSummary.Me.Name);

            Logger.Instance.Log($"Filtered raise moves: {string.Join("/", raiseMoves.Select(m => m.GetStringForMove()))}");
            var grid = new RangeGrid(holes);

            if (raiseMoves.Count == 0)
            {
                return(GetDecisionOnUnraisedPot(statusSummary, grid));
            }

            if (raiseMoves.Count == 1)
            {
                return(GetDecisionAgainstOpenRaise(statusSummary, grid, raiseMoves[0].Player.Position));
            }

            if (raiseMoves.Count == 2)
            {
                return(GetDecisionAgainstThreeBet(statusSummary, grid, raiseMoves[1].Player.Position));
            }

            if (raiseMoves.Count == 3)
            {
                return(GetDecisionAgainstFourBet(statusSummary, grid, raiseMoves[2].Player.Position));
            }

            if (raiseMoves.Count == 4)
            {
                return(GetDecisionAgainstFiveBet(statusSummary, grid, raiseMoves[3].Player.Position));
            }

            throw new NotSupportedException();
        }
        public double CalculateEquityAgainstGrid(HoldingHoles heroHoles, HoldingHoles villainHoles, BoardStatus boardStatus)
        {
            var boards =
                boardStatus.GenerateAllPossibleBoards(new List <Card>()
            {
                heroHoles.Hole1,
                heroHoles.Hole2,
                villainHoles.Hole1,
                villainHoles.Hole2
            });

            double heroWin = 0, villainWin = 0;

            foreach (var board in boards)
            {
                var heroSeven    = new SevenCardsHand(heroHoles.Hole1, heroHoles.Hole2, board.Flop1, board.Flop2, board.Flop3, board.Turn, board.River);
                var villainSeven = new SevenCardsHand(villainHoles.Hole1, villainHoles.Hole2, board.Flop1, board.Flop2, board.Flop3, board.Turn, board.River);

                var heroFive    = BettingUtils.FindBestFive(heroSeven);
                var villainFive = BettingUtils.FindBestFive(villainSeven);

                int heroScore    = BettingUtils.GetScoreForFiveCardHand(heroFive);
                int villainScore = BettingUtils.GetScoreForFiveCardHand(villainFive);

                if (heroScore > villainScore)
                {
                    heroWin++;
                }
                else
                {
                    villainWin++;
                }
            }

            return(heroWin / (heroWin + villainWin));
        }
示例#26
0
 private PlayerRange SqueezeOnCheck(PlayerRange previousRange, Move lastMove, int bigBlindSize, FlopBoard flopBoard, HoldingHoles heroHoles)
 {
     return(_playerRangeSqueezer.Squeeze(previousRange, grid => TestGrid(flopBoard, grid), TestOutcomeOnCheck, GetCards(flopBoard, heroHoles)));
 }
示例#27
0
        public static double CompareHoles(HoldingHoles holes1, HoldingHoles holes2, BoardStatus boardStatus)
        {
            var compareResult = new HolesCompareResult(holes1, holes2, boardStatus);

            throw new NotImplementedException();
        }
示例#28
0
 public Decision GetPreflopDecision(PreflopStatusSummary statusSummary, HoldingHoles heroHoles)
 {
     return(_preflopStrategy.MakeDecision(statusSummary, GetStartingHand(heroHoles.Hole1, heroHoles.Hole2)));
 }
示例#29
0
        public Dictionary <Tuple <SuitEnum, SuitEnum>, bool> ShouldAGridFoldToBoardBySuit(RangeGrid grid,
                                                                                          FlopBoard flopBoard, HoldingHoles heroHoles)
        {
            var conflictCards = new List <Card>()
            {
                heroHoles.Hole1, heroHoles.Hole2, flopBoard.Flop1, flopBoard.Flop2, flopBoard.Flop3
            };

            grid.EliminateConflicts(conflictCards);
            switch (flopBoard.SuitTexture)
            {
            case FlopBoardSuitTextureEnum.SuitedThree:
                return(new SuitedThreeSuitTexture(flopBoard).ShouldAGridFoldToBet(grid));

            case FlopBoardSuitTextureEnum.SuitedTwo:
                return(new SuitedTwoSuitTexture(flopBoard).ShouldAGridFoldToBet(grid));

            case FlopBoardSuitTextureEnum.Rainbow:
                return(new RainbowSuitTexture().ShouldAGridFoldToBet(grid));

            default:
                throw new InvalidOperationException();
            }
        }
        public double CalculateEquityAgainstARange(HoldingHoles heroHoles, PlayerRange villainPlayerRange, BoardSpectrum boardSpectrum)
        {
            var heroEquityAgainstVillainRange = boardSpectrum.GetEquity(heroHoles);

            return(heroEquityAgainstVillainRange);
        }