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