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))))

しかし、これは 1 つのゲーム データ構造ではなく、すべての反復の結果 (私のゲーム状態データ構造) のリストを返します。どういうわけか、各反復の結果を for に戻すことができるはずです。おそらく loop/recur のようなものですが、recur と for を組み合わせることはできないと思います。

誰か手がかり?

ありがとう

4

2 に答える 2

8

あなたができることは、以下に示すようにで使用することreduceです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 に答える