sortingclojurereorganize

Clojure re-order function


This I must admit is still where I am a clojure newbie. I often find that if I search in the Clojure Docs, I find the function I am looking for. ;)

But I am nervous about this one, but maybe I might get lucky.

I have a card game. Each player has a hand of anywhere from 1-9 cards in hand.

The cards get put into their hands 1 card at a time, from the top of their decks by drawing.

What the players are requesting is the ability to take there UNORGANIZED hand or UNSORTED hand and re-oganize their hand.

I offered a solution of "How about a command like /re-order 31487652 in the command window, that could issue the function (no worries about the command, it's just the sorting func).

The goal of this would be to take each card in their hand 12345678 and change the order to a new order that they provide, the 31487652.

The data is in this format:

(: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}]

My only issue is, I could THINK about this using traditional programming languages, I mean easy, you just copy the data over to another array, haha but I mean don't we love clojure?...

But I'd like to keep things in the pure clojure ideology, AND LEARN the how to do something like this. I mean if it's just "Use this function" that's great I guess, but I don't want to create an atom, unless mandatory, but I don't think that is the case.

If someone could help get me started just THINKING of a way to approach this problem using clojure that would be awesome!

Thanks for ANY help/advice/answer...

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

So here is my current code, with extraction of data. There is a massive @state, with the side the player is on. I use:

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

To look at the data before and after the execution of the defn, but I am not get ANY change. The vector is, for simplicity, 21436587 into [2 1 4 3 6 5 8 7].

But I am missing something because I even run the /re-order 12345678 to make sure things aren't moved and I am just not seeing things. But nothing...

Thank You, definitely for getting me this far.


Solution

  • With your help:

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

    WORKS!!! 100%