Skip to content

Instantly share code, notes, and snippets.

@jellea
Created January 2, 2015 10:01
Show Gist options
  • Save jellea/179118d0794cba9b85a6 to your computer and use it in GitHub Desktop.
Save jellea/179118d0794cba9b85a6 to your computer and use it in GitHub Desktop.
(def properties [:fill :round :big :black])
(defrecord Piece [^Boolean fill ^Boolean round ^Boolean big ^Boolean black])
(defn gray2 [n]
(loop [nleft n combos '(())]
(if (zero? nleft)
combos
(recur (dec nleft) (concat (map #(conj % true) combos) (map #(conj % false) combos))))))
(def all-pieces
"generate all unique pieces"
(mapv (fn [e] (apply ->Piece e)) (vec (gray2 4))))
(def available (atom all-pieces))
(def grid (atom (vec (take 4 (repeat (vec (take 4 (repeat nil))))))))
(def hand (atom nil))
(def status (atom nil))
(def your-turn (atom true))
(defn switch-user! []
(swap! your-turn not))
(defn choose-piece!
"Move from :available to :hand.
Takes Piece record."
[piece] ;; if piece is still available and it's users turn
(if @your-turn
(do
(swap! available (fn [p] (filter #(not (identical? % piece)) p)))
(reset! hand piece))))
(defn place-piece!
"Move from :hand to :grid.
Takes a [x y] position"
[position]
(if @your-turn
(if (= (count @available) 0)
(println "end game")
(do
(swap! grid assoc-in position @hand)
(reset! hand nil)
(switch-user)))
(println "not your turn, patience")))
(defn all-true-or-false [pieces]
; map over different properties
(not-every? false?
(map (fn [prop]
; check whether _all_ true or false
(if (or (every? true? (map prop pieces))
(every? false? (map prop pieces)))
true false))
properties)))
(defn check-board [board]
(or
;; rows
(not-every? false? (map all-true-or-false board))
;; columns
(map (fn [index]
(map all-true-or-false (vec (map #(nth % index) board)))) (range 4))))
;; Testing switching a user
(switch-user!)
(assert (false? @your-turn))
(switch-user!)
(assert (true? @your-turn))
;; Testing picking a piece
(let [piece (first @available)
numavailable (count @available)]
(choose-piece! (first @available))
(assert (identical? piece @hand))
(println @available)
(assert (= (count @available) (dec numavailable))))
;; Testing placing a piece
(let [piece @hand]
(place-piece! [0 0])
(assert (nil? @hand))
(assert (identical? piece (get-in @grid [0 0]))))
;; Testing detecting 4 in row
(let [all-true-row [(Piece. true false false false) (Piece. true true false false) (Piece. true true true false) (Piece. true true true true)]
all-false-row [(Piece. false false false false) (Piece. false true false false) (Piece. false true true false) (Piece. false true true true)]
nothing-row [(Piece. false false false false) (Piece. true true false false) (Piece. true true true false) (Piece. true true true true)]
missing-row [nil nil nil nil]]
;; check row on true
(assert (all-true-or-false all-true-row))
;; check row on false
(assert (all-true-or-false all-false-row))
;; check row but nothing
(all-true-or-false nothing-row)
(assert (not (all-true-or-false nothing-row)))
;; check row with nils
(assert (not (all-true-or-false missing-row))))
;; Testing a whole board
(let [all-true-row [[(Piece. true false false false) nil (Piece. false false false false) nil] [(Piece. true true false false) (Piece. true false true false) nil nil] [(Piece. true true true false) (Piece. true true false false) nil nil] [(Piece. true true true true) (Piece. true false false true) nil nil]]]
(check-board all-true-row))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment