Skip to content

Instantly share code, notes, and snippets.

@mguinada
Forked from cgrand/set-game.clj
Created May 10, 2017 09:18
Show Gist options
  • Save mguinada/adc7676b73869d20c931ee1038a9c93c to your computer and use it in GitHub Desktop.
Save mguinada/adc7676b73869d20c931ee1038a9c93c to your computer and use it in GitHub Desktop.
the SET game in clojure.spec
;; the SET game in clojure.spec
;; inspired by https://github.com/jgrodziski/set-game
(require '[clojure.spec :as s])
(s/def ::shape #{:oval :diamond :squiggle})
(s/def ::color #{:red :purple :green})
(s/def ::value #{1 2 3})
(s/def ::shading #{:solid :striped :outline})
(s/def ::card (s/keys :req [::shape ::color ::value ::shading]))
(s/def ::deck (s/coll-of ::card :distinct true :max-count 12 :min-count 12))
(defn unique-or-distinct [feature]
#(not= 2 (count (into #{} (map feature) %)))) ; assumes 3-item set
(s/def ::set
(s/and
(s/coll-of ::card :min-count 3 :max-count 3 :distinct true :into #{})
(unique-or-distinct ::shape)
(unique-or-distinct ::color)
(unique-or-distinct ::value)
(unique-or-distinct ::shading)))
(defn deal []
(first (clojure.test.check.generators/sample (s/gen ::deck) 1)))
(defn sets [deck]
(into #{}
(for [carda deck cardb deck cardc deck
:let [s (hash-set carda cardb cardc)]
:when (s/valid? ::set s)]
s)))
;;;;;; repl
=> (sets (deal))
#{#{#:user{:shape :oval, :color :purple, :value 1, :shading :outline}
#:user{:shape :diamond, :color :red, :value 3, :shading :solid}
#:user{:shape :squiggle, :color :green, :value 2, :shading :striped}}
#{#:user{:shape :diamond, :color :green, :value 3, :shading :solid}
#:user{:shape :oval, :color :purple, :value 1, :shading :striped}
#:user{:shape :squiggle, :color :red, :value 2, :shading :outline}}
#{#:user{:shape :diamond, :color :green, :value 3, :shading :solid}
#:user{:shape :oval, :color :purple, :value 2, :shading :solid}
#:user{:shape :squiggle, :color :red, :value 1, :shading :solid}}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment