/// <summary>Creates a pokerhand.</summary> public static UInt32PokerHand Create(PokerHandType tp, uint mask) { var hand = new UInt32PokerHand(); hand.mask = ((uint)tp << 28) | mask; return(hand); }
public static int Solve() { int hand1Wins = 0; int dealNumber = 1; List <Deal> deals = Deal.ReadDeals(); foreach (Deal deal in deals) { PokerHandType pokerhandType1 = deal.Hand1.GetPokerHandType(); PokerHandType pokerhandType2 = deal.Hand2.GetPokerHandType(); bool isHand1Winner = deal.IsHand1Winner(); WriteLine("----------------------------------------------------------"); WriteLine($"Deal Number = {dealNumber}"); WriteLine($"{deal}"); WriteLine($"hand1Type = {pokerhandType1}, hand2Type = {pokerhandType2}"); WriteLine($"Hand 1 wins = {isHand1Winner}"); if (isHand1Winner) { hand1Wins++; } dealNumber++; } return(hand1Wins); }
/// <summary>Initializes a new instance of poker hand based on the serialization info.</summary> /// <param name="info">The serialization info.</param> /// <param name="context">The streaming context.</param> private PokerHand(SerializationInfo info, StreamingContext context) { if (info == null) { throw new ArgumentNullException("info"); } tp = (PokerHandType)info.GetInt32("tp"); c0 = (Card)info.GetValue("c0", typeof(Card)); c1 = (Card)info.GetValue("c1", typeof(Card)); c2 = (Card)info.GetValue("c2", typeof(Card)); c3 = (Card)info.GetValue("c3", typeof(Card)); c4 = (Card)info.GetValue("c4", typeof(Card)); }
public async void CanCheckIfValidHand(string playerAndCards, PokerHandType handType, bool expected) { // arrange var hand = await new PokerHandCreator().CreateCardGameHand(playerAndCards.Split(',')); // act var result = hand.IsValidHand(handType); // assert Assert.Equal(expected, result); }
/// <summary>Reads the poker hand from an xml writer.</summary> /// <remarks> /// Uses the string parse set function of card. /// </remarks> /// <param name="reader">An xml reader.</param> void IXmlSerializable.ReadXml(XmlReader reader) { var s = reader.ReadElementString(); var val = CreateFrom5(Cards.Parse(s)); tp = val.tp; c0 = val.c0; c1 = val.c1; c2 = val.c2; c3 = val.c3; c4 = val.c4; }
public PokerHandType GetPokerHandType() { PokerHandType pokerHandType = PokerHandType.HighCard; if (IsRoyalFlush()) { pokerHandType = PokerHandType.RoyalFlush; } else if (IsStraightFlush()) { pokerHandType = PokerHandType.StraightFlush; } else if (IsFourOfKind()) { pokerHandType = PokerHandType.FourOfKind; } else if (IsFullHouse()) { pokerHandType = PokerHandType.FullHouse; } else if (IsFlush()) { pokerHandType = PokerHandType.Flush; } else if (IsStraight()) { pokerHandType = PokerHandType.Straight; } else if (IsThreeOfKind()) { pokerHandType = PokerHandType.ThreeOfKind; } else if (IsTwoPairs()) { pokerHandType = PokerHandType.TwoPair; } else if (IsOnePair()) { pokerHandType = PokerHandType.OnePair; } else if (IsHighCard()) { pokerHandType = PokerHandType.HighCard; } return(pokerHandType); }
public bool IsHand1Winner() { PokerHandType pokerHandType1 = Hand1.GetPokerHandType(); PokerHandType pokerHandType2 = Hand2.GetPokerHandType(); if (pokerHandType1 > pokerHandType2) { return(true); } if (pokerHandType1 < pokerHandType2) { return(false); } return(IsHand1WinnerWhereBothHandsHaveSamePokerType(pokerHandType1)); }
private void TypeAndSort() { cards = SortCards(cards); if (RoyalFlush()) { Type = PokerHandType.RoyalFlush; return; } if (StraightFlush()) { Type = PokerHandType.StraightFlush; return; } if (FourOfAKind()) { Type = PokerHandType.FourOfAKind; return; } if (FullHouse()) { Type = PokerHandType.FullHouse; return; } if (Flush()) { Type = PokerHandType.Flush; return; } if (Straight()) { Type = PokerHandType.Straight; return; } if (ThreeOfAKind()) { Type = PokerHandType.ThreeOfAKind; return; } if (TwoPair()) { Type = PokerHandType.TwoPair; return; } if (Pair()) { Type = PokerHandType.Pair; return; } Type = PokerHandType.HighCard; }
private bool IsHand1WinnerWhereBothHandsHaveSamePokerType(PokerHandType pokerHandType) { return(pokerHandType switch { PokerHandType.HighCard => IsHand1WithHighCardWinner(), PokerHandType.OnePair => IsHand1WithOnePairWinner(), PokerHandType.TwoPair => throw new Exception("There are no deals where both hands have this poker type"), PokerHandType.ThreeOfKind => throw new Exception( "There are no deals where both hands have this poker type"), PokerHandType.Straight => throw new Exception( "There are no deals where both hands have this poker type"), PokerHandType.Flush => throw new Exception("There are no deals where both hands have this poker type"), PokerHandType.FullHouse => throw new Exception( "There are no deals where both hands have this poker type"), PokerHandType.FourOfKind => throw new Exception( "There are no deals where both hands have this poker type"), PokerHandType.StraightFlush => throw new Exception( "There are no deals where both hands have this poker type"), PokerHandType.RoyalFlush => throw new Exception( "There are no deals where both hands have this poker type"), _ => throw new Exception("Should not get here") });
/// <summary> /// Determines whether or not this player's hand contains /// cards that make up the requested hand type. /// </summary> /// <param name="HandType">The type of hand for which the test is being run.</param> /// <returns>True if this hand contains the requested type. Otherwise, false.</returns> public bool ContainsHandType(PokerHandType HandType) { bool containsHandType = false; if (Cards.Count > 0) { switch (HandType) { case PokerHandType.Flush: containsHandType = ContainsFlush(); break; case PokerHandType.FourOfAKind: containsHandType = GroupCardsByRank().Values.Where(cards => cards.Count >= 4).Count() > 0; break; case PokerHandType.FullHouse: Dictionary <CardRank, List <Card> > cardsByRank = GroupCardsByRank(); cardsByRank .Keys .Where( majorityRank => cardsByRank[majorityRank].Count >= NumberOfCardsInMajorityOfFullHouse) .ToList() // Each of the ranks that reach this portion of the query will have 3 or // more of that rank in the current hand. .ForEach(majorityRank => { if (cardsByRank .Keys .Where( minorityRank => minorityRank != majorityRank && cardsByRank[minorityRank].Count >= NumberOfCardsInMinorityOfFullHouse) // If another rank exists (other than the majority rank) which has two // or more cards of that rank in the current hand, we have a full house. .Count() > 0) { containsHandType = true; } }); break; case PokerHandType.None: containsHandType = // Covers: pair, two pair, three of a kind, four of a kind, full house !ContainsHandType(PokerHandType.Pair) && // Covers: straight & straight flush !ContainsHandType(PokerHandType.Straight) && // Covers: flush & straight flush !ContainsHandType(PokerHandType.Flush); break; case PokerHandType.Pair: containsHandType = GroupCardsByRank().Values.Where(cards => cards.Count >= 2).Count() > 0; break; case PokerHandType.Straight: containsHandType = FindFirstCardInStraight() != null; break; case PokerHandType.StraightFlush: Card firstCardInStraight = FindFirstCardInStraight(); if (firstCardInStraight != null && firstCardInStraight.Rank != null && firstCardInStraight.Rank.HasValue && firstCardInStraight.Suit != null && firstCardInStraight.Suit.HasValue) { bool straightFlushStillInPlay = true; // Verifies that the rest of the cards in the straight are a flush. for (int straightCardsInspected = 1; straightCardsInspected < NumberOfCardsInAFlushOrStraight; straightCardsInspected++) { if (!ContainsCard( // This casting is safe to do because we've already determined that the // hand contains a straight and that means that the lowest card in // that straight will always be low enough that sum being calculated here // will fall within the enumeration's value. (CardRank)((int)firstCardInStraight.Rank.Value + straightCardsInspected), firstCardInStraight.Suit.Value)) { straightFlushStillInPlay = false; } } containsHandType = straightFlushStillInPlay; } break; case PokerHandType.ThreeOfAKind: containsHandType = GroupCardsByRank().Values.Where(cards => cards.Count >= 3).Count() > 0; break; case PokerHandType.TwoPair: containsHandType = GroupCardsByRank().Values.Where(cards => cards.Count >= 2).Count() > 1; break; } } return(containsHandType); }
/// <summary> /// Compares two poker hands of the same poker hand type; /// for example: 2 poker hands with hand type Four Of A Kind. /// </summary> /// <param name="pokerHand1">First poker hand to compare.</param> /// <param name="pokerHand2">Second poker hand to compare.</param> /// <param name="pokerHandType">Poker Hand Type of the 2 poker hands.</param> /// <returns> /// Int value indicating the winning hand. /// 1: Hand 1 is the winning hand, /// 0: The two hands are equal, /// -1: Hand 2 is the winning hand. /// </returns> public static int CompareHandsOfSameType(Hand pokerHand1, Hand pokerHand2, PokerHandType pokerHandType) { //Arrange cards pokerHand1.Cards = pokerHand1.Cards.OrderBy(h => h.Value); pokerHand2.Cards = pokerHand2.Cards.OrderBy(h => h.Value); var result = 0; //Compare the hands with no sets switch (pokerHandType) { case PokerHandType.StraightFlush: case PokerHandType.Straight: case PokerHandType.Flush: case PokerHandType.HighCard: return(ComparePokerHands(pokerHand1.Cards, pokerHand2.Cards)); } //Find sets of cards with same value: KK QQQ List <Card> hand1SameCardSet1, hand1SameCardSet2, hand2SameCardSet1, hand2SameCardSet2; FindSetsOfCardsWithSameValue( pokerHand1, out hand1SameCardSet1, out hand1SameCardSet2); FindSetsOfCardsWithSameValue( pokerHand2, out hand2SameCardSet1, out hand2SameCardSet2); //Comparing the hands with sets switch (pokerHandType) { case PokerHandType.FullHouse: case PokerHandType.ThreeOfAKind: case PokerHandType.FourOfAKind: case PokerHandType.Pair: result = CompareCards( hand1SameCardSet1.FirstOrDefault(), hand2SameCardSet1.FirstOrDefault()); break; case PokerHandType.TwoPair: //Compare first pair result = CompareCards( hand1SameCardSet1.FirstOrDefault(), hand2SameCardSet1.FirstOrDefault()); if (result == 0) { //Compare second pair result = CompareCards( hand1SameCardSet2[0], hand2SameCardSet2[0]); } break; } if (result != 0) { return(result); } //Compare kickers (side cards) var kicker1 = pokerHand1.Cards.Where(card => !hand1SameCardSet1.Contains(card) && !hand1SameCardSet2.Contains(card)).ToList(); var kicker2 = pokerHand2.Cards.Where(card => !hand2SameCardSet1.Contains(card) && !hand2SameCardSet2.Contains(card)).ToList(); return(ComparePokerHands(kicker1, kicker2, kicker1.Count() - 1)); }
/// <summary> /// Renders a verdict based on the provided hands. /// /// Both hands must not be null and contain more than zero cards. Otherwise, /// the verdict will be rendered as a tie and no other values on it will be set. /// </summary> /// <param name="LeftHand">The first hand to be compared.</param> /// <param name="RightHand">The second hand to be compared.</param> /// <returns>The judgement of the provided hands.</returns> public PokerHandVerdict Judge(PokerHand LeftHand, PokerHand RightHand) { PokerHandVerdict verdict = verdictFactory(); verdict.VerdictType = PokerHandVerdictType.Tie; if (LeftHand != null && LeftHand.Cards.Count > 0 && RightHand != null && RightHand.Cards.Count > 0) { // It is safe to assume that these values are set since both // hands have cards in them. PokerHandType leftHandType = LeftHand.DetermineHandType().Value; PokerHandType rightHandType = RightHand.DetermineHandType().Value; bool leftHandWins = false; bool isTie = false; KeyValuePair <int, KeyValuePair <Card, Card>?>?compareResult = null; // If the two hands are of differing types, simply compare those types. if (leftHandType != rightHandType) { leftHandWins = leftHandType > rightHandType; verdict.DecidingHandTypePair = new KeyValuePair <PokerHandType, PokerHandType>( leftHandWins ? leftHandType : rightHandType, leftHandWins ? rightHandType : leftHandType); verdict.VerdictType = PokerHandVerdictType.WinByHandType; } // If the two hands are of the same type, tie-breakers need to be considered. else { Dictionary <CardRank, List <Card> > leftHandRanked = LeftHand.GroupCardsByRank(); Dictionary <CardRank, List <Card> > rightHandRanked = RightHand.GroupCardsByRank(); switch (leftHandType) { case PokerHandType.Flush: case PokerHandType.None: case PokerHandType.Straight: case PokerHandType.StraightFlush: compareResult = Compare(LeftHand.Cards, RightHand.Cards); if (compareResult.Value.Key == 0) { isTie = true; } else { verdict.VerdictType = leftHandType != PokerHandType.None ? PokerHandVerdictType.WinByInTypeOrdering : PokerHandVerdictType.WinByExtraTypeOrdering; } break; case PokerHandType.FourOfAKind: case PokerHandType.ThreeOfAKind: compareResult = Compare( GetCardListOfSize( leftHandRanked, leftHandType == PokerHandType.ThreeOfAKind? 3 : 4), GetCardListOfSize( rightHandRanked, leftHandType == PokerHandType.ThreeOfAKind? 3 : 4)); verdict.VerdictType = PokerHandVerdictType.WinByInTypeOrdering; break; case PokerHandType.FullHouse: compareResult = Compare( GetCardListOfSize( leftHandRanked, PokerHand.NumberOfCardsInMajorityOfFullHouse), GetCardListOfSize( rightHandRanked, PokerHand.NumberOfCardsInMajorityOfFullHouse)); verdict.VerdictType = PokerHandVerdictType.WinByInTypeOrdering; break; case PokerHandType.Pair: // First the cards that make up the pair are considered. compareResult = Compare( GetCardListOfSize(leftHandRanked, 2), GetCardListOfSize(rightHandRanked, 2)); if (compareResult.Value.Key != 0) { verdict.VerdictType = PokerHandVerdictType.WinByInTypeOrdering; } // If this doesn't give a decision about which is better, // consider the rest of the cards next. else { compareResult = Compare( GetCardListOfSize(leftHandRanked, 1), GetCardListOfSize(rightHandRanked, 1)); // If these are also the same, the result is a tie if (compareResult.Value.Key == 0) { isTie = true; } else { verdict.VerdictType = PokerHandVerdictType.WinByExtraTypeOrdering; } } break; case PokerHandType.TwoPair: // First, compare the results of the higher of each hands pairs. compareResult = Compare( leftHandRanked .Where(entry => entry.Value.Count == 2) .Last() .Value, rightHandRanked .Where(entry => entry.Value.Count == 2) .Last() .Value); if (compareResult.Value.Key != 0) { verdict.VerdictType = PokerHandVerdictType.WinByInTypeOrdering; } else { // If the higher pairs are the same, compares the lower pairs. compareResult = Compare( leftHandRanked .Where(entry => entry.Value.Count == 2) .First() .Value, rightHandRanked .Where(entry => entry.Value.Count == 2) .First() .Value); if (compareResult.Value.Key != 0) { verdict.VerdictType = PokerHandVerdictType.WinByInTypeOrdering; } else { // If both pairs are equal, compares the remaining card(s) compareResult = Compare( GetCardListOfSize(leftHandRanked, 1), GetCardListOfSize(rightHandRanked, 1)); if (compareResult.Value.Key == 0) { isTie = true; } else { verdict.VerdictType = PokerHandVerdictType.WinByExtraTypeOrdering; } } } break; } } if (!isTie) { if (compareResult != null) { leftHandWins = compareResult.Value.Key > 0; verdict.DecidingCardPair = new KeyValuePair <Card, Card>( // This is a bit confusing since both KeyValuePairs and nullable type // are being used but the chain of values sorts through the objects like: // Nullable compare result -> non-nullable -> Nullable card pair -> non-nullable compareResult.Value.Value.Value.Key, compareResult.Value.Value.Value.Value); } verdict.WinningHand = leftHandWins ? LeftHand : RightHand; } } return(verdict); }
/// <summary> /// Determines whether or not this player's hand contains /// cards that make up the requested hand type. /// </summary> /// <param name="HandType">The type of hand for which the test is being run.</param> /// <returns>True if this hand contains the requested type. Otherwise, false.</returns> public bool ContainsHandType(PokerHandType HandType) { bool containsHandType = false; if(Cards.Count > 0) { switch(HandType) { case PokerHandType.Flush: containsHandType = ContainsFlush(); break; case PokerHandType.FourOfAKind: containsHandType = GroupCardsByRank().Values.Where(cards => cards.Count >= 4).Count() > 0; break; case PokerHandType.FullHouse: Dictionary<CardRank, List<Card>> cardsByRank = GroupCardsByRank(); cardsByRank .Keys .Where( majorityRank => cardsByRank[majorityRank].Count >= NumberOfCardsInMajorityOfFullHouse) .ToList() // Each of the ranks that reach this portion of the query will have 3 or // more of that rank in the current hand. .ForEach(majorityRank => { if(cardsByRank .Keys .Where( minorityRank => minorityRank != majorityRank && cardsByRank[minorityRank].Count >= NumberOfCardsInMinorityOfFullHouse) // If another rank exists (other than the majority rank) which has two // or more cards of that rank in the current hand, we have a full house. .Count() > 0) { containsHandType = true; } }); break; case PokerHandType.None: containsHandType = // Covers: pair, two pair, three of a kind, four of a kind, full house !ContainsHandType(PokerHandType.Pair) && // Covers: straight & straight flush !ContainsHandType(PokerHandType.Straight) && // Covers: flush & straight flush !ContainsHandType(PokerHandType.Flush); break; case PokerHandType.Pair: containsHandType = GroupCardsByRank().Values.Where(cards => cards.Count >= 2).Count() > 0; break; case PokerHandType.Straight: containsHandType = FindFirstCardInStraight() != null; break; case PokerHandType.StraightFlush: Card firstCardInStraight = FindFirstCardInStraight(); if(firstCardInStraight != null && firstCardInStraight.Rank != null && firstCardInStraight.Rank.HasValue && firstCardInStraight.Suit != null && firstCardInStraight.Suit.HasValue) { bool straightFlushStillInPlay = true; // Verifies that the rest of the cards in the straight are a flush. for(int straightCardsInspected = 1; straightCardsInspected < NumberOfCardsInAFlushOrStraight; straightCardsInspected++) { if (!ContainsCard( // This casting is safe to do because we've already determined that the // hand contains a straight and that means that the lowest card in // that straight will always be low enough that sum being calculated here // will fall within the enumeration's value. (CardRank)((int)firstCardInStraight.Rank.Value + straightCardsInspected), firstCardInStraight.Suit.Value)) { straightFlushStillInPlay = false; } } containsHandType = straightFlushStillInPlay; } break; case PokerHandType.ThreeOfAKind: containsHandType = GroupCardsByRank().Values.Where(cards => cards.Count >= 3).Count() > 0; break; case PokerHandType.TwoPair: containsHandType = GroupCardsByRank().Values.Where(cards => cards.Count >= 2).Count() > 1; break; } } return containsHandType; }
private bool IsHigherValueHand(PokerHandType pokerHandType) { if (IsRoyalFlush()) { return(true); } if (pokerHandType == PokerHandType.StraightFlush) { return(false); } /////////////////////////// if (IsStraightFlush()) { return(true); } if (pokerHandType == PokerHandType.FourOfKind) { return(false); } /////////////////////////// if (IsFourOfKind()) { return(true); } if (pokerHandType == PokerHandType.FullHouse) { return(false); } /////////////////////////// if (IsFullHouse()) { return(true); } if (pokerHandType == PokerHandType.Flush) { return(false); } /////////////////////////// if (IsFlush()) { return(true); } if (pokerHandType == PokerHandType.Straight) { return(false); } /////////////////////////// if (IsStraight()) { return(true); } if (pokerHandType == PokerHandType.ThreeOfKind) { return(false); } /////////////////////////// if (IsThreeOfKind()) { return(true); } if (pokerHandType == PokerHandType.TwoPair) { return(false); } /////////////////////////// if (IsTwoPairs()) { return(true); } if (pokerHandType == PokerHandType.OnePair) { return(false); } /////////////////////////// if (IsOnePair()) { return(true); } return(false); }