<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <title>Blackjack in ClojureScript&mdash;How It Was Written</title>
  <link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<h1>Blackjack in ClojureScript</h1>
<p>
    Many years ago—in 1998—I implemented a version of <a href="http://catcode.com/cardgame/sb21.html">Blackjack using dynamic HTML</a>. Hey, using JavaScript to control a web page was new and shiny back then.
</p>
<p>
    I decided to do an update of the code to learn some <a href="https://github.com/clojure/clojurescript">ClojureScript</a>. Also to update the graphics :)
</p>

<h2 id="data-structures">Data Structures</h2>

<p>
    The first question is how to represent a playing card. I could store it as a vector of two elements: like so: <code>[3 &quot;clubs&quot;]</code>, but that's not a good representation, as some of the card names would be strings rather than numbers, e.g., <code>&quot;Queen&quot;</code>. Instead, I decided to go with a number from 0 to 51. Numbers 0-12 are the clubs, 13-25 diamonds, and similarly for hearts and spades. Within each set of thirteen, the first card is the Ace, then 2 through 10, Jack, Queen, and King.
</p>

<p>
    This is a better representation, since it makes calculating a card's base value a simple matter of division and remainders. When I need the text representation of a card for the <code>alt</code> attribute of a card image, it's easy enough to write a function to generate that.
</p>

<p>
    When a card goes into a player's hand, I need to know if it is face up or face down. So, in a player's hand, a card is represented by a two-element vector: <code>[0 :up]</code>—the Ace of Clubs, face up.
</p>

<p>
    Once that fundamental issue is taken care of, what other data does the game need?
</p>
<ul>
    <li>The deck: a vector of integers</li>
    <li>The discard pile: a vector of integers. Once a game is played, the cards go into the discard pile; if the deck is empty, the discard pile is shuffled and becomes the new deck.</li>
    <li>The dealer's cards: a vector of <code>[<i>integer</i> :up|:down]</code> pairs</li>
    <li>The player's cards: a vector of <code>[<i>integer</i> :up|:down]</code> pairs</li>
    <li>The amount of money the player has left: a number</li>
    <li>The player's current bet: a number</li>
</ul>
<p>
    At this point, you may be wondering &ldquo;So, where&rsquo;s the ClojureScript? It will be here soon, but one of the things that functional programming encourages is figuring out what you need to do <em>before</em> you start coding. Now that this part seems reasonably figured out, here is the ClojureScript for the game state. It&rsquo;s an atom that holds a map, with the deck initialized to a shuffle of the numbers 0 through 52.
</p>
<pre>(defonce game (atom {:deck (into [] (shuffle (range 0 52)))
                     :discard-pile []
                     :dealer-hand []
                     :player-hand []
                     :player-money 1000.0
                     :current-bet 0}))
</pre>

<h2>Transformations</h2>

<p>
    Now it&rsquo;s time to figure out what transformations are needed. That&rsquo;s what functions do&mdash;they transform input to output.
</p>

<h3>Dealing A Card</h3>
<p>
Here are the transformations that have to happen when you deal a card:
</p>

<table>
    <thead>
    <tr><th>Input</th><th>Output</th><th>Code</th></tr>
    </thead>
    <tbody>
    <tr>
        <td>
            <ul>
                <li>The deck</li>
                <li>A hand</li>
                <li>How to deal the card (<code>:up</code> or <code>:down</code>)</li>
            </ul>
        </td>
        <td>
            <ul>
                <li>The deck without the first card</li>
                <li>The hand with a new card, dealt <code>:up</code> or <code>:down</code></li>
            </ul>
        </td>
        <td>
        <pre>(defn deal
  [deck hand position]
  (let [card (first deck)]
    (vec [(rest deck) (conj hand [card position])])))</pre>
        </td>
    </tr>
    </tbody>
</table>

<h3>Reshuffling</h3>
<p>
At some point the deck will be empty and you have to reshuffle the discard pile, which becomes the new deck, and the discard pile is emptied.
</p>

<ul>
    <li>Input: The deck and the discard pile</li>
    <li>Output: A new deck and an empty vector (the new discard pile)</li>
    <li>Code:<pre>(defn reshuffle
  [deck discard]
  [(shuffle discard) []])</pre>
    </li>
</ul>

<p>
    <img src="stop-sign.svg" width="135" height="135" alt="Stop sign"/>
</p>

<p>
This is <strong>not</strong> a good approach. In fact, from a functional standpoint, it&rsquo;s dreadful. Because I&rsquo;ve split up the dealing process into two parts, then when you deal two cards to the player&rsquo;s hand, the code is well on its way to something like this:
</p>

<div><pre>(let [[deck player-hand] (del player-hand deck :up)
      [deck discard-pile2] (reshuffle deck discard-pile)
      [deck player-hand] (deal player-hand deck :up)
      [deck discard-pile] (reshuffle deck discard-pile)]
  ...)</pre></div>

<p>
    ...and you&rsquo;re back in imperative programming land again. After further thought, the deck, hand, <em>and</em> discard pile are all of a piece. Why not have <code>deal</code> take two arguments: a vector of <code>[deck&nbsp;hand&nbsp;discard-pile]</code> and a position (<code>:up</code> or <code>:down</code>). Then the return value of a <code>deal</code> can be fed directly to the first parameter of another <code>deal</code>:
</p>

<div><pre>(deal (deal [deck player-hand discard-pile] :up) :up)</pre></div>

<p>
Here is the better way:
</p>

<table>
    <thead>
    <tr><th>Input</th><th>Output</th><th>Code</th></tr>
    </thead>
    <tbody>
    <tr>
        <td>
            <ul>
                <li>The deck</li>
                <li>A hand</li>
                <li>The discard pile</li>
                <li>How to deal the card (<code>:up</code> or <code>:down</code>)</li>
            </ul>
        </td>
        <td>
            <ul>
                <li>The deck without the first card</li>
                <li>The hand with a new card, dealt <code>:up</code> or <code>:down</code></li>
                <li>The discard pile (changed if the deck was empty)</li>
            </ul>
        </td>
        <td>
        <pre>(defn deal
  [[deck hand discard-pile] position]
  [[deck hand discard-pile] position]
  (let [new-deck (if (empty? deck) (shuffle discard-pile) deck)
        new-discard (if (empty? deck) [] discard-pile)
        card [(first new-deck) position]]
      [(rest new-deck) (conj hand card) new-discard]))</pre>
        </td>
    </tr>
    </tbody>
</table>

<h3>Evaluating a Hand</h3>
<p>
    Now that you can deal someone a hand, you have to know what its total value is. The function to do that has a hand as its input and produces a vector in the form <code>[<i>total</i> :ok|:blackjack|:bust]</code>.  The first entry in the vector is the total value of the hand; the second entry tells whether the total is <code>:ok</code> (less than or equal to 21), <code>:blackjack</code> (an Ace and any card worth 10), or <code>:bust</code> (greater than 21). Let&rsquo;s break this into smaller pieces.
</p>

<p>
Finding the total for a hand involves adding up the values of each card. If you think this is a good place to use the <code>reduce</code> function, you are correct.  But this code won&rsquo;t work:
</p>

<div>
    <pre>(reduce (fn [acc card] (+ acc (mod (first card) 13)) 1) hand)</pre>
</div>

<p>
    It doesn&rsquo;t work for two reasons:
</p>

<ul>
    <li>Adding one to the <code>mod 13</code> value of the card gives the wrong values for the Jack, Queen, and King. They are all worth 10, not 11, 12, and 13.</li>
    <li>This code thinks Aces are worth one point, but the first Ace in a hand is worth 1 or 11. (It counts as 11 unless you would go bust, in which case it is worth only one.) The other Aces are worth one each.</li>
    </ul>

<p>
    The first problem is easily solved. For non-Aces, take the minimum of the <code>mod</code> value and 10; that caps the value at 10. The second problem is a bit trickier. The function used with <code>reduce</code> needs to keep track of <em>two</em> things in its accumulator: the current total <em>and</em> the current value of an Ace. Luckily for us, there&rsquo;s no law that says the accumulator cannot be a vector.  Here is the code that will accumulate the value of a hand.
</p>

<div><pre>1 (defn accumulate-value
2   [[acc ace-value] card]
3   (let [card-mod (inc (mod (first card) 13))
4         card-value (if (= card-mod 1)
5                      ace-value
6                      (min 10 card-mod))]
7     [(+ acc card-value)
8      (if (= card-mod 1) 1 ace-value)]))</pre></div>

<p>
    Going through the relevant lines:
</p>

<dl>
    <dt>Line 2:</dt>
    <dd>This line uses destructuring to take the first argument (a vector) and bind it to the symbols <code>acc</code> (the total value) and <code>ace-value</code> (the current value of an Ace)</dd>
    <dt>Line 3:</dt>
    <dd>Calculate the &ldquo;base value&rdquo; of the card by taking it mod 13 and adding 1.</dd>
    <dt>Line 4:</dt>
    <dd>If the base value is 1, this is an Ace, so...</dd>
    <dt>Line 5:</dt>
    <dd>The card&rsquo;s final value is the current value of an Ace</dd>
    <dt>Line 6:</dt>
    <dd>Otherwise, its final value is capped at 10</dd>
    <dt>Line 7:</dt>
    <dd>The return value for the next stage of <code>reduce</code> must be a vector. The first item in the vector is the current total plus the card&rsquo;s final value</dd>
    <dt>Line 8:</dt>
    <dd>And the second item is the new value for an Ace. If this card is an Ace, then this at least our first Ace, and the new value for any subsequent Aces is 1; otherwise the value of an Ace remains unchanged.</dd>
</dl>

<p>
Now evaluating a hand is straightforward.
</p>

<div><pre>1 (defn evaluate-hand [hand]
2   (let [[pre-total ace-value] (reduce accumulate-value [0 11] hand)
3         total (if (and (> pre-total 21) (= ace-value 1)) (- pre-total 10) pre-total)]
4    (vec [total (cond
5                  (and (= total 21) (= (count hand) 2)) :blackjack
6                  (<= total 21) :ok
7                  :else :bust)])))</pre></div>

<dl>
    <dt>Line 2:</dt>
    <dd>Notice the initial value <code>[0 11]</code> passed to <code>reduce</code>: the zero is the initial value of the total, and the value of an Ace (which will be the first one) is 11.</dd>
    <dt>Line 3:</dt>
    <dd>If the hand would have gone over 21 and there is at least one Ace, count the first Ace as only 1 instead of 11 by subtracting 10.</dd>
    <dt>Line 5:</dt>
    <dd>The <code>cond</code> gives the hand&rsquo;s status. The test for a Blackjack works because if you have a total of 21 and only two cards, you must have an Ace and a card worth 10.</dd>
</dl>

<h3>Miscellaneous Functions</h3>
<p>
At some point, you have to turn over the face-down cards that went to the dealer. The <code>reveal</code> function takes a hand and returns a new hand with all the cards face up:
</p>

<div><pre>(defn reveal
  "This function takes a player's hand and returns a new hand
  with all the cards in the :up position"
  [hand]
  (let [result (vec (map (fn [card] [(first card) :up]) hand))]
    result))</pre></div>

<p>
And you have to be able to take a hand and put it on the discard pile. The <code>discard</code> function takes a vector consisting of the hand and the current discard pile as it input. It returns a similar vector with an empty hand and the new value of the discard pile. (This will allow the calls to be chained if that is ever desired.) Note that just the card number goes into the discard pile, the <code>:up</code> or <code>:down</code> is irrelevant.
</p>

<div><pre>(defn discard
  [[hand pile]]
  [ [] (vec (reduce (fn [acc x] (conj acc (first x))) pile hand)]))</pre></div>

<p>
After the first two cards are dealt, we need to know if there is an immediate win or not:
</p>

<ul>
    <li>Input: Dealer hand and player hand</li>
    <li>Output: <code>true</code> if someone has blackjack, <code>false</code> otherwise.</li>
</ul>

<p>Here is the code:</p>
<div><pre>(defn immediate-win
  [dealer-hand player-hand]
  (let [[ptotal _] (evaluate-hand player-hand)
        [dtotal _] (evaluate-hand dealer-hand)]
    (or (= ptotal 21) (= dtotal 21))))
</pre></div>


<p>
That takes care of the game logic.
</p>

<h2>User Interface</h2>

<p>
Two more items need to be added to the <code>game</code> atom: <code>:player-feedback</code> (initially the empty string) and <code>:feedback-color</code> (<code>:red</code>, <code>:green</code>, or <code>:black</code> for loss, win, and tie). I&rsquo;m not showing the code here; it&rsquo;s just two more entries into the key/value map.
 (Originally the design had two feedback areas; one above the dealer&rsquo;s cards and one above the player&rsquo;s. During development, I eliminated the feedback at the dealer area, as it was too confusing to look in two different places to figure out whether you had won or lost.)</p>

<p>
    The rest of the code displays the card playing area (the tableau) and handles events, all using the Reagent library. If you&rsquo;re not familiar with Reagent, <a href="http://reagent-project.github.io/">stop and read this excellent introduction</a>. TL;DR: In Reagent, a user interface <dfn>component</dfn> is a function that describes the HTML to be displayed and the functions to which it should react. Here is the code that generates the tableau.
</p>

<div><pre>  1  (defn tableau
  2    "Display the playing area (the tableau)."
  3    []  
  4    (let [{:keys [dealer-hand player-hand playing player-feedback feedback-color
  5                  player-money current-bet]} @game]
  6    [:div
  7     [:h2 "Dealer's Cards"]
  8     [show-cards dealer-hand]
  9     [:hr]
 10     [:h2 "Your Cards" [:span {:style {:color feedback-color}} player-feedback]]
 11     [show-cards player-hand]
 12     [:p 
 13      [:input {:type "button"
 14               :value "Start Game"
 15               :style {:display (if playing "none" "inline")}
 16               :on-click start-game}]
 17      [:input {:type "button"
 18               :value "Hit"
 19               :on-click hit-me
 20               :style {:display (if playing "inline" "none")}}]
 21      [:input {:type "button"
 22               :value "Stand"
 23               :on-click stand
 24               :style {:display (if playing "inline" "none")}}]
 25       " Your bet: $"
 26       [:input {:type "text"
 27                :size "5" 
 28                :on-change change-bet
 29                :value current-bet}]
 30       " Current money: $" player-money
 31      "\u00a0 \u00a0" ;; spacing
 32      [:input {:type "button"
 33               :value "Recharge money"
 34               :on-click recharge-money
 35               :style {:display (if (= player-money 0) "inline" "none")}}]]]))
</pre></div>

<p>Here are the Reagent concepts you need to know from these lines.</p>

<dl>
    <dt>Lines 4-5</dt>
    <dd>Get all the values from the <code>game</code> atom</dd>
    <dt>Line 6</dt>
    <dd>HTML is represented as a vector, with element names as keywords.</dd>
    <dt>Line 9</dt>
    <dd>You can nest elements (the <code>[:span...]</code>). Attributes are represented as a ClojureScript map. The content of the span is <code>player-feedback</code>, which is bound to the value from the <code>game</code> atom. This means that any change to that part of the atom will be reflected in the HTML.</dd>
    <dt>Line 8</dt>
    <dd>The <code>:h2</code> element is followed by another component: <code>show-cards player-hand</code> will call the <code>show-cards</code> function with <code>player-hand</code> as its argument. Again, because <code>player-hand</code> is bound to part of the atom, any change to that value will re-display that component.</dd>
    <dt>Line 15</dt>
    <dd>CSS properties are also represented by a map. The <code>display</code> property will be set depending upon the state of <code>playing</code>, which, again, is bound to a value in the <code>game</code> atom.</dd>
    <dt>Line 16</dt>
    <dd>This is how you do event handling. When the button is clicked, the <code>start-game</code> function will be called with the event as its argument.</dd>
</dl>

<h2>Displaying Cards</h2>
<p>
This code creates an HTML <code>&lt;div&gt;</code> element that contains the images of the cards in a person&rsquo;s hand by mapping <code>card-image</code> across all the cards. The function given to <code>map-indexed</code> will receive the index number of the item in the sequence and the item as its arguments. The result goes <code>into</code> a vector and thus becomes a component.
</p>

<div><pre>(defn show-cards [hand]
  (into [] (concat [:div {:class "cards"}]
                   (map-indexed card-image hand))))</pre></div>

<p>
<code>card-image</code> is given an index number and a card as its arguments. It then creates an <code>&lt;img&gt;</code> element with an appropriate <code>src</code> attribute (lines 3 and 4 in the following code). It also sets the <code>alt</code> and <code>title</code> attribute using the <code>english</code> function (lines 5 and 6). The reason the index is required is so that the cards can be relatively positioned to overlap (line 8).
</p>

<div><pre> 1 (defn card-image
 2   [n [card pos]]
 3   (let [filename (if (= pos :up) card "blue_grid_back")]
 4     [:img {:src (str "./images/" filename ".svg")
 5            :alt (english card pos)
 6            :title (english card pos)
 7            :style {:position "relative"
 8                    :left (* -55 n)
 9                    :height "133px"
10                    :width "98px"}}]))</pre></div>

<aside>
    One of the hardest parts of writing this program was finding some good card images. Many of the open source card images I found were small GIFs or extremely ornate&mdash;and large&mdash;SVG files. I found the images at my go-to place for such things: the <a href="http://openclipart.org">Open Clip Art Library</a>. The cards designed by <a href="http://nicubunu.ro/">Nicu Buculei</a> were just what I needed.
</aside>

<p>This is the code for conversion to English; just an integer division and remainder to figure out the suit and card:</p>

<div><pre>(def cardnames ["Ace", "2", "3", "4", "5", "6", "7", "8", "9" "10" "Jack" "Queen" "King"])
(def suits ["clubs" "diamonds" "hearts" "spades"])

(defn english [cval pos]
  (if (= pos :up)
    (str (nth cardnames (rem cval 13)) " of "
         (nth suits (quot cval 13)))
    "face down card")</pre>)</div>

<h2>Event Handling</h2>
<p>
The events that the code has to handle are:
</p>
<ul>
    <li>Click on the <span class="button">Start Game</span> button</li>
    <li>Click on the <span class="button">Hit</span> or <span class="button">Stand</span> buttons</li>
    <li>Change of the amount bet.</li>
    <li>Click on the <span class="button">Recharge Money</span> button when the player&rsquo;s money hits zero.</li>
</ul>

<h3>Starting the Game</h3>

<div><pre> 1 (defn start-game
 2   [event]
 3   (let [{:keys [deck discard-pile dealer-hand player-hand current-bet]} @game
 4         [player1 pile0] (discard [player-hand discard-pile])
 5         [dealer1 pile1] (discard [dealer-hand pile0])]
 6         [deck2 dealer2 pile2] (deal (deal [deck dealer1 pile1] :up) :down)
 7         [deck3 player2 pile3] (deal (deal [deck2 player1 pile2] :up) :up)]
 8     (swap! game assoc :playing true :discard-pile pile3 :player-hand player2
 9            :dealer-hand dealer2 :deck deck3 :dealer-feedback "" :player-feedback "")
10     (if (immediate-win dealer2 player2)
11       (do
12         (swap! game assoc :dealer-hand (reveal dealer2))
13         (end-game dealer2 player2)))))</pre></div>

<p>
    At the beginning of a new game, the code has to:
</p>

<ul>
    <li>Take any cards currently on the tableau and put them on the discard pile (lines 4-5)</li>
    <li>Deal a card face up, then a card face down to the dealer (line 6)</li>
    <li>Deal two face-up cards to the player (line 7)</li>
    <li>Update the <code>game</code> atom and clear the feedback area (lines 8-9)</li>
</ul>

<p>
You may be wondering why I am creating variables like <code>deck3</code> and <code>player2</code> instead of re-using the variable names:
</p>

<div><pre>  (let [{:keys [deck discard-pile dealer-hand player-hand current-bet]} @game
        [player pile] (discard [player-hand discard-pile])
        [dealer pile] (discard [dealer-hand pile])
        [deck dealer pile] (deal (deal [deck dealer pile] :up) :down)
        [deck player pile] (deal (deal [deck player pile] :up) :up)]</pre></div>

<p>
The reason is that I come from an Erlang background, where variables are not only immutable but are also <dfn>single-assignment</dfn>. Once you bind a value to a symbol, you cannot rebind another value to that symbol; you must create a new symbol.
</p>

<h3>Hit and Stand</h3>
<p>
If the player or dealer don&rsquo;t have blackjack, the player can either <dfn>hit</dfn> to request another card or <dfn>stand</dfn> to say they are happy with their hand. The following code deals a card face up to the player, evaluates the hand, updates the <code>game</code> atom, and ends the game if the total is over 21 (the player has &ldquo;busted&rdquo;).
</p>

<div><pre>(defn hit-me [event]
  (let [{:keys [deck discard-pile dealer-hand player-hand]} @game
        [deck2 player2 discard2] (deal [deck player-hand discard-pile] :up)
        [total status] (evaluate-hand player2)]
    (swap! game assoc :player-hand player2 :deck deck2 :discard-pile discard2)
    (if (= status :bust) (end-game dealer-hand player2))))</pre></div>

<p>
    Here is the code that is invoked when the player clicks the <span class="button">Stand</span> button.
    </p>

<div><pre>  1 (defn stand [event]
  2   (let [{:keys [deck dealer-hand player-hand discard-pile]} @game
  3         dhand (reveal dealer-hand)]
  4     (swap! game assoc :dealer-hand dhand)
  5     (loop [loop-deck deck
  6            loop-hand dhand
  7            loop-pile discard-pile]
  8       (let [[total status] (evaluate-hand loop-hand)]
  9         (if (or (= status :bust) (>= total 17))
 10           (do
 11             (swap! game assoc :dealer-hand loop-hand)
 12             (end-game loop-hand player-hand))
 13           (let [[new-deck new-hand new-discard] (deal [loop-deck loop-hand loop-pile] :up)]
 14             (swap! game assoc :dealer-hand new-hand)
 15             (recur new-deck new-hand new-discard)))))))</pre></div>

<p>
The code reveals the dealer&rsquo;s face-down card (line 3) and updates the atom in order to force the card to redisplay (line 4). Lines 5-7 start a loop that evaluates the hand (line 8). If the dealer has to stop taking cards (either because they went bust or over 17), then update the display and end the game (lines 11-12). Otherwise, deal another card into the dealer hand (line 13), update (line 14), and get another card (line 15)&mdash;<code>recur</code> invokes the loop again.
</p>


<h3>Ending the Game</h3>

<p>
If the game is over, the code must look at the dealer&rsquo;s and player&rsquo;s hand, determine the winner, update the feedback area, and update the money. The <code>end-game</code> is pretty much a list of conditions.
</p>

<p>The <code>end-game</code> code is pretty much a list of conditions:</p>

<div><pre>(defn end-game [dealer player]
  (let [[ptotal pstatus] (evaluate-hand player)
        [dtotal dstatus] (evaluate-hand dealer)]
    (cond
      (> ptotal 21) (feedback "Sorry, you busted." :red)
      (> dtotal 21) (feedback "Dealer goes bust. You win!" :green)
      (= ptotal dtotal) (feedback "Tie game." :black)
      (= pstatus :blackjack) (feedback "You win with blackjack!" :green)
      (= dstatus :blackjack) (feedback "Dealer has blackjack." :red)
      (< ptotal dtotal) (feedback "Dealer wins." :red)
      (> ptotal dtotal) (feedback "You win!" :green)
      :else (feedback "Unknown result (Shouldn't happen.)" :gray))
    (update-money dtotal dstatus ptotal pstatus)
    (swap! game assoc :playing false)))</pre></div>

<p>
    The <code>feedback</code> function changes the <code>:player-feedback</code> and <code>:feedback-color</code> values in the <code>game</code>, and Reagent will automagically do the update.
</p>

<div><pre>(defn feedback [message color]
  (swap! game assoc :player-feedback (str "\u00a0" message) :feedback-color (name color)))</pre></div>

<p>
Updating the money is, again, a list of conditions. However, I do feel rather guilty about accessing the player money and current bet directly from the <code>game</code> atom instead of passing them as parameters. It really feels imperative rather than functional. Sorry about that.
</p>

<div><pre>(defn update-money [dtotal dstatus ptotal pstatus]
  (let [{:keys [player-money current-bet]} @game
        new-money (cond
                    (= ptotal dtotal) player-money ;; least common, but avoids lots of ugliness later
                    (= pstatus :blackjack) (+ player-money (* 1.5 current-bet))
                    (= pstatus :bust) (- player-money current-bet)
                    (or (= dstatus :bust) (> ptotal dtotal)) (+ player-money current-bet)
                    (< ptotal dtotal)(- player-money current-bet)
                    :else player-money)]
    (swap! game assoc :player-money new-money :current-bet (max 0 (min current-bet new-money)))))</pre></div>

<h3>More Money Matters</h3>
<p>
Finally, the code for handling a change in the amount of bet and allowing people to recharge their money if they gamble their entire bankroll and lose:
</p>

<div><pre>(defn change-bet [event]
  (let [val (.parseFloat js/window (.-value (.-target event)))
        amount (if (js/isNaN val) 0 val)
        total (:player-money @game)]
    (swap! game assoc :current-bet (max 0 (min amount total)))))

(defn recharge-money [event]
  (swap! game assoc :current-bet 10 :player-money 1000))</pre></div>

<p>
The code for <code>change-bet</code> is the only event handler that uses the information from the <code>event</code> parameter to retrieve the value the player typed. It&rsquo;s converted to a number (or zero if that isn&rsquo;t possible), and then the <code>game</code> atom is updated so that the current bet cannot go negative or greater than the amount of money you have. It is possible to bet zero, and that wasn&rsquo;t intentional, so I rationalized it: people who have moral restrictions against gambling can still play the game without having to bet.
</p>

<p>
Recharging the money updates the appropriate values in the <code>game</code> atom.
</p>

<h2>Wrap-up</h2>
<p>
Well, there you have it. Since this one of my first non-trivial ClojureScript programs, it probably has a large number of violations of coding conventions and isn&rsquo;t as functionally pure as it could be. Feel free to <a href="https://github.com/jdeisenberg/cljs-blackjack">fork the source on GitHub</a> and improve it.
</body>
</html>
