patterncsharpMinor
Poker Hand Evaluator, take 2
Viewed 0 times
evaluatorpokerhandtake
Problem
This is following up on my previous attempt, which was admittedly done fast and not-so-well. This code attempts to allow comparing two poker hands to determine a winner, not only evaluating a given set of cards. (this was actually edited - see original take 2 here).
I'm abstracting the dirt away into an interface... and yet it doesn't look very clean to me, but maybe it's just because I don't use
This is my current implementation - it correctly evaluates all 5-card hands, and I've tested it correctly evaluates a Straight Flush (ace low) with a 7-card hand as well. So it works, but it doesn't make a good marketing for
```
public class PokerHandEvaluator : IPokerHandEvaluator
{
private IEnumerable> GroupByNominalValue(IEnumerable cards)
{
return cards.GroupBy(card => card.NominalValue);
}
private IEnumerable> Pairs(IEnumerable cards)
{
return GroupByNominalValue(cards).Where(group => group.Count() == 2);
}
private IEnumerable> Triplets(IEnumerable cards)
{
return GroupByNominalValue(cards).Where(group => group.Count() == 3);
}
private IEnumerable> Suits(IEnumerable cards)
{
return cards.GroupBy(card => card.Suit);
}
public Tuple> IsPair(IEnumerable cards)
{
var pairs = Pairs(cards);
var result = pairs.Count() == 1 && !Triplets(cards).Any();
var winningCards = result ? pairs.SelectMany(group => group.Select(card =
I'm abstracting the dirt away into an interface... and yet it doesn't look very clean to me, but maybe it's just because I don't use
Tuple very often. T1 is a bool indicating whether the hand is matched, T2 contains the winning cards.public interface IPokerHandEvaluator
{
Tuple> IsPair(IEnumerable cards);
Tuple> IsTwoPair(IEnumerable cards);
Tuple> IsThreeOfKind(IEnumerable cards);
Tuple> IsFourOfKind(IEnumerable cards);
Tuple> IsFlush(IEnumerable cards);
Tuple> IsFullHouse(IEnumerable cards);
Tuple> IsStraight(IEnumerable cards);
Tuple> IsStraightFlush(IEnumerable cards);
Tuple> IsRoyalFlush(IEnumerable cards);
}This is my current implementation - it correctly evaluates all 5-card hands, and I've tested it correctly evaluates a Straight Flush (ace low) with a 7-card hand as well. So it works, but it doesn't make a good marketing for
Tuple:```
public class PokerHandEvaluator : IPokerHandEvaluator
{
private IEnumerable> GroupByNominalValue(IEnumerable cards)
{
return cards.GroupBy(card => card.NominalValue);
}
private IEnumerable> Pairs(IEnumerable cards)
{
return GroupByNominalValue(cards).Where(group => group.Count() == 2);
}
private IEnumerable> Triplets(IEnumerable cards)
{
return GroupByNominalValue(cards).Where(group => group.Count() == 3);
}
private IEnumerable> Suits(IEnumerable cards)
{
return cards.GroupBy(card => card.Suit);
}
public Tuple> IsPair(IEnumerable cards)
{
var pairs = Pairs(cards);
var result = pairs.Count() == 1 && !Triplets(cards).Any();
var winningCards = result ? pairs.SelectMany(group => group.Select(card =
Solution
-
The idiomatic way of creating
-
Tuples are great when you want to bunch up some values and pass them around together. Unfortunately the
-
Your
The idiomatic way of creating
Tuples is to use the Create factory method. This should remove a fair amount of type clutter from the code.-
Tuples are great when you want to bunch up some values and pass them around together. Unfortunately the
Tuple properties Item1, Item2, etc. are not very descriptive. You also use the the same type of Tuple in a lot of places so I think the excessive use of it could warrant its own class.-
Your
PokerGame class is a weird abstraction. A poker game consists of 2 or more players, each of them having a hand and the one with the highest wins. Your PokerGame class evaluates only a single hand. PokerPlayer or so might have been a better name.Context
StackExchange Code Review Q#36873, answer score: 7
Revisions (0)
No revisions yet.