Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
98 lines (81 sloc) 3.33 KB
(ns farkle-ai.rules
(:gen-class))
(defn n-of-a-kind?
"True if there are n die with a given pip value in the roll. If no pip value
is provided, only check for existence of a group of die size n."
([n value roll]
(let [number-matched (or (get (frequencies roll) value) 0)]
(if (>= number-matched n) true false)))
([n roll]
(let [frequency (frequencies roll)]
(true? (some #(= (val %) n) frequency)))))
(def one-one?
"True if there is one one in the roll."
(partial n-of-a-kind? 1 1))
(def one-five?
"True if there is one five in the roll."
(partial n-of-a-kind? 1 5))
(def three-ones?
"True if there are three ones in the roll."
(partial n-of-a-kind? 3 1))
(def three-twos?
"True if there are three twos in the roll."
(partial n-of-a-kind? 3 2))
(def three-threes?
"True if there are three threes in the roll."
(partial n-of-a-kind? 3 3))
(def three-fours?
"True if there are three fours in the roll."
(partial n-of-a-kind? 3 4))
(def three-fives?
"True if there are three fives in the roll."
(partial n-of-a-kind? 3 5))
(def three-sixes?
"True if there are three sixes in the roll."
(partial n-of-a-kind? 3 6))
(def four-of-a-kind?
"True if there are four matching dice in the roll."
(partial n-of-a-kind? 4))
(def five-of-a-kind?
"True if there are five matching dice in the roll."
(partial n-of-a-kind? 5))
(def six-of-a-kind?
"True if there are six matching dice in the roll."
(partial n-of-a-kind? 6))
(defn straight?
"True if the roll is 1, 2, 3, 4, 5, 6."
[roll]
(if (= (set roll) #{1 2 3 4 5 6}) true false))
(defn three-pairs?
"True if there are three pairs in the roll."
[roll]
(let [groups (frequencies roll)
twoDieInEachGroup? (every? #(= (second %) 2) groups)
threeGroups? (= 3 (count groups))]
(and threeGroups? twoDieInEachGroup?)))
(defn two-three-of-a-kind?
"True if there are two three-of-a-kind in the roll."
[roll]
(let [groups (frequencies roll)
threeDieInEachGroup? (every? #(= (second %) 3) groups)
twoGroups? (= 2 (count groups))]
(and twoGroups? threeDieInEachGroup?)))
(defn score-roll
"Given a roll, return the highest score possible."
[roll]
(cond
(six-of-a-kind? roll) {:score 3000 :dice-used 6 :name "six of a kind"}
(two-three-of-a-kind? roll) {:score 2500 :dice-used 6 :name "two three of a kind"}
(five-of-a-kind? roll) {:score 2000 :dice-used 5 :name "five of a kind"}
(three-pairs? roll) {:score 1500 :dice-used 6 :name "three pairs"}
(straight? roll) {:score 1500 :dice-used 6 :name "a straight"}
(three-ones? roll) {:score 1000 :dice-used 3 :name "three ones"}
(four-of-a-kind? roll) {:score 1000 :dice-used 4 :name "four of a kind"}
(three-sixes? roll) {:score 600 :dice-used 3 :name "three sixes"}
(three-fives? roll) {:score 500 :dice-used 3 :name "three fives"}
(three-fours? roll) {:score 400 :dice-used 3 :name "three fours"}
(three-threes? roll) {:score 300 :dice-used 3 :name "three threes"}
(three-twos? roll) {:score 200 :dice-used 3 :name "three twos"}
(one-one? roll) {:score 100 :dice-used 1 :name "a one"}
(one-five? roll) {:score 50 :dice-used 1 :name "a five"}
:else {:score 0 :dice-used 0 :name "a farkle"}))