我想表示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