public void FiveCardStudScoreTest_ThreeOfAKind() { var hand = new PlayingCardHand(); hand.SetCards(new[] { new PlayingCard(Suit.Clubs, CardValue.Ace), new PlayingCard(Suit.Diamonds, CardValue.Ace), new PlayingCard(Suit.Hearts, CardValue.Ace), new PlayingCard(Suit.Hearts, CardValue.Two), new PlayingCard(Suit.Spades, CardValue.Three) }); var expectedRank = new int[] { (int)CardValue.Ace, (int)CardValue.Ace, (int)CardValue.Ace, (int)CardValue.Three, (int)CardValue.Two, }; var score = new FiveCardStudScore(hand); Assert.AreEqual(HandType.ThreeOfAKind, score.HandType); Assert.IsTrue(expectedRank.SequenceEqual(score.Rank)); }
public void FiveCardStudScoreTest_StraightFlush() { var hand = new PlayingCardHand(); hand.SetCards(new[] { new PlayingCard(Suit.Hearts, CardValue.Ten), new PlayingCard(Suit.Hearts, CardValue.King), new PlayingCard(Suit.Hearts, CardValue.Queen), new PlayingCard(Suit.Hearts, CardValue.Jack), new PlayingCard(Suit.Hearts, CardValue.Ace) }); var expectedRank = new int[] { (int)CardValue.Ace, (int)CardValue.King, (int)CardValue.Queen, (int)CardValue.Jack, (int)CardValue.Ten }; var score = new FiveCardStudScore(hand); Assert.AreEqual(HandType.StraightFlush, score.HandType); Assert.IsTrue(expectedRank.SequenceEqual(score.Rank)); }
public void Convert_ThrowsArgumentExceptionWhenPassedNull() { try { PlayingCardHand playingCardHand = _playingCardHandConverter.Convert(new List <string>()); } catch (Exception e) { Assert.IsTrue(e is ArgumentException); Assert.AreEqual("No card strings were provided to the converter.", e.Message); return; } Assert.Fail("No Exception Was Thrown."); }
public void FiveCardStudScoreTest_InvalidHand() { var invalidCardValues = new CardValue[] { CardValue.AceLow, CardValue.None, CardValue.Joker }; var invalidSuits = new Suit[] { Suit.None, Suit.JokerOne, Suit.JokerTwo }; var hand = new PlayingCardHand(); for (var i = 0; i < invalidCardValues.Length; i++) { try { hand.SetCards(new[] { new PlayingCard(Suit.Hearts, CardValue.Ten), new PlayingCard(Suit.Hearts, CardValue.King), new PlayingCard(Suit.Hearts, CardValue.Queen), new PlayingCard(Suit.Hearts, CardValue.Jack), new PlayingCard(Suit.Hearts, invalidCardValues[i]) }); var score = new FiveCardStudScore(hand); } catch (Exception e) { continue; } Assert.Fail("Expected Exception Not Thrown!"); } for (var i = 0; i < invalidSuits.Length; i++) { try { hand.SetCards(new[] { new PlayingCard(Suit.Hearts, CardValue.Ten), new PlayingCard(Suit.Hearts, CardValue.King), new PlayingCard(Suit.Hearts, CardValue.Queen), new PlayingCard(Suit.Hearts, CardValue.Jack), new PlayingCard(invalidSuits[i], CardValue.Ace) }); var score = new FiveCardStudScore(hand); } catch (Exception e) { continue; } Assert.Fail("Expected Exception Not Thrown!"); } }
private static bool IsValid(PlayingCardHand hand) { if (hand.CardsByCount.Any(kvp => kvp.Key.Suit == Suit.JokerOne || kvp.Key.Suit == Suit.JokerTwo || kvp.Key.Suit == Suit.None || kvp.Key.CardValue == CardValue.AceLow || kvp.Key.CardValue == CardValue.Joker || kvp.Key.CardValue == CardValue.None)) { return(false); } if (hand.CardsByCount.Sum(kvp => kvp.Value) != 5) { return(false); } return(true); }
public void Convert_ConvertsHandSuccessfully() { string[] cardStrings = new[] { "2H", "3H", "4H", "5H", "6H" }; PlayingCardHand playingCardHand = _playingCardHandConverter.Convert(cardStrings); PlayingCard twoOfHearts = new PlayingCard(Suit.Hearts, CardValue.Two); PlayingCard threeOfHearts = new PlayingCard(Suit.Hearts, CardValue.Three); PlayingCard fourOfHearts = new PlayingCard(Suit.Hearts, CardValue.Four); PlayingCard fiveOfHearts = new PlayingCard(Suit.Hearts, CardValue.Five); PlayingCard sixOfHearts = new PlayingCard(Suit.Hearts, CardValue.Six); Assert.IsTrue(playingCardHand.CardsByCount.ContainsKey(twoOfHearts)); Assert.IsTrue(playingCardHand.CardsByCount.ContainsKey(threeOfHearts)); Assert.IsTrue(playingCardHand.CardsByCount.ContainsKey(fourOfHearts)); Assert.IsTrue(playingCardHand.CardsByCount.ContainsKey(fiveOfHearts)); Assert.IsTrue(playingCardHand.CardsByCount.ContainsKey(sixOfHearts)); Assert.IsTrue(playingCardHand.CardsByCount.Keys.Count == 5); }
public PlayingCardHand Convert(IEnumerable <string> handAsCardStrings) { if (handAsCardStrings == null) { throw new ArgumentNullException(); } if (!handAsCardStrings.Any()) { throw new ArgumentException("No card strings were provided to the converter."); } var playingCards = handAsCardStrings.Select(s => _playingCardConverter.Convert(s)); var playingCardHand = new PlayingCardHand(); playingCardHand.SetCards(playingCards); return(playingCardHand); }
public void SetCardsTest() { PlayingCard aceOfClubs = new PlayingCard(Suit.Clubs, CardValue.Ace); PlayingCard threeOfHearts = new PlayingCard(Suit.Hearts, CardValue.Three); PlayingCard[] playingCards = new [] { aceOfClubs, aceOfClubs, threeOfHearts }; PlayingCardHand hand = new PlayingCardHand(); Assert.IsNull(hand.CardsByCount); hand.SetCards(playingCards); Assert.AreEqual(2, hand.CardsByCount[aceOfClubs]); Assert.AreEqual(1, hand.CardsByCount[threeOfHearts]); PlayingCard threeOfHearts2 = new PlayingCard(Suit.Hearts, CardValue.Three); playingCards = new [] { threeOfHearts, threeOfHearts2 }; hand.SetCards(playingCards); Assert.IsFalse(hand.CardsByCount.ContainsKey(aceOfClubs)); Assert.AreEqual(2, hand.CardsByCount[threeOfHearts]); }
public FiveCardStudScore(PlayingCardHand hand) { if (!IsValid(hand)) { throw new ArgumentException("The hand being scored is invalid."); } _countsBySuit = new Dictionary <Suit, int>() { { Suit.Clubs, 0 }, { Suit.Diamonds, 0 }, { Suit.Hearts, 0 }, { Suit.Spades, 0 } }; _valuesByCount = new Dictionary <int, HashSet <CardValue> >() { { 1, null }, { 2, null }, { 3, null }, { 4, null } }; Hand = hand; var cards = hand.CardsByCount.Select(kvp => kvp.Key).OrderByDescending(c => c.CardValue); foreach (var suit in _countsBySuit.Keys.ToList()) { _countsBySuit[suit] = cards.Count(c => c.Suit == suit); } foreach (var count in _valuesByCount.Keys.ToList()) { var values = new HashSet <CardValue>(); values.UnionWith(cards.Select(c => c.CardValue).Where(v => cards.Count(c => c.CardValue == v) == count)); _valuesByCount[count] = values; } //Check for Four Of A Kind first as it is the easier to determine than a Straight Flush due to the Dictionary if (IsAFourOfAKind) { HandType = HandType.FourOfAKind; int fourOfAKindRank = (int)_valuesByCount[4].Single(); int leftoverRank = (int)_valuesByCount[1].Single(); Rank = new int[] { fourOfAKindRank, fourOfAKindRank, fourOfAKindRank, fourOfAKindRank, leftoverRank }; //We can't possibly have a straight flush if we have four of a kind so there's no need to look for anything else return; } bool threeOfAKindFound = false; int threeOfAKindRank = -1; //Next, check for Full House as we need to check for Three of a Kind first and that is easy to determine with the Dictionary //Although the Flush is easier to check for, //Also, even if we don't have a Full House we can memoize the check for the Three of a Kind, giving us helpful information going forward if (IsAThreeOfAKind) { threeOfAKindFound = true; threeOfAKindRank = (int)_valuesByCount[3].Single(); if (_valuesByCount[2].Any()) { var remainingTwoOfAKindRank = (int)_valuesByCount[2].Single(); HandType = HandType.FullHouse; Rank = new int[] { threeOfAKindRank, threeOfAKindRank, threeOfAKindRank, remainingTwoOfAKindRank, remainingTwoOfAKindRank }; //We can't possibly have a straight flush if we have a full house so there's no need to look for anything else return; } } //We check for a Flush next as it is also easy to determine using the dictionary //Also, we can avoid the iteration in isAStraight on the off-chance we also have a Three of a Kind if (IsAFlush) { HandType = HandType.Flush; Rank = cards.Select(c => (int)c.CardValue).ToArray(); if (threeOfAKindFound) { //We can't possibly have a straight flush if we have three of a kind so there's no need to check return; } if (IsAStraight(cards)) { HandType = HandType.StraightFlush; return; } return; } if (threeOfAKindFound) { HandType = HandType.ThreeOfAKind; var remainingCardsValues = _valuesByCount[1].OrderByDescending(v => v).ToArray(); Rank = new int[] { threeOfAKindRank, threeOfAKindRank, threeOfAKindRank, (int)remainingCardsValues[0], (int)remainingCardsValues[1] }; //We can't possibly have a straight if we have three of a kind so there's no need to check return; } //We'll check for Two Pair next, and we'll save our first found pair in case we only have One Pair if (IsTwoPair) { HandType = HandType.TwoPair; int firstPairRank = (int)_valuesByCount[2].First(); int lastPairRank = (int)_valuesByCount[2].Last(); var highTwoOfAKindRank = firstPairRank > lastPairRank ? firstPairRank : lastPairRank; var lowTwoOfAKindRank = highTwoOfAKindRank == firstPairRank ? lastPairRank : firstPairRank; var remainingCardRank = (int)_valuesByCount[1].Single(); Rank = new int[] { highTwoOfAKindRank, highTwoOfAKindRank, lowTwoOfAKindRank, lowTwoOfAKindRank, remainingCardRank }; // We can't possibly have a straight if we have two pair so there's no need to check return; } if (IsOnePair) { var onePairRank = (int)_valuesByCount[2].Single(); var remainingCardValues = _valuesByCount[1].OrderByDescending(v => v).ToArray(); Rank = new int[] { onePairRank, onePairRank, (int)remainingCardValues[0], (int)remainingCardValues[1], (int)remainingCardValues[2] }; HandType = HandType.OnePair; // We can't possibly have a straight if we have a pair so there's no need to check return; } //Whether we have a straight or high-card we already know the ranking is the same (unless it's an Ace-Low Straight Rank = cards.Select(c => (int)c.CardValue).ToArray(); if (IsAStraight(cards)) { HandType = HandType.Straight; return; } //Check for Ace-Low Straight if (cards.Any(pc => pc.CardValue == CardValue.Ace)) { var aceLowHand = cards.Select(pc => pc.CardValue == CardValue.Ace ? new PlayingCard(pc.Suit, CardValue.AceLow) : pc).OrderByDescending(pc => pc.CardValue); if (IsAStraight(aceLowHand)) { HandType = HandType.Straight; Rank = aceLowHand.Select(c => (int)c.CardValue).ToArray(); return; } } HandType = HandType.HighCard; return; }
public void Convert_ThrowsArgumentNullExceptionWhenPassedNull() { PlayingCardHand playingCardHand = _playingCardHandConverter.Convert(null); }