Clojure функция повторного заказа - PullRequest
0 голосов
/ 29 сентября 2018

Это, я должен признать, все еще там, где я начинающий новичок.Я часто нахожу, что, если я ищу в Документах Clojure, я нахожу нужную функцию.;)

Но я нервничаю по этому поводу, но, может быть, мне повезет.

У меня есть карточная игра.У каждого игрока в руке может быть от 1 до 9 карт.

Карты попадают в их руки по 1 карте за раз, начиная с верха их колод, вытягивая.

Чтоигроки запрашивают возможность взять там неорганизованную руку или несортированную руку и повторно организовать их.

Я предложил решение «Как насчет команды, подобной / изменить порядок 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, что было бы замечательно!

Спасибо за ЛЮБУЮ помощь / совет / ответ ...

ADDENDUM # 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]))

Для просмотра данных до и после выполнения определения, но я не получаю никаких изменений.Вектор, для простоты, 21436587 в [2 1 4 3 6 5 8 7].

Но я что-то упускаю, потому что я даже запускаю / re-order 12345678, чтобы убедиться, что вещи не перемещены иЯ просто не вижу вещей.Но ничего ...

Спасибо, определенно за то, что вы так далеко зашли.

Ответы [ 3 ]

0 голосов
/ 30 сентября 2018

Если у вас есть требуемый порядок элементов в виде вектора, вы можете 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)
0 голосов
/ 30 сентября 2018

С вашей помощью:

(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%

0 голосов
/ 29 сентября 2018

Итак, первой заметной функцией будет 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,

...