Skip to content

Instantly share code, notes, and snippets.

@zerg000000
Last active July 20, 2019 10:18
Show Gist options
  • Save zerg000000/5000ee75892c5eab19429547e8a2e9b2 to your computer and use it in GitHub Desktop.
Save zerg000000/5000ee75892c5eab19429547e8a2e9b2 to your computer and use it in GitHub Desktop.
;; 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