On 25 April 2016 at 21:03, Rafał Cieślak <ravici...@gmail.com> wrote:

> Hi,
>
> I'm writing a turn-based game and one of the biggest functions is the one
> which handles player moves. It receives the current game state (a map) and
> the index of the cell that the player clicked on (an integer).
>
> It has to make a couple of decisions based on the game state. So far I
> just used -> and cond->. The code looks more or less like this, I removed
> a bunch of function calls for brevity.
>
> (-> game-state
>     ; This stuff happens on each move.
>     (reveal-cell cell-index)
>     ; And this stuff happens only under certain conditions.
>     (cond->
>       (zero? (:surrounding-power cell))
>       (reveal-safe-cells cell-index)))
>
> The code looks clear IMHO. But then I wanted to add another feature which
> requires me to make decisions based on the updated value of game-state
> (the one that is being threaded inside cond->).
>
> I thought about cond-> a bit and came to the conclusion that the reason
> you can't access the currently threaded value is to keep you from writing
> order-dependent statements. But in my case, I sometimes do want to write
> order-dependent code. For example, I want to give player exp for killing a
> monster and then if the exp is above certain threshold, I want to level up
> his character.
>
> So the problem is that I have to check the current value being threaded,
> but cond-> doesn't allow me to do that.
>
>
You don't need a macro for this sort of thing, and can get some way with
reduce. For example:

(defn apply-conditional-actions
  [game-state & pred-actions]
  (reduce (fn [game-state [pred action]]
            (if (pred game-state)
              (action game-state)
              game-state))
          game-state
          (partition 2 pred-actions)))

Then call this function with the game-state and a list of pred/action pairs:

(apply-conditional-actions game-state
                           safe-cell? reveal-safe-cells
                           monster-killed? inc-exp-points)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to