Skip to content

Instantly share code, notes, and snippets.

@paddycakes
Last active December 29, 2015 19:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paddycakes/7720394 to your computer and use it in GitHub Desktop.
Save paddycakes/7720394 to your computer and use it in GitHub Desktop.
Score a poker hand using Clojure
;; This returns a list of 52 maps
(def deck
"Represents a deck of 52 poker cards."
(for [suit [:clubs :hearts :spades :diamonds]
pip (range 2 15)]
{:suit suit
:pip pip}))
(defn get-hand
"Return a poker hand of 5 cards."
[]
(take 5 (shuffle deck)))
;; Used for testing
(def test-hand
'({:suit :diamonds, :pip 6} {:suit :spades, :pip 6} {:suit :hearts, :pip 6} {:suit :spades, :pip 4} {:suit :hearts, :pip 4}))
;; Functions to test for various scoring hands
(defn n-of-a-kind?
"Returns true if the hand contains
n of the same kind. Nil otherwise."
[hand n]
(some #(= % n) (vals (frequencies (map :pip hand)))))
(n-of-a-kind? test-hand 2)
(defn two-of-a-kind?
"Returns true if the hand contains
two of the same kind. Nil otherwise."
[hand]
(n-of-a-kind? hand 2))
(two-of-a-kind? test-hand)
(defn two-pair?
"Returns true if the hand contains 2
different pairs. Nil otherwise."
[hand]
(= 2 (count (filter (fn [n] (= n 2)) (vals (frequencies (map :pip hand)))))))
(two-pair? test-hand)
(defn three-of-a-kind?
"Returns true if the hand contains
three of the same kind. Nil otherwise."
[hand]
(n-of-a-kind? hand 3))
(three-of-a-kind? test-hand)
(defn straight?
"Returns true if the hand contains cards
that form a sequence. Nil otherwise."
[hand]
(let [in-order (sort (map :pip hand))]
(= (- (last in-order) (first in-order)) 4)))
(straight? test-hand)
(defn flush?
"Returns ture if the hand contains only
cards of the same suit. Nil otherwise."
[hand]
(let [first-card (first hand)]
(every? #(= (:suit first-card) (:suit %)) (rest hand))))
(flush? test-hand)
(defn full-house?
"Returns true if the hand contains 2 of the same
kind and 3 of the same kind. Nil otherwise."
[hand]
(and (n-of-a-kind? hand 2) (n-of-a-kind? hand 3)))
(full-house? test-hand)
(defn four-of-a-kind?
"Returns true if the hand contains
four of the same kind. Nil otherwise."
[hand]
(n-of-a-kind? hand 4))
(four-of-a-kind? test-hand)
(defn straight-flush?
"Returns true if the hand is both a
flush and a straight. Nil otherwise."
[hand]
(and (flush? hand) (straight? hand)))
(straight-flush? test-hand)
(defn royal-flush?
"Returns true if the hand is an ace-high
straight flush. Nil otherwise."
[hand]
(and (flush? hand) (straight? hand) (every? #(> (:pip %) 10) hand)))
(royal-flush? test-hand)
(defn score-hand
"Output the best score for this hand."
[hand]
(cond
(royal-flush? hand) "Royal Flush"
(straight-flush? hand) "Straight Flush"
(four-of-a-kind? hand) "Four of a Kind"
(full-house? hand) "Full House"
(flush? hand) "Flush"
(straight? hand) "Straight"
(three-of-a-kind? hand) "Three of a Kind"
(two-pair? hand) "Two Pair"
(two-of-a-kind? hand) "One Pair"
:else "High Card"))
(score-hand test-hand)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment