Skip to content

Instantly share code, notes, and snippets.

@rlb3
Created February 25, 2010 13:16
Show Gist options
  • Save rlb3/314530 to your computer and use it in GitHub Desktop.
Save rlb3/314530 to your computer and use it in GitHub Desktop.
(ns com.rlb3.rps)
(defstruct object :type :verb)
(def rock (struct object :rock "breaks"))
(def paper (struct object :paper "covers"))
(def scissors (struct object :scissors "cuts"))
(def *objects* [rock paper scissors])
(def *object-map* (zipmap [:rock :paper :scissors] *objects*))
(defmulti play (fn [o1 o2] (if (= (:type o1) (:type o2))
:same
[(:type o1) (:type o2)])))
;; rock wins
(defmethod play [:rock :scissors] [o1 o2]
{:winner o1 :loser o2})
(defmethod play [:scissors :rock] [o1 o2]
{:winner o2 :loser o1})
;; paper wins
(defmethod play [:paper :rock] [o1 o2]
{:winner o1 :loser o2})
(defmethod play [:rock :paper] [o1 o2]
{:winner o2 :loser o1})
;; scissors wins
(defmethod play [:scissors :paper] [o1 o2]
{:winner o1 :loser o2})
(defmethod play [:paper :scissors] [o1 o2]
{:winner o2 :loser o1})
(defmethod play :same [o1 o2] {:same (:type o1)})
(defn display-results [map]
(if (contains? map :same)
(format "Both objects are the same (%s)", (name (:same map)))
(let [winner (:winner map)
loser (:loser map)]
(format "%s %s %s!" (name (:type winner)) (:verb winner) (name (:type loser))))))
(defn get-random-object []
(*objects* (rand-int (count *objects*))))
(defn play-game
([]
(display-results (play (get-random-object) (get-random-object))))
([object]
(display-results (play (get-random-object) (*object-map* object)))))
(doseq [object [:rock :paper :scissors]]
(println (play-game object)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment