Skip to content

Instantly share code, notes, and snippets.

Created Sep 26, 2014
What would you like to do?
2048 core engine in clojure (based on
(defn transpose [m]
(apply mapv vector m))
(defn rotate-left [m]
(apply mapv vector (map reverse m)))
(defn- combine [[x y & xs :as row]]
(cond (empty? row) nil
(nil? y) (list x)
(= x y) (cons (* x 2) (combine xs))
:else (cons x (combine (cons y xs)))))
(defn merge-row [row]
(let [merged (combine (filter (comp not zero?) row))
padding (repeat (- (count row) (count merged)) 0)]
(vec (concat merged padding))))
(defn move-left [grid]
(mapv merge-row grid))
(defn move-right [grid]
(mapv (comp vec reverse merge-row reverse) grid))
(defn move-up [grid]
(-> grid transpose move-left transpose))
(defn move-down [grid]
(-> grid transpose move-right transpose))
(def board (vec (repeat 4 [0 0 0 0])))
(defn get-zeroes [grid]
(let [coordinates (mapcat #(map vector (repeat 4 %) (range 4)) (range 4))]
(filter #(zero? (get-in grid %)) coordinates)))
(defn is-move-left? [grid]
(let [moves [move-left move-right move-up move-down]
choices (map (fn [move]
(count (get-zeroes (move grid)))) moves)]
(> (reduce + choices) 0)))
(defn add-tile [grid]
(let [candidates (get-zeroes grid)
pos (rand-nth candidates)
value (rand-nth [2 2 2 2 2 2 2 2 2 4])]
(assoc-in grid pos value)))
(-> board add-tile move-left add-tile move-right))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment