I don’t think I’d have four lists. Without having dug into this in any detail, I’d say you should start with a PlayingCard class, which has the following fields:
public class PlayingCard {
public CardSuit Suit {get;set;}
public int FaceValue {get;set;}
}
public enum CardSuit {
Hearts,
Diamonds,
Spades,
Clubs
}
(Disclaimer: I haven’t tested any of this code, so there may be errors…)
There are probably articles out there on how to do the actual analysis of a “hand”, so I’d probably just google that. If I were going to approach it from scratch, the most complicated aspect seems to be breaking ties. For example, if two players both had a pair of 10s, you have to look at the rest of their cards to break the tie. With a total of five cards in a hand, and a face value ranging from 2 to 14 (2 through Ace), I’d want to build a ranking algorithm that would provide a numeric score for each hand, which properly accounts for ties and kickers. This means a system that determines numeric score where three of a kind always has a higher value than a pair, but three 6s are always better than three 5s. This is where there are probably a lot of elegant solutions, but let’s create a HandRank class, which is what stores the “value” of the hand, which can be compared to other hands. Each different kind of hand has a primary ranking value that determines whether it beats other kinds of hands. And for two hands of the same primary ranking value, there are other criteria for breaking ties. So let’s just say that any given ranking can have multiple levels of comparison.
public class HandRank {
public int Rank1Value {get;set;}
public int Rank2Value {get;set;}
public int Rank3Value {get;set;}
public int Rank4Value {get;set;}
public int Rank5Value {get;set;}
public int Rank6Value {get;set;}
// Maybe more ranks for more complex hands?
public int CompareTo(HandRank other) {
if (this.Rank1Value == other.Rank1Value) {
if (this.Rank2Value == other.Rank2Value) {
// Etc...for the remaining ranks.
} else {
return this.Rank2Value.CompareTo(other.Rank2Value);
}
} else {
return this.Rank1Value.CompareTo(other.Rank1Value);
}
}
}
Now you’d need to generate a HandRank for any given Hand. The Rank1Value would be based on the kind of hand:
- High Card: 0
- Pair: 1
- Two Pair: 2
- Three of a Kind: 3
- Straight: 4
- Flush: 5
- Full House: 6
- Four of a Kind: 7
- Straight Flush: 8
Next, for each hand type, you’d have to follow the rules of poker to determine how to evaluate the 2nd, 3rd, etc ranks. Let’s do a couple of examples.
- 7h 7d 3c Kh 5c - We have a pair of sevens, with a King kicker. So out Rank1Value is “1”. The Rank2 value will be the value of our next highest card, which is “13”. Then “5”, then “3”. So this hand would have four ranking values, “1”, “13”, “5”, “3”. The 5th ranking value remains 0.
- 4h 4c 6c 6d 9 - We have two pairs. The Rank1Value is “2”. Next we get the value of the highest pair, and call that our Rank2Value. So, “6”. Next the value of the 2nd pair, “4”. And finally the kicker value, “9”. So our ranking values are “2”, “6”, “4”, “9”. Again, the 5th ranking value remains 0.
- 2c 3s 5s 6h 8d - We have nothing, just a high card. So our primary ranking is “0”. Rankings 2 through 6 are just the face values of the cards, in descending orders, giving us a final set of Ranking values of: “0”, “8”, “6”, “5”, “3”, “2”.
- 4h 6h 9h 10h Kh - We have a flush. So, the Rank1Value is 5. The remaining values 2 through 6 are the face values of the cards. So, we have “6”, “13”, “10”, “9”, “6”, “4”.
Note that you can still have ties, which will come out to have the same ranking value, and return “0” from the CompareTo function.
As for what may be the heart of your question, of how you actually process the hands, given that you have 7 cards from which you muct pick 5, I would just approach that naively by iterating through the combinations, and keeping track of the max hand rank value. So, for each distinct combination of 5 cards, perform the hand rank, and compare it to the highest hand rank found so far. Keep the winner.
Again, I’d just google this sort of thing in case someone has a dead simple class you can use for this…