Reputation: 83
We have to develop a poker game. I have developed all the required functions but I'm stuck with one. It goes: (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.
What I've been able to do is compare the two hands, like:
(defn compare-cards [[v1 s1] [v2 s2]]
(if (= v1 v2)
(compare (suit-value s1) (suit-value s2))
(compare v1 v2)))
(defn sort-cards [cards]
(sort compare-cards cards))
(defn parse-hand [s]
(sort-cards (mapv parse-card (.split s " "))))
(def foo [[:straight straight?] [:high-card high-card?]])
(defn categorize-hand [hand]
(some #(% (parse-hand hand)) (map second foo)))
(defmulti tie-break (fn [h _] (categorize-hand h)))
(defmethod tie-break :high-card [h1 h2]
(drop-while zero? (map compare-cards (reverse h1) (reverse h2))))
(defmethod tie-break :straight [[f1 & _] [f2 & _]]
(compare-cards f1 f2))
(defn compare-hands [hand1 hand2]
(let [category1-value (.indexOf (map first foo) (categorize-hand hand1))
category2-value (.indexOf (map first foo) (categorize-hand hand2))]
(if (= category1-value category2-value)
(tie-break (parse-hand hand1) (parse-hand hand2))
(compare category1-value category2-value))))
But, Im stuck when it comes to comparing the face values one by one to see if the first one is greater. Can anyone help me?
Like I'm doing:
(defn higher-kicker? [
card-ranks-1 card-ranks-2]
(->> (map compare card-ranks-1 card-ranks-2)
(filter #(not (zero? %)))
then what to do after that?
Upvotes: 1
Views: 503
Reputation: 800
Oddly enough I could not find a function that creates a list of pairs from two lists so I rolled my own. Beware zipmap because it does not preserve ordering. That said after that it's all rather simple. Get the first unequal pair. If there aren't any the lists are equal so return false otherwise compare them and return if the first is greater than the second.
(defn make-pairs [list1 list2] (partition 2 (interleave list1 list2)))
(defn pair-not= [[item1 item2]] (not (= item1 item2)))
(defn unequal-pairs [list1 list2] (filter pair-not= (make-pairs list1 list2)))
(defn higher-kicker? [kicker1 kicker2]
(let [unequal-pair (first (unequal-pairs kicker1 kicker2))]
(if unequal-pair
(> (first unequal-pair) (second unequal-pair))
false)))
Upvotes: 1