LoginSignup
0
0

More than 5 years have passed since last update.

ClojureScriptでReactチュートリアルやってみた (2)

Last updated at Posted at 2018-09-17

はじめに

この記事の続き。

公式チュートリアルの「Wrapping Up」の章(最後)まで進めてみました。部品の大部分をBoardコンポーネントからGameコンポーネントに移し、historyに盤面を保存していくように変更しています。

全ソースはこちら

1. 実装

(defn square [{:keys [on-click value]}]
  [:button.square
    {:on-click #(on-click)}
    value])

(defn board [& {:keys [squares on-click]}]
  (letfn
    [(render-square [i]
       [square {
         :value (squares i)
         :on-click #(on-click i)
       }])]
        [:div
          [:div.board-row
            (render-square 0)
            (render-square 1)
            (render-square 2)]
          [:div.board-row
            (render-square 3)
            (render-square 4)
            (render-square 5)]
          [:div.board-row
            (render-square 6)
            (render-square 7)
            (render-square 8)]]))

(defn game []
  (let [state (r/atom {:history (vec [{:squares (vec (repeat 9 ""))}])
                       :x-is-next? true})]
    (fn []
      (letfn
        [(handle-click [i]
          (let [history (get @state :history)
                current (last history)
                squares (get current :squares)
                x-is-next? (get @state :x-is-next?)]
            (when (and (= (calculate-winner squares) nil) (= (squares i) ""))
                  (swap! state
                         assoc :history
                         (conj history
                               (assoc-in current [:squares i] (if x-is-next? "X" "O"))))
                  (swap! state assoc :x-is-next? (not x-is-next?)))))]
            (let [history (get @state :history)
                  current (last history)
                  squares (get current :squares)
                  winner (calculate-winner squares)
                  status (if (= winner nil)
                              (str "Next player: " (if (get @state :x-is-next?) "X" "O"))
                              (str "Winner: " winner))]
                    [:div.game
                      [:div.game-board
                        [board :squares squares
                               :on-click handle-click]
                        ]
                    [:div.game-info
                      [:div status]
                    [:ol
                    ;"todo"
                    ]]])))))

2.ClojureScriptコーディングあれこれ

2.1. last

(last history)

lastはcollectionの最後の要素を取得する。

2.2. conj

(conj history
      (assoc-in current [:squares i] (if x-is-next? "X" "O")))

conjはcollectionの最後に要素を追加する。

続き

こちら

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0