Clojure纸牌游戏的状态

Dri*_*den 3 state clojure game-engine

我对clojure相对较新,但掌握了主要的功能概念.我真正挣扎的是国家.

我正在写一个简单的纸牌游戏应用程序,它已经到了我正在编写游戏引擎的地步.因此,国家的概念很快打动了我.

我需要跟踪许多与游戏相关的事情:

  • 甲板的状态
  • 积分的状态
  • 谁是经销商
  • 等等

我已经阅读过如何在clojure,Refs,Agents,Atoms和thread local vars中使用状态.但它们似乎都不是我正在做的正确选择.

所以我的实际问题是:我用什么clojure构造来维护clojure中单线程游戏引擎的状态?

noi*_*ith 7

函数式编程的一般原则是,通过用每个函数访问状态的附加输入arg和输出arg替换全局状态,可以使代码更通用.

在这种情况下,这意味着为game每轮比赛提供一个arg,并且每轮比赛都会返回一个新的game用于前进的比赛.这有一些优点.没有突变,因此不需要管理和协调突变.您的测试可以包括运行一轮游戏功能.如果你需要AI,它可以在广度优先的基础上轻松地运行游戏的许多分支轮次来测试可能的结果,而不会干扰实际游戏的状态.

这可能是一个粗略的草图:

(def make-game
  [players]
  (let [[draw & deck] (shuffle cards)]
  {:draw draw
   :deck deck
   :points (zipmap players (repeat 0))
   :dealer (first players)})

(defn run-round
  [game]
  (let [points (update-points (:draw game) (:points game))
        [draw & deck] (:deck game)]
    (assoc game :deck deck :draw draw :points points)))

(defn winner?
  [game]
  (some #(> (val %) 42) (:points game)))

(defn -main
  (let [gameplay (take-while #(not (winner? %))
                             (iterate run-round (make-game)))]
    (:points (run-round (last gameplay)))))
Run Code Online (Sandbox Code Playgroud)

这当然是一个非常微不足道的游戏,其中每个玩家的积分都来自绘制的卡片.下一张牌将在每个回合中从洗牌的牌组中抽出,直到我们有一个总得分表示获胜者.