> (defn move
> "The function responsible for moving Pieces. Each piece knows how to move
> itself. If trying? is true, there will be no histiry of the new state of the
> board. Returns the new board."
>  ^clojure.lang.PersistentVector
> [game mappings p coords]
> {:pre [(satisfies? Piece p)]}  ;safety comes first
>
> (if (in? mappings (vector-of-doubles coords)) ;check that position exists on
> the grid
> (let [newPiece (update-position p coords)] ;the piece that results from the
> move
> (reset! (current-items game true) ;replace the appropriate board atom and
> log new state
> (populate-board game   ;replace dead-pieces with nils
> (-> (current-items game false) ;deref the appropriate board atom
>    (assoc (getListPosition p) nil) ;old position should have nil
>    (assoc (getListPosition newPiece) newPiece))))) ;new pos shoudl have the
> new piece
>
> (throw (IllegalArgumentException. (str coords " is NOT a valid position
> according to the mappings provided!")))))

There should not be any atom in this. The function would be more
reusable if it take a board and return
a board without changing any atom.
(You will still be to express the atom change around it but you could
also use to try and build a tree without undoing
anything.)

>
> (defmacro current-items
> [game atom?]
> `(condp = ~game
>       (symbol "chess")    (if ~atom? current-chessItems @current-chessItems)
>       (symbol "checkers") (if ~atom? current-checkers   @current-checkers)
> ))
>
I don't think this approach is extensible enough. You will want to
implement more games later.
So maybe a good thing is to use protocols or multimethods to represent
game rules.
The atoms should disappear until later. (You are building a library of
moves and rules, there is no notion
of state in that. Only when you use it for playing a game on a GUI you
will need a state)



> populate board is a monster I don't even want to look at it!
>
>
> (defn populate-board
> "Builds the appropriate board (chess or chekers). Will have nil at vacant
> positions. Really ugly fn but it does everything in 1 pass!"
>  ^clojure.lang.PersistentVector
> [game board]
> (loop [nb (vec (empty-board game)) ;building a brand new board after each
> move
>       p  board]
> (if (empty? p) nb
>  (let [fp (first p)]
>    (recur
>    (if (nil? fp) nb ;if encounter nil just carry on recursing with the
> current board
>       (assoc nb  ;else
>          (getListPosition fp)    ;the piece's position
>        (if (dead-piece? fp)   nil ;if the piece is dead stick nil
>                         fp)))  ; else stick the piece in
>         (rest p) )))))  ;carry on recursing
>
If it is just to remove dead pieces, you could do it during the move.
(When a piece is killed remove it immedialty.)
Then you don't need to copy the board, which will be in turn slightly
less expensive.
(Being able to share and not to copy is one of the benefits of immutability.)

Else something like (into [] (map (fn [x] (and (not (dead-piece? x))
x)) board)) should work.

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