Skip to content

Instantly share code, notes, and snippets.

@ihodes
Forked from mistercam/reversi-move-valid.clj
Created May 1, 2012 00:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ihodes/2563868 to your computer and use it in GitHub Desktop.
Save ihodes/2563868 to your computer and use it in GitHub Desktop.
A function to determine if a move in Reversi is valid
(def directions
{:N [-1 0] :NE [-1 1] :E [0 1] :SE [1 1] :S [1 0] :SW [1 -1] :W [0 -1] :NW [-1 -1]})
(defn move-valid? [board piece move]
"Returns true if the specified move for the specified piece will cause
a piece to be flipped in any direction."
(let [r (move 0) c (move 1)]
(cond
(or (> r 7) (< r 0) (> c 7) (< c 0)) nil
(not= nil ((board r) c)) nil
:else (or
(flippable? board piece move (directions :N ))
(flippable? board piece move (directions :NE ))
(flippable? board piece move (directions :E ))
(flippable? board piece move (directions :SE ))
(flippable? board piece move (directions :S ))
(flippable? board piece move (directions :SW ))
(flippable? board piece move (directions :W ))
(flippable? board piece move (directions :NW ))))))
(defn flippable? [board piece move direction]
"Examines each square on the board moving outward from the specified
move in the specified direction, looking for an opponent-piece that
could be flipped as a result of the move. If a flippable piece is found,
returns true, else returns false."
(loop [m (vec (map + move direction))] ; m is the current square
(let [r (m 0)
c (m 1)
rd (Math/abs (- (move 0) r)) ; num rows between originating square and current square
cd (Math/abs (- (move 1) c))] ; num cols between originating square and current square
(cond
(or (> r 7) (< r 0) (> c 7) (< c 0)) false ; 'm' is outside the board
(= nil ((board r) c)) false ; 'm' is empty
(= piece ((board r) c)) (or (> rd 1) (> cd 1)) ; return false if we're 1 move away from origin, else true
:else (recur (vec (map + m direction))))))) ; start next iteration of loop with 'm' set to next square
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment