ボードゲームのために、Clojureの2Dポジション+ネイバーのグラフを表現したい。私は隣人のベクトルに位置をマップするマップを使用しています:clojure - キー値に基づいて異なる方法でマップ値を更新する
{[0 0] [[0 1] [1 0] [1 1]]}
私は任意のサイズのボードに隣接グラフを生成することができますいくつかの機能を書かれている:
(defn positions [size]
(for [x (range 0 size) y (range 0 size)] [x y]))
(defn neighbors [size [x y]]
(filter (fn [[x y]]
(and (>= x 0) (< x size) (>= y 0) (< y size)))
(-> []
(conj [(inc x) y])
(conj [(dec x) y])
(conj [x (inc y)])
(conj [x (dec y)])
(conj [(inc x) (inc y)])
(conj [(dec x) (dec x)]))))
(defn board-graph
[size]
(reduce (fn [map position] (assoc map
position
(neighbors size position)))
{}
(positions size)))
これは正常に動作します:
(board-graph 2)
=> {[0 0] ([1 0] [0 1] [1 1]), [0 1] ([1 1] [0 0]), [1 0] ([0 0] [1 1] [0 0]), [1 1] ([0 1] [1 0] [0 0])}
しかし私は今、ボードの端にあるボードの位置のそれぞれに、この追加の「仮想隣人に追加したいです、 .e.g:TOP、:BOTTOM、:LEFT、:RIGHT。だから私は希望:
ここ(board-graph 2)
=> {[0 0] (:LEFT :TOP [1 0] [0 1] [1 1]), [0 1] (:LEFT :BOTTOM [1 1] [0 0]), [1 0] (:RIGHT :TOP [0 0] [1 1] [0 0]), [1 1] (:RIGHT :BOTTOM [0 1] [1 0] [0 0])}
は、これまでの私の試みですが、それは全く正しい動作しない、それは本当にオーバー複雑なようだ:
(defn- filter-keys
[pred map]
(into {}
(filter (fn [[k v]] (pred k)) map)))
(defn board-graph
[size]
(let [g (reduce (fn [map position] (assoc map
position
(neighbors size position)))
{}
(positions size))]
(merge g
(reduce-kv #(assoc %1 %2 (conj %3 :TOP)) {}
(filter-keys (fn [[x y]] (= y 0)) g))
(reduce-kv #(assoc %1 %2 (conj %3 :BOTTOM)) {}
(filter-keys (fn [[x y]] (= y (dec size))) g))
(reduce-kv #(assoc %1 %2 (conj %3 :LEFT)) {}
(filter-keys (fn [[x y]] (= x 0)) g))
(reduce-kv #(assoc %1 %2 (conj %3 :RIGHT)) {}
(filter-keys (fn [[x y]] (= x (dec size))) g)))))
が、私は基本的に私のマップを構築したいですそれをもう一度やり直すと、特定のキーについては、キーが何であるかに応じて関連する値が更新されます。私は状態に頼らずにこれを行う良い方法を見つけることができません! これを行う方法はもっと慣れていますか?
[更新](https://clojuredocs.org/clojure.core/update)に詳しいですか? – RedDeckWins
ありがとうございます。更新はただ一つのキーでしか機能しません。私は基本的に私が更新を呼び出す必要があるキーの4つのリストがあります。私が検索を変更したことを考えれば、これが見つかった:http://stackoverflow.com/questions/9638271/update-the-values-of-multiple-keys これはコードの最後の部分を修正する可能性があります。 – jimypbr