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); }
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); }
private List <IHand> FindBetterSuitedHandsFromOffsuitGrid(PlayerRangePkGrid villainGrid, IHand villainOffsuitHand, List <Card> fullBoard, SuitEnum suit) { var betterSuitedHands = new List <IHand>(); var villainSuitedRanks = fullBoard.Where(c => c.Suit == suit).Select(c => c.Rank).ToList(); var hand1 = _suitedHandFinder.FindBestHand(villainSuitedRanks); if (hand1 != null && hand1.CompareTo(villainOffsuitHand) > 0) { betterSuitedHands.Add(hand1); } foreach (var holes in villainGrid.Grid.EnumerateAllPossibleHolesContainingSuit(suit)) { var newVillainSuitedRanks = new List <RankEnum>(villainSuitedRanks); if (holes.Item1.Suit == suit) { newVillainSuitedRanks.Add(holes.Item1.Rank); } if (holes.Item2.Suit == suit) { newVillainSuitedRanks.Add(holes.Item2.Rank); } var newHand = _suitedHandFinder.FindBestHand(newVillainSuitedRanks); if (newHand != null && newHand.CompareTo(villainOffsuitHand) > 0) { betterSuitedHands.Add(newHand); } } return(betterSuitedHands); }
/// <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)); } }
/// <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); }
/// <summary> /// Set Fold if a grid or part of it should fold to board /// </summary> private void SetFoldToBoard(PlayerRangePkGrid grid) { if (_shouldAGridFoldToBoardByRank.Invoke(grid.Grid)) { grid.GridPkStatus.RankWiseStatus = PlayerGridPkStatusEnum.Fold; } SetFoldToBoardBySuit(grid); }
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)); } }
private PkResult PkHeroHandWithOffsuitHand(IHand heroBestHand, PlayerRangePkGrid villainGrid, IHand villainOffsuitHand) { int pk = heroBestHand.CompareTo(villainOffsuitHand); 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)); } }
private PkResult PkHeroHandOnSuitedBoard(IHand heroBestHand, PlayerRangePkGrid villainGrid, List <Card> fullBoard, SuitEnum suit) { var villainOffsuitRanks = fullBoard.Select(c => c.Rank).ToList(); villainOffsuitRanks.Add(villainGrid.Grid.HighRank); villainOffsuitRanks.Add(villainGrid.Grid.LowRank); var villainOffsuitHand = _offsuitHandFinder.FindBestHand(villainOffsuitRanks); var pkResult = PkHeroHandWithOffsuitHand(heroBestHand, villainGrid, villainOffsuitHand); if (pkResult.HeroWinScenariosCount == 0 && pkResult.TiedScenariosCount == 0 && pkResult.TiedScenariosCount == 0) { //villain already won, no need to compare anymore return(pkResult); } bool tied = pkResult.TiedScenariosCount != 0; foreach (var villainSuitedHand in FindBetterSuitedHandsFromOffsuitGrid(villainGrid, villainOffsuitHand, fullBoard, suit)) { var pk = heroBestHand.CompareTo(villainSuitedHand); if (pk == 0) { pkResult.TiedScenariosCount++; } else if (pk < 0) { pkResult.VillainWinScenariosCount++; } if (tied) { pkResult.TiedScenariosCount--; } else { pkResult.HeroWinScenariosCount--; } } return(pkResult); }
private void SetFoldToBoardBySuit(PlayerRangePkGrid grid) { var shouldFoldDict = _shouldAGridFoldToBoardBySuit(grid.Grid); var hhKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Heart, SuitEnum.Heart); var ssKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Spade, SuitEnum.Spade); var ddKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Diamond, SuitEnum.Diamond); var ccKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Club, SuitEnum.Club); var hsKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Heart, SuitEnum.Spade); var hdKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Heart, SuitEnum.Diamond); var hcKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Heart, SuitEnum.Club); var shKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Spade, SuitEnum.Heart); var sdKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Spade, SuitEnum.Diamond); var scKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Spade, SuitEnum.Club); var dhKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Diamond, SuitEnum.Heart); var dsKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Diamond, SuitEnum.Spade); var dcKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Diamond, SuitEnum.Club); var chKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Club, SuitEnum.Heart); var csKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Club, SuitEnum.Spade); var cdKey = new Tuple <SuitEnum, SuitEnum>(SuitEnum.Club, SuitEnum.Diamond); switch (grid.GridPkStatus.Category) { case GridCategoryEnum.Suited: if (!shouldFoldDict.ContainsKey(hhKey)) { grid.GridPkStatus.SuitedStatus.HeartStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[hhKey]) { grid.GridPkStatus.SuitedStatus.HeartStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(ssKey)) { grid.GridPkStatus.SuitedStatus.SpadeStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[ssKey]) { grid.GridPkStatus.SuitedStatus.SpadeStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(ddKey)) { grid.GridPkStatus.SuitedStatus.DiamondStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[ddKey]) { grid.GridPkStatus.SuitedStatus.DiamondStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(ccKey)) { grid.GridPkStatus.SuitedStatus.ClubStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[ccKey]) { grid.GridPkStatus.SuitedStatus.ClubStatus = PlayerGridPkStatusEnum.Fold; } break; case GridCategoryEnum.Paired: if (!shouldFoldDict.ContainsKey(hsKey)) { grid.GridPkStatus.PairedStatus.HeartSpadeStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[hsKey]) { grid.GridPkStatus.PairedStatus.HeartSpadeStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(hdKey)) { grid.GridPkStatus.PairedStatus.HeartDiamondStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[hdKey]) { grid.GridPkStatus.PairedStatus.HeartDiamondStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(hcKey)) { grid.GridPkStatus.PairedStatus.HeartClubStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[hcKey]) { grid.GridPkStatus.PairedStatus.HeartClubStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(sdKey)) { grid.GridPkStatus.PairedStatus.SpadeDiamondStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[sdKey]) { grid.GridPkStatus.PairedStatus.SpadeDiamondStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(scKey)) { grid.GridPkStatus.PairedStatus.SpadeClubStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[scKey]) { grid.GridPkStatus.PairedStatus.SpadeClubStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(dcKey)) { grid.GridPkStatus.PairedStatus.DiamondClubStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[dcKey]) { grid.GridPkStatus.PairedStatus.DiamondClubStatus = PlayerGridPkStatusEnum.Fold; } break; case GridCategoryEnum.Offsuit: if (!shouldFoldDict.ContainsKey(hsKey)) { grid.GridPkStatus.OffsuitStatus.HeartSpadeStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[hsKey]) { grid.GridPkStatus.OffsuitStatus.HeartSpadeStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(hdKey)) { grid.GridPkStatus.OffsuitStatus.HeartDiamondStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[hdKey]) { grid.GridPkStatus.OffsuitStatus.HeartDiamondStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(hcKey)) { grid.GridPkStatus.OffsuitStatus.HeartClubStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[hcKey]) { grid.GridPkStatus.OffsuitStatus.HeartClubStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(sdKey)) { grid.GridPkStatus.OffsuitStatus.SpadeDiamondStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[sdKey]) { grid.GridPkStatus.OffsuitStatus.SpadeDiamondStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(scKey)) { grid.GridPkStatus.OffsuitStatus.SpadeClubStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[scKey]) { grid.GridPkStatus.OffsuitStatus.SpadeClubStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(dcKey)) { grid.GridPkStatus.OffsuitStatus.DiamondClubStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[dcKey]) { grid.GridPkStatus.OffsuitStatus.DiamondClubStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(shKey)) { grid.GridPkStatus.OffsuitStatus.SpadeHeartStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[shKey]) { grid.GridPkStatus.OffsuitStatus.SpadeHeartStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(dhKey)) { grid.GridPkStatus.OffsuitStatus.DiamondHeartStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[dhKey]) { grid.GridPkStatus.OffsuitStatus.DiamondHeartStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(chKey)) { grid.GridPkStatus.OffsuitStatus.ClubHeartStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[chKey]) { grid.GridPkStatus.OffsuitStatus.ClubHeartStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(dsKey)) { grid.GridPkStatus.OffsuitStatus.DiamondSpadeStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[dsKey]) { grid.GridPkStatus.OffsuitStatus.DiamondSpadeStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(csKey)) { grid.GridPkStatus.OffsuitStatus.ClubSpadeStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[csKey]) { grid.GridPkStatus.OffsuitStatus.ClubSpadeStatus = PlayerGridPkStatusEnum.Fold; } if (!shouldFoldDict.ContainsKey(cdKey)) { grid.GridPkStatus.OffsuitStatus.ClubDiamondStatus = PlayerGridPkStatusEnum.NotAvailable; } else if (shouldFoldDict[cdKey]) { grid.GridPkStatus.OffsuitStatus.ClubDiamondStatus = PlayerGridPkStatusEnum.Fold; } break; } }
private static IEnumerable <HoldingHoles> EnumerateHoles(PlayerRangePkGrid pkGrid, Func <PlayerGridPkStatusEnum, bool> valid) { var grid = pkGrid.Grid; switch (pkGrid.GridPkStatus.Category) { case GridCategoryEnum.Offsuit: if (valid(pkGrid.GridPkStatus.OffsuitStatus.HeartSpadeStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Heart, grid.HighRank), new Card(SuitEnum.Spade, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.OffsuitStatus.HeartDiamondStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Heart, grid.HighRank), new Card(SuitEnum.Diamond, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.OffsuitStatus.HeartClubStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Heart, grid.HighRank), new Card(SuitEnum.Club, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.OffsuitStatus.SpadeHeartStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Spade, grid.HighRank), new Card(SuitEnum.Heart, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.OffsuitStatus.SpadeDiamondStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Spade, grid.HighRank), new Card(SuitEnum.Diamond, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.OffsuitStatus.SpadeClubStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Spade, grid.HighRank), new Card(SuitEnum.Club, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.OffsuitStatus.DiamondHeartStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Diamond, grid.HighRank), new Card(SuitEnum.Heart, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.OffsuitStatus.DiamondSpadeStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Diamond, grid.HighRank), new Card(SuitEnum.Spade, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.OffsuitStatus.DiamondClubStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Diamond, grid.HighRank), new Card(SuitEnum.Club, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.OffsuitStatus.ClubHeartStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Club, grid.HighRank), new Card(SuitEnum.Heart, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.OffsuitStatus.ClubSpadeStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Club, grid.HighRank), new Card(SuitEnum.Spade, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.OffsuitStatus.ClubDiamondStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Club, grid.HighRank), new Card(SuitEnum.Diamond, grid.LowRank))); } break; case GridCategoryEnum.Paired: if (valid(pkGrid.GridPkStatus.PairedStatus.HeartSpadeStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Heart, grid.HighRank), new Card(SuitEnum.Spade, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.PairedStatus.HeartDiamondStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Heart, grid.HighRank), new Card(SuitEnum.Diamond, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.PairedStatus.HeartClubStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Heart, grid.HighRank), new Card(SuitEnum.Club, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.PairedStatus.SpadeDiamondStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Spade, grid.HighRank), new Card(SuitEnum.Diamond, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.PairedStatus.SpadeClubStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Spade, grid.HighRank), new Card(SuitEnum.Club, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.PairedStatus.DiamondClubStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Diamond, grid.HighRank), new Card(SuitEnum.Club, grid.LowRank))); } break; case GridCategoryEnum.Suited: if (valid(pkGrid.GridPkStatus.SuitedStatus.HeartStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Heart, grid.HighRank), new Card(SuitEnum.Heart, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.SuitedStatus.SpadeStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Spade, grid.HighRank), new Card(SuitEnum.Spade, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.SuitedStatus.DiamondStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Diamond, grid.HighRank), new Card(SuitEnum.Diamond, grid.LowRank))); } if (valid(pkGrid.GridPkStatus.SuitedStatus.ClubStatus)) { yield return(new HoldingHoles(new Card(SuitEnum.Club, grid.HighRank), new Card(SuitEnum.Club, grid.LowRank))); } break; } }
private static IEnumerable <HoldingHoles> FilterCardAvailabilities(this IEnumerable <HoldingHoles> holeses, PlayerRangePkGrid pkGrid) { return(holeses.Where(holes => pkGrid.Grid.Card1AvaliableSuits.Contains(holes.Hole1.Suit) && pkGrid.Grid.Card2AvaliableSuits.Contains(holes.Hole2.Suit))); }
public static IEnumerable <HoldingHoles> EnumerateUnfoldedHoles(PlayerRangePkGrid pkGrid) { return(EnumerateHoles(pkGrid, status => status != PlayerGridPkStatusEnum.Fold && status != PlayerGridPkStatusEnum.NotAvailable) .FilterCardAvailabilities(pkGrid)); }