Skip to content

Instantly share code, notes, and snippets.

@timothypratley
Created March 11, 2010 07:25
Show Gist options
  • Save timothypratley/328929 to your computer and use it in GitHub Desktop.
Save timothypratley/328929 to your computer and use it in GitHub Desktop.
;; This is intended to be entered interactively one part at a time
;; Try to keep state manipulation separate from logic functions
;; deal can just take a current game and return a new game.
;; thanks to persistent data structures, we aren't penalized for doing so.
(defn deal
[game n hand]
(update-in
(update-in game [hand] concat (take n (:deck game)))
[:deck]
(partial drop n)))
;; Handy side effect is it is easier to test the parts
(use 'clojure.test)
(deftest deal-test
(is (= (deal {:deck [[8 \C] [9 \C]]
:house []
:player []}
2 :player)
{:deck []
:house []
:player [[8 \C] [9 \C]]})))
(run-tests)
;; And you don't have to think about concurrency or state yet
(defn new-game
[deck]
(-> {:deck deck
:house []
:player []}
(deal 2 :player)
(deal 2 :house)))
;; To know that the parts are working
(deftest new-game-test
(is (= (new-game [[\A \S] [\K \S] [\A \D] [\K \D]])
{:deck []
:house [[\A \D] [\K \D]]
:player [[\A \S] [\K \S]]})))
(run-tests)
(defn build-test-deck
[]
[[8 \S] [2 \C] [6 \C] [8 \D] [6 \H] [\A \H] [8 \C] [7 \H] [\A
\C] [2 \D] [\K \H] [10 \D] [4 \H] [6 \S] [2 \H] [\Q \H] [3 \D] [10 \S]
[3 \S] [1 \S] [\A \D] [9 \H] [\J \S] [4 \D] [1 \C] [\K \D] [2 \S] [1
\H] [5 \C] [\K \C] [10 \H] [9 \D] [9 \C] [\J \D] [\Q \C] [7 \S] [7 \D]
[9 \S] [1 \D] [\J \H] [10 \C] [6 \D] [\K \S] [5 \H] [\J \C] [7 \C] [4
\C] [\Q \D] [\Q \S] [5 \D] [\A \S] [3 \C] [3 \H] [4 \S] [8 \H] [5
\S]])
;; Now if you really do need concurrency or state,
;; the state management is much clearer
(def my-game (ref nil))
(defn my-new-game
[]
(dosync (ref-set my-game (new-game (build-test-deck)))))
(defn my-deal
[n hand]
(dosync (alter my-game deal n hand)))
;; Now we can try the mixture of both parts
(my-new-game)
(my-deal 1 :player)
(my-deal 1 :house)
(my-deal 1 :player)
;; And the killer feature is we can run multiple independent games without changing the game code!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment