Skip to content

Instantly share code, notes, and snippets.

@stianeikeland
Last active August 29, 2015 14:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stianeikeland/c7f2c493ea81b2bcdb35 to your computer and use it in GitHub Desktop.
Save stianeikeland/c7f2c493ea81b2bcdb35 to your computer and use it in GitHub Desktop.
blackjack kata in hy at bergen coding dojo
(require hy.contrib.loop)
(import [random [shuffle]])
(def ranks (+ (range 2 11) [:a :k :q :j]))
(def suits [:h :c :d :s])
;; OH MY IMPERATIVE GAAWD!
(def deck [])
(for [rank ranks
suit suits]
(.append deck
{:rank rank
:suit suit}))
(def values {:a 1
:k 10
:q 10
:j 10})
(defn card-value [x]
(let [[val (:rank x)]]
(.get values val val)))
(defn score [a]
(reduce (fn [a b] (+ a b))
(map card-value a)))
(defn score-players [game]
(let [[out {}]]
(for [[k v] (.items game)]
(assoc out k (score v)))
out))
(defn filter-over-21 [game]
(let [[out {}]]
(for [[k v] (.items game)]
(when (<= v 21)
(assoc out k v)))
out))
(defn decide-winner [game]
(let [[scored-game (-> game
score-players
filter-over-21)]]
(reduce (fn [a b]
(let [[a-score (get scored-game a)]
[b-score (get scored-game b)]]
(cond [(and (= a-score b-score)
(= a :dealer)) a]
[(> a-score b-score) a]
[True b])))
(.keys scored-game))))
(defn get-cards [values]
(map (fn [x] {:suit :h :rank x}) values))
(do
;; Basic scoring
(assert (= 2 (score [{:suit :h :rank 2}])))
(assert (= 5 (score [{:suit :h :rank 2}
{:suit :c :rank 3}])))
(assert (= 5 (score [{:suit :h :rank 2}
{:suit :c :rank 3}])))
;; Score high-cards
(assert (= 10 (score [{:suit :h :rank :j}])))
(assert (= 20 (score [{:suit :h :rank :j}
{:suit :c :rank :k}])))
;; Score multiple players
(let [[game {:cuttles (get-cards [4 5 6])
:dealer (get-cards [2 3 4])}]]
(assert (= {:cuttles 15L
:dealer 9L} (score-players game))))
;; Decide winner
(let [[game {:cuttles (get-cards [4 5 6])
:dealer (get-cards [2 3 4])}]]
(assert (= :cuttles (decide-winner game))))
;; Score over 21 loses
(let [[game {:cuttles (get-cards [4 5 6])
:dealer (get-cards [:j :q :k])}]]
(assert (= :cuttles (decide-winner game))))
;; Dealer wins if both score 21
(let [[game {:cuttles (get-cards [21])
:dealer (get-cards [21])}]]
(assert (= :dealer (decide-winner game)))))
;; (shuffle deck)
;; (def mine (list (take 2 deck)))
;; (def dine (list (take 2 (drop 2 deck))))
;; (score dine)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment