In this project, you are a player in a game of Texas hold'em. The cards have been dealt, and you want to know the odds that no other player at the table has a better hand. To do this, you're going to need to know (a) how to play poker, including specifically (b) how to compare two poker hands, and (c) how to enumerate all possible hands your competitors might have in order to compute your odds of winning.

For the purposes of this assignment, here's how the game works. (We're ignoring the rounds of betting and dealing.) There are five cards revealed on the table (the "community" cards). There are two cards in your hand (the "hole" cards). That's seven, from which you will choose the optimal five-card hand. (A poker hand is always five cards.) Each other player uses those same community cards plus the two cards they have in their own hand (hidden from you). Whoever can produce the best five-card hand wins.

Note: everyone here knows how to find the best five-card hand, so this will not be a game of strategy. You just want to know, given the cards available, how likely your hand is to win.

Wikipedia's article on poker hands is a good place to learn about hands and their ranking. (Also useful: this summary and Wikipedia on Texas hold'em.)

Here's a brief version of how to compare two five-card poker hands.

- Straight flush > 4 of a kind > full house > flush > straight > 3 of a kind > two pair > one pair > nothing (a.k.a. "high card")
- If two hands have the same "label" (above), then the hands are compared according to the ranks of their cards. For example, if there are no pairs, then compare the highest-ranking cards from each hand; if they tie, check the next highest rank, and so on. Another example: if there is 3 of a kind, first check the ranks of the 3 matching cards; if they are equal for both players, check the highest non-paired card; and if they are equal, the remaining card. Ties are also possible.
- Suits don't matter at all. The only time you look at suits is to determine if you have a flush (all cards the same suit). If you have two flushes that are identical ranks but different suits, then they tie.
- Aces are high (Ace > King). Except they can be low in a straight: 5-4-3-2-A.

They work how you would think. You can see 7 cards. There are 45 other cards in the deck, and each of the *b* other players has 2 of them. For example, if there are two other players, you could look at _{45}C_{2} * _{43}C_{2} configurations.

Notice that in this example, if player 1 has cards {1, 2} and player 2
has {3, 4}, it's all the same to you as if player 1 had {3, 4} and
player 2 had {1, 2}. We don't need to distinguish who has what. So
above, we actually double counted the configurations. But it's tricky
to not double count; it would work differently for each *b*. It's
okay not to worry about that here; as long as we're overcounting each
configuration equally many times, the probabilities will come out
right. Extra credit if you find and implement a solution that reduces
the overcounting of the method shown above.

You are provided a code base that knows a few things about poker.

- It knows what a card is (from a number 1-52), and its rank and suit.
- It knows that a seven-card hand contains a best five-card hand; it can check for flushes and straights and reason about them; and, it can do most of the work of extracting the best hand and comparing two five-card hands.
But, it relies on a pre-processing step to make it easier to reason
about the hands: computing what's called the "shape" of the
hand.
**You'll need to implement this before the code about hands will work.**Two methods: FiveCardHand.computeShape() and RankAndFreq.compareTo(). There are test cases coded up (in Deal.java) that will help you check your work. Don't assume they are exhaustive. You may want to add your own.

The second (and larger) part of the assignment is to implement `Deal.computeOdds()`

-- iterate through possible hands of the other players to compute the probability that you have the highest hand (where a tie != highest). The input to the program will be your cards, the community cards, and the number of other players. The output will be your probability of winning.

For computeOdds(), you will need to write a helper function that takes a set and shifts it over: mapToAvailableCards(). For example, if 7 cards have already been dealt--say, the Ace through 7 of spades--and we are choosing two more from the remaining pool of 45, the function needs to map from the range 1-45 to the 45 available card values.

In general, add any extra methods you find helpful, but be cautious about changing the existing code unless you're sure you know what you're doing.

The 5 java files needed for this assignment are in a folder called
`proj2`

in the
`cs240`

directory of the edlab machines. To get to it, use this link to the ftp server, or see the edlab main page for other ways to connect.

While you're there, you can also download a working version of
`proj1`

, in case you need one. As we've mentioned, this code could help you solve
some problems on HW#2 if you don't trust your own code.

Submit the 5 completed java files to the `cs240`

folder of
your own home directory by midnight on Wednesday, March 25, 2009.