6

我正在下班后学习 clojure,我正在通过制作一个小游戏(喜欢 quil 库)来让我熟悉 clojure 在特定方面和 FP 方面的不同方面。

所以,我的游戏世界存在地图数据结构的 3d 网格(地图矢量的矢量)。我想迭代 3d 空间(地图)中的每个点并在满足条件时更改数据。这是我最初的解决方案:

(游戏数据结构是游戏状态(一张地图))

(defn soil-gen [game]
  (let [world-x (game :world-x)
        world-y (game :world-y)
    world-z (game :world-z)]
      (for [x (range world-x) 
          y (range world-y) 
          z (range world-z) 
          :when (> z (* world-z (rand)))]
         (assoc-in game [:world x y z :type] :soil))))

但这会返回每次迭代的结果列表(我的游戏状态数据结构),而不是一个游戏数据结构。我应该能够以某种方式将每次迭代的结果传回 for。可能像循环/递归之类的东西,但我认为你不能将递归与 for 结合使用。

有人提供线索吗?

谢谢

4

2 回答 2

8

您可以使用reducewith for,如下所示:

(defn soil-gen [game]
  (let [world-x (game :world-x)
        world-y (game :world-y)
    world-z (game :world-z)]

    (reduce (fn [g [x y z]] (assoc-in g [:world x y z :type] :soil)))
            game
            (for [x (range world-x) 
                  y (range world-y) 
                  z (range world-z) 
                 :when (> z (* world-z (rand)))]
                 [x y z]))))
于 2012-10-29T06:23:27.640 回答
2

您可能希望使用类似reduce的方法在每次迭代之间传递累积的结果。

简化示例:

(reduce 
  (fn [m val] (assoc m val (str "foo" val))) 
  {}               ;; initial value for m 
  (range 5))       ;; seqence of items to reduce over

=> {4 "foo4", 3 "foo3", 2 "foo2", 1 "foo1", 0 "foo0"}

reduce通常在函数式编程中有一些“累加值”的概念时非常有用。它还具有非常高效的优点。

于 2012-10-29T06:21:56.563 回答