Hi again,

I tried a couple of things during the day and I came up with a solution that is both performant and decoupled from the core.logic part of the program...It turns out I could achieve the 'filtering' I wanted with a couple of HOFs...I 'm happy with my solution mainly because I don't have to touch my core.logic code ... to give you an idea, it is sufficient to add the following line just before the 'run*' statement on all my core.logic functions:

(remove #(collides? [x y] % (make-walker (resolve-direction [x y] %)) board mappings colour)
 (run* [q]
 ... ... ...

 * 'collides?' is a recursive fn that accepts the starting position,
   the ending position, a walker-fn, the current board, the
   board-mappings and the colour of the piece that is trying to move.
   all of this was already available apart from the walker.
 * the walker allows 'collides?' to try doing the move one step at a
   time and check if it collides with anything or not. the walker only
   provides the mechanics of moving...'collides' is the one going into
   recursion.

Also there is practically no overhead! I don't know how this is possible but timing it for a couple of hundred times shows no difference whatsoever (it settles at 1.81 ms roughly)...this is really good stuff!!! Chess is almost complete now!I can start showing things up on screen :-)

In case someone is confused about how I did it, the 3 fns at the end should clear things up...

Jim

---------------------------------------------------------------------------------------------
(defn make-walker [direction]
 (fn [[sx sy]]
   (condp = direction
          :north [sx (dec sy)]
          :south [sx (inc sy)]
          :east  [(dec sx) sy]
          :west  [(inc sx) sy]
          :north-east [(inc sx) (dec sy)]
          :north-west [(dec sx) (dec sy)]
          :south-east [(inc sx) (inc sy)]
          :south-west [(dec sx) (inc sy)])))

(defn resolve-direction
[[sx sy] [ex ey]]
(let [dx (- ex sx)
      dy (- ey sy)]
(cond
   (and (pos? dx)  (zero? dy)) :west
   (and (neg? dx)  (zero? dy)) :east
   (and (pos? dx)  (pos?  dy)) :south-east
   (and (pos? dx)  (neg?  dy)) :north-east
   (and (zero? dx) (pos? dy))  :south
   (and (zero? dx) (neg? dy))  :north
   (and (neg? dx)  (neg? dy))  :north-west
   (and (neg? dx)  (pos? dy))  :south-west)))

(defn collides?
[[sx sy] [ex ey] walker b m dir]
(let [[next-x next-y] (walker [sx sy])]
(cond
  (and (= ex sx) ;if reached destination
(= ey sy)) (if (not= dir (:direction (get b (translate-position (double ex) (double ey) m)))) false true) (= dir (:direction (get b (translate-position (double next-x) (double next-y) m)))) true
:else (recur [next-x next-y] [ex ey] walker b m dir))))

----------------------------------------------------------------------------------------------------------------------------------------------------

On 15/08/12 15:09, David Nolen wrote:
On Wed, Aug 15, 2012 at 9:53 AM, Jim - FooBar(); <jimpil1...@gmail.com> wrote:
OK thanks a lot both of you....it turns out the != works just fine!

at the moment I've almost completed the entire moving rules for chess and
checkers (including kills) but only on an empty board...the only thing
remaining to finish things off is ideally a 'non-blocking?' fn to check each
move generated against the current-board. essentially filtering out the
moves that are blocked by other pieces...do you think this can be done
non-relationally by a novice or am I better off using a regular fn?

any clues are greatly appreciated...

Jim
Thinking relationally on large problems is challenging. When I'm
having serious trouble, I will often translate my solution into Prolog
and ask questions about it on StackOverflow - there seems to be an
active if small Prolog community there. Also #prolog on freenode seems
pretty helpful. Good luck and let us know what you discover along the
way! :)

David


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

Reply via email to