Write and test code to evaluate a Poker hand.
You don't need to know Poker; you can think of this as an abstract exercise. While I believe this assignment is self-contained, you can visit the Wikipedia article on Poker hands for more information.
Poker cards have a rank (2, 3, 4, 5, 6, 7, 8, 9, 10, Jack=11, Queen=12, King=13, Ace=14) and a suit (Clubs, Diamonds, Hearts, Spades). A card will be represented by a two character string, the first indicating its rank (use T for 10), and the second indicating its suit. For example, "2C" would be the 2 of Clubs, and "JH" would be the Jack of Hearts. A deck of cards consists of 52 (4*13) cards, all different.
A hand consists of a vector of exactly five cards.
Write and test the following methods:
(suit card) returns the suit of the card, one of "C", "D", "H", "S".(rank card) returns the rank of the card, as an integer in the range 2 to 14. (Hint: Use the Java methods (Character/isDigit char) and (Integer/valueOf string). Use a map to convert the characters T, J, Q, K, A into the numbers 10 through 14.(pair? hand) returns true if the hand contains two (but not more than two) cards of the same rank.(three-of-a-kind? hand) returns true if the hand contains three (but not four) cards of the same rank.(four-of-a-kind? hand) returns true if the hand contains four cards of the same rank.(flush? hand) returns true if all the cards have the same suit, but they are not in sequence.(full-house? hand) returns true if the hand contains three matching cards of one rank and two matching cards of another rank.(two-pairs? hand) returns true if the hand contains two pairs of two different ranks.(straight? hand) returns true if the hand contains five ranks in sequence (for example, ["2H" "3S" "6C" "5D" "4D"]). An Ace may be counted as rank 1 or rank 14.(straight-flush? hand) returns true if the hand is both a straight and a flush.(value hand) returns:
0 for none of the above |
3 for three of a kind |
6 for a full house |
1 for a pair |
4 for a straight |
|
2 for two pairs |
5 for a flush |
8 for a straight flush |
(kickers hand) returns an ordered list of ranks (integers) of the cards, arranged as follows:
(kickers ["2H" "3S" "6C" "5D" "4D"]) returns '(6 5 4 3 2).(kickers ["5H" "AD" "5C" "7D" "AS"]) returns '(14 5 7).frequencies function. All of the above can be summarized as: Higher frequencies first, equal frequencies in descending order. (higher-kicker? kicker1 kicker2) compares the corresponding values in the two kickers, and returns true if the first kicker has the larger value of the first difference, false if the second kicker does, or if the lists are pairwise equal. Example: (higher-kicker? '(8 5 9) '(8 7 3)) should return false, because 8==8 but 7>5. Assume that the two kicker lists are of equal lengths.(beats? hand1 hand2) returns true if the value of the first hand is larger than the value of the second hand, or if the values are equal and the first hand has a higher kicker value than the second hand. Returns nil in all other cases.(winning-hand & hands) returns the winning hand (the one that beats all the others) or, in the case of a tie, a sequence (list or vector) of the tied hands. Returns nil if no hands are given.Useful built-in functions:
(frequencies sequence) gives a map from elements in the sequence to the number of times each element occurs in the sequence.(keys a-map) returns the keys in a map.(vals a-map) returns the values in a map.(max & nums) returns the largest argument (the & indicates zero or more arguments).(min & nums) returns the smallest argument.(apply fun list-of-args) calls the function with the given arguments.(sort a-seq) returns a copy of the sequence with the elements in ascending order.(range lower-bound upper-bound) returns a sequence of integers starting with the lower bound and going up to, but not including, the upper bound.(replace a-map a-sequence) replace each element of the sequence that occurs as a key in the map with the corresponding value.Here are some sample hands you can use for testing.
(def high-seven ["2H" "3S" "4C" "5C" "7D"])
(def pair-hand ["2H" "2S" "4C" "5C" "7D"])
(def two-pairs-hand ["2H" "2S" "4C" "4D" "7D"])
(def three-of-a-kind-hand ["2H" "2S" "2C" "4D" "7D"])
(def four-of-a-kind-hand ["2H" "2S" "2C" "2D" "7D"])
(def straight-hand ["2H" "3S" "6C" "5D" "4D"])
(def low-ace-straight-hand ["2H" "3S" "4C" "5D" "AD"])
(def high-ace-straight-hand ["TH" "AS" "QC" "KD" "JD"])
(def flush-hand ["2H" "4H" "5H" "9H" "7H"])
(def full-house-hand ["2H" "5D" "2D" "2C" "5S"])
(def straight-flush-hand ["2H" "3H" "6H" "5H" "4H"])
(def low-ace-straight-flush-hand ["2D" "3D" "4D" "5D" "AD"])
(def high-ace-straight-flush-hand ["TS" "AS" "QS" "KS" "JS"])
Some of this assignment is "borrowed" from a very good online Clojure course. (Solutions are not provided!
)