Last active
July 20, 2019 10:18
-
-
Save zerg000000/5000ee75892c5eab19429547e8a2e9b2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; P.S. 閱讀指引,在 Code Snippet(白色的地方)按Ctrl+Enter看結果。也可以修改後按Ctrl+Enter~ | |
;; 假設我想寫一個簡單的猜字遊戲。 | |
;; 首先,我應該要有一本字典提供生字。 | |
(def dict ["Clojure" "Java" "Go" "Javascript" "Haskell" "Scala" "C" "C++" "Rust" "C#" "Prolog"]) | |
;; 遊戲應該會隨機選擇生字給玩家猜猜看。 | |
(dict 0) | |
(dict 10) | |
(count dict) | |
(find-doc "random") | |
;; 噢~似乎沒有這好用的功能,不過 Google 一下還可以。 | |
(dict (rand-int (count dict))) | |
;; 似乎已經可以達成效果,將它封裝成Function。 | |
(defn pick-a-word! [dict] | |
(dict (rand-int (count dict)))) | |
;; 試用一下。 | |
(pick-a-word! dict) | |
;; 效果不錯,似乎有更好的實作? | |
(defn pick-a-word! [dict] | |
(rand-nth dict)) | |
;; 再試一下。 | |
(pick-a-word! dict) | |
;; 完成! | |
;; 現在可以隨機選字,還差什麼呢?還差什麼可以開始遊戲? | |
(defn start-game! [] | |
(let [player (new-player "Albert") | |
word-for-guess (pick-a-word! dict)] | |
{:player player | |
:word word-for-guess | |
:match? false})) | |
(start-game!) | |
;; 不錯~?呃~為什麼執行不到? | |
(defn new-player [player-name] | |
{:times 0 :guess-words [] :name player-name}) | |
(new-player "Albert") | |
(start-game!) | |
;; 沒有問題了,Data也符合預期。試一下遊戲吧。 | |
;; 現在,作為玩家,我應該可以猜字和知道猜字結果。 | |
(defn guess-word [game word] | |
(-> game | |
(update-in [:player :times] inc) | |
(update-in [:player :guess-words] conj word) | |
(update-in [:match?] #(= (:word game) word)))) | |
;; 由於這REPL環境沒有IO,先用Variable (Clojure裡名叫Atom)去模擬。 | |
(defcell game (start-game!)) | |
(swap! game guess-word "Java") | |
(swap! game guess-word "D") | |
;; 似乎還不錯?但遊戲的結果是?猜中和猜錯5次都應該會結束遊戲。 | |
(defn is-end? [game] | |
(cond | |
(:match? game) :win | |
(>= (get-in game [:player :times]) 5) :lose | |
:else false)) | |
(is-end? {:match? true}) | |
(is-end? {:match? true | |
:player {:times 10}}) | |
(is-end? {:match? false | |
:player {:times 6}}) | |
(is-end? {:match? false | |
:player {:times 3}}) | |
;; 萬事俱備,玩遊戲。噢⋯⋯這是程式測試。 | |
(do (reset! game (start-game!)) | |
(swap! game guess-word "Java") | |
(is-end? @game) | |
(swap! game guess-word "C") | |
(is-end? @game) | |
(swap! game guess-word "D") | |
(is-end? @game) | |
(swap! game guess-word "E") | |
(is-end? @game) | |
(swap! game guess-word "Lua") | |
(is-end? @game) | |
(swap! game guess-word "CoffeeScript") | |
(is-end? @game) | |
(swap! game guess-word "TypeScript") | |
(is-end? @game) | |
) | |
;; 媽⋯⋯我只會輸⋯⋯不好玩⋯⋯但遊戲程式基本完成,只要勾連Game Engine和Event Dispatchers就可以有個像樣的遊戲。 | |
;; 但等一等⋯⋯為什麼每次玩家都是Albert?⋯⋯讓我修一修⋯⋯ | |
(defn start-game! [player-name] | |
(let [player (new-player player-name) | |
word-for-guess (pick-a-word! dict)] | |
{:player player | |
:word word-for-guess | |
:match? false})) | |
;; 剪貼之前的測試,再試試看? | |
(do (reset! game (start-game! "Freak!")) | |
(swap! game guess-word "Java") | |
(is-end? @game) | |
(swap! game guess-word "C") | |
(is-end? @game) | |
(swap! game guess-word "D") | |
(is-end? @game) | |
(swap! game guess-word "E") | |
(is-end? @game) | |
(swap! game guess-word "C++") | |
(is-end? @game) | |
(swap! game guess-word "CoffeeScript") | |
(is-end? @game) | |
(swap! game guess-word "TypeScript") | |
(is-end? @game) | |
) | |
;; 以上是一個REPL開發的演示,感謝閱讀完畢~撒花~ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment