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