Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (ns chess.state)
- (defn make-board
- "Creates a chess board in the initial configuration."
- []
- '({:type :rook :color :black :rank 8 :file 1 }
- {:type :knight :color :black :rank 8 :file 2 }
- {:type :bishop :color :black :rank 8 :file 3 }
- {:type :queen :color :black :rank 8 :file 4 }
- {:type :king :color :black :rank 8 :file 5 }
- {:type :bishop :color :black :rank 8 :file 6 }
- {:type :knight :color :black :rank 8 :file 7 }
- {:type :rook :color :black :rank 8 :file 8 }
- {:type :pawn :color :black :rank 7 :file 1 }
- {:type :pawn :color :black :rank 7 :file 2 }
- {:type :pawn :color :black :rank 7 :file 3 }
- {:type :pawn :color :black :rank 7 :file 4 }
- {:type :pawn :color :black :rank 7 :file 5 }
- {:type :pawn :color :black :rank 7 :file 6 }
- {:type :pawn :color :black :rank 7 :file 7 }
- {:type :pawn :color :black :rank 7 :file 8 }
- {:type :pawn :color :white :rank 2 :file 1 }
- {:type :pawn :color :white :rank 2 :file 2 }
- {:type :pawn :color :white :rank 2 :file 3 }
- {:type :pawn :color :white :rank 2 :file 4 }
- {:type :pawn :color :white :rank 2 :file 5 }
- {:type :pawn :color :white :rank 2 :file 6 }
- {:type :pawn :color :white :rank 2 :file 7 }
- {:type :pawn :color :white :rank 2 :file 8 }
- {:type :rook :color :white :rank 1 :file 1 }
- {:type :knight :color :white :rank 1 :file 2 }
- {:type :bishop :color :white :rank 1 :file 3 }
- {:type :queen :color :white :rank 1 :file 4 }
- {:type :king :color :white :rank 1 :file 5 }
- {:type :bishop :color :white :rank 1 :file 6 }
- {:type :knight :color :white :rank 1 :file 7 }
- {:type :rook :color :white :rank 1 :file 8 }))
- (ns chess.movement
- (:require [chess.state :refer :all]
- [clojure.math.numeric-tower :as math]))
- (defn on-board?
- "Determines if a position is on the board."
- [[rank file :as position]]
- (and (>= rank 1)
- (<= rank 8)
- (>= file 1)
- (<= file 8)))
- (defn same-rank?
- "Determines if two positions are in the same rank."
- [[start-rank start-file :as position] [dest-rank dest-file :as destination]]
- (and (= dest-rank start-rank) (not= dest-file start-file)))
- (defn same-file?
- "Determines if two positions are in the same file."
- [[start-rank start-file :as position] [dest-rank dest-file :as destination]]
- (and (= dest-file start-file) (not= dest-rank start-rank)))
- (defn diagonal?
- "Determines if two positions are diagonal from each other. We need this for things like determining whether a pawn movement is a capture, etc."
- [[start-rank start-file :as position] [dest-rank dest-file :as destination]]
- (= (math/abs (- start-rank dest-rank))
- (math/abs (- start-file dest-file))))
- (defn occupied?
- "Determines if a location on the board is occupied by a piece. If the color actual
- parameter is provided then the piece at that location must be that color. We need to know this
- to help determine the ability to move, capture, etc."
- ([board [rank file :as position]]
- (some #(and (= rank (% :rank)) (= file (% :file))) board))
- ([board [rank file :as position] color]
- (some #(and (= rank (% :rank)) (= file (% :file)) (= color (% :color))) board)))
- (defn opponent-color
- "Returns the opponent's color."
- [color]
- (cond
- (= color :black) :white
- (= color :white) :black))
- (defn remove-pieces
- "Removes pieces from the board at the specified locations."
- [board position & remaining-positions]
- (let [positions (into #{position} remaining-positions)
- matching-position? #(positions [(% :rank) (% :file)])]
- (remove matching-position? board)))
- (defn positions-between
- "Generates a list of the positions between start and end. If the
- start and end positions aren't in the same rank, file, or diagonal
- from each other then returns an empty sequence."
- [[s-rank s-file :as start] [e-rank e-file :as end]]
- (let [min-rank (min s-rank e-rank)
- max-rank (max s-rank e-rank)
- min-file (min s-file e-file)
- max-file (max s-file e-file)]
- (cond
- (= min-rank max-rank)
- (into '() (map (fn [file] [min-rank file]) (range (inc min-file) max-file)))
- (= min-file max-file)
- (into '() (map (fn [rank] [rank min-file]) (range (inc min-rank) max-rank)))
- (diagonal? start end)
- (into '() (map (fn [rank file] [rank file]) (range (inc min-rank) max-rank) (range (inc min-file) max-file)))
- :else '())))
- (defn movement-blocked?
- "Move is blocked if the destination is occupied by the player's own piece, or
- if any position between the start and destination contains a piece. Note that
- this function does not work for Pawns (yet) because a pawn is blocked when
- moving forward if the destination is occupied by any piece."
- [board [rank file :as position] [dest-rank dest-file :as destination] color]
- (or (occupied? board destination color)
- (some (into #{} (positions-between position destination))
- (map (fn [p] [(p :rank) (p :file)]) board))))
- (ns chess.rook-movement
- (:require [chess.movement :refer :all]
- [chess.state :refer :all]))
- (defn valid-rook-move?
- "Determines if a rook can make a move from one position to another on a board."
- [board [start-rank start-file :as position] [dest-rank dest-file :as destination] color]
- (and (on-board? destination)
- (or (same-rank? position destination)
- (same-file? position destination))
- (not (movement-blocked? board position destination color))))
- (defn rook-destinations
- "Returns a lazy sequence of positions (tuples containing rank and file) that a rook can move to."
- [board [rank file :as position] color]
- (let [possible-dests (concat (map (fn [f] [rank f]) (range 1 9))
- (map (fn [r] [r file]) (range 1 9)))]
- (filter #(valid-rook-move? board position % color) possible-dests)))
- (same-file? position destination))
- (not (movement-blocked? board position destination color))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement