0

我必须承认,这仍然是我是 clojure 新手的地方。我经常发现,如果我在 Clojure Docs 中搜索,我会找到我正在寻找的函数。;)

但我对此感到紧张,但也许我会走运。

我有一个纸牌游戏。每个玩家手上有 1-9 张牌。

这些卡通过抽牌从他们的牌组顶部一次一张地放入他们的手中。

玩家所要求的是能够将 UNORGANIZED 手牌或 UNSORTED 手牌带到那里并重新组织他们的手牌。

我提供了一个解决方案“如何在命令窗口中使用 /re-order 31487652 之类的命令,它可以发出函数(不用担心命令,它只是排序函数)。

这样做的目的是拿到他们手中的每张卡片 12345678 并将顺序更改为他们提供的新顺序,即 31487652。

数据格式如下:

(:hand player)

[{:name : "Troll", :_id : 39485723},
{:name : "Ranger", :_id : 87463293},
{:name : "Archer", :_id : 78462721},
{:name : "Orc", :_id : 12346732},
{:name : "Orc", :_id : 13445130},
{:name : "Spell", :_id : 23429900},
{:name : "Dagger", :_id : 44573321}]

我唯一的问题是,我可以使用传统的编程语言来思考这个问题,我的意思是很简单,你只需将数据复制到另一个数组,哈哈,但我的意思是我们不喜欢 clojure 吗?...

但我想把事情保留在纯粹的 clojure 意识形态中,并学习如何做这样的事情。我的意思是,如果它只是“使用此功能”,我想这很好,但我不想创建一个原子,除非是强制性的,但我认为情况并非如此。

如果有人可以帮助我开始思考使用 clojure 解决这个问题的方法,那就太棒了!

感谢您提供任何帮助/建议/回答...

附录#1

(defn vec-order [n]
  (into [] (if (pos? n)
             (conj (vec-order (quot n 10)) (mod n 10) )
             [])))

(defn new-index [index new-order] (.indexOf new-order (inc index)))

(defn re-order [state side value]
  (println (get-in @state [side :hand]))
  (update @state [side :hand]
          (fn [hand]
            (->> hand
                 (map-indexed (fn [index card] [(new-index index (vec-order value)) card]))
                 (sort-by first)
                 (mapv second))))
  (println (get-in @state [side :hand])))

所以这是我当前的代码,提取数据。有一个巨大的@state,玩家所在的一边。我用:

(println (get-in @state [side :hand]))

查看执行defn之前和之后的数据,但我没有得到任何更改。为简单起见,向量是 21436587 到 [2 1 4 3 6 5 8 7]。

但是我遗漏了一些东西,因为我什至运行 /re-order 12345678 以确保没有移动东西,而我只是看不到东西。但没什么...

谢谢你,绝对让我走到这一步。

4

3 回答 3

3

如果您将所需的元素顺序作为向量,则可以sort-by通过函数返回该向量中卡片的索引:

(let [cards [1 2 3 4 5 6 7 8]
      my-order [3 1 4 8 7 6 5 2]]
  (sort-by #(.indexOf my-order %) cards))
;; => (3 1 4 8 7 6 5 2)
于 2018-09-29T21:23:29.797 回答
1

因此,第一个值得注意的函数将是update,如果我们这样调用它,它将允许我们返回一个带有应用于手的函数的新玩家。

(update player :hand (fn [hand] ... ))

一旦有了这个基本结构,下一个对我们有帮助的函数就是map-indexed,它允许我们将当前手牌与新的排序索引配对。

从那里,我们将能够按索引排序,最后通过 mapv检索卡片。

因此,最终结构将类似于:

(defn sort-hand [player new-order]
  (update
    player
    :hand
    (fn [hand]
     (->> hand 
          (map-indexed (fn [index card] [(new-index index new-order) card]))
          (sort-by first)
          (mapv second)))))

为此,预计这new-order是一个像[3 1 4 8 7 6 5 2]

至于解决方案new-index

我们可以.indexOf这样 使用(defn new-index [index new-order] (.indexOf new-order (inc index)))

于 2018-09-29T19:49:50.067 回答
0

在您的帮助下:

(defn vec-order [n]
  (into [] (if (pos? n)
             (conj (vec-order (quot n 10)) (mod n 10) )
             [])))

(defn new-index [new-order index] (.indexOf new-order (inc index)))

(defn re-order [state side value]
  (swap! state update-in [side :hand]
             (fn [hand]
               (->> hand
                    (map-indexed (fn [index card] [(new-index (vec-order value) index) card]))
                    (sort-by first)
                    (mapv second)))))

作品!!!100%

于 2018-09-29T23:33:03.470 回答