Skip to content

Instantly share code, notes, and snippets.

@gamecubate
Last active February 10, 2017 03:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gamecubate/8a2121c39bf3969f02e7ac787a77c570 to your computer and use it in GitHub Desktop.
Save gamecubate/8a2121c39bf3969f02e7ac787a77c570 to your computer and use it in GitHub Desktop.
(ns rps.app
(:require [reagent.core :as r]
[cljs.core.logic :as m :refer [membero]]
[clojure.core.logic.pldb :as pldb :refer [db-rel db with-db with-dbs]]
;; DATA
(def default-data {:player-hand nil
:computer-hand nil
:outcome nil
:player-score 0
:computer-score 0})
(def data (r/atom (default-data)))
;; LOGIC
(db-rel beats hand1 hand2)
(def facts
(db
[beats :rock :scissors]
[beats :paper :rock]
[beats :scissors :paper]))
(defn outcome [hand1 hand2]
(with-db facts
(doall
(m/run* [result]
(m/conde
((beats hand1 hand2) (m/== result :victory))
((beats hand2 hand1) (m/== result :loss))
((m/== hand1 hand2) (m/== result :tie)))))))
;; ACTIONS
(defn next-round! []
(.setTimeout js/window
#(reset! data default-data)
2000))
(defn computer-play! []
(swap! data assoc-in [:computer-hand] (rand-nth [:rock :paper :scissors]))
(let [hand1 (:player-hand @data)
hand2 (:computer-hand @data)
o (first (outcome hand1 hand2))]
(swap! data assoc-in [:outcome] o)
(next-round!)))
(defn play! [hand-type]
(swap! data assoc-in [:player-hand] hand-type)
(computer-play!))
(defn rock! []
(play! :rock))
(defn paper! []
(play! :paper))
(defn scissors! []
(play! :scissors))
;; VIEWS
(defn scoreboard []
(fn []
[:div.scoreboard
[:div.score
[:h2 "You"]
[:h1 (:player-score @data)]]
[:div.score
[:h2 "Computer"]
[:h1 (:computer-score @data)]]]))
(defn button [hand-type handler]
(fn [hand-type handler]
(let [icon-class (case hand-type
:rock "fa-hand-rock-o"
:paper "fa-hand-paper-o"
:scissors "fa-hand-scissors-o")
btn-class (if (= hand-type (:player-hand @data)) "selected" nil)]
[:span.btn {:class btn-class :on-click handler}
[:i.fa.fa-4x {:class icon-class :aria-hidden true}]])))
(defn computer-hand []
[:div.button
[blank-button]])
(defn referee []
(fn []
(let [o (:outcome @data)]
[:div.header
[:h1
(case o
:victory "You win!"
:loss "You lose."
"Pick a hand.")]])))
(defn player-choices []
[:div.buttons
[button :rock rock!]
[button :paper paper!]
[button :scissors scissors!]])
(defn game-view []
[:div
[scoreboard]
[computer-hand]
[referee]
[player-choices]])
(defn init []
(r/render-component [game-view]
(.getElementById js/document "container")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment