Skip to content
Browse files

Separate board from game mechanics

  • Loading branch information...
1 parent 78e1e41 commit b00453ff0fa5428859108df86a1b0de389759a0c @reiddraper committed Apr 18, 2012
Showing with 79 additions and 83 deletions.
  1. +68 −0 src/crosscram/board.clj
  2. +11 −83 src/crosscram/core.clj
View
68 src/crosscram/board.clj
@@ -0,0 +1,68 @@
+(ns crosscram.board
+ (:require [clojure.core.match :as match]))
+
+(defn valid-pair? [[a b] [c d]]
+ (cond (= a c) (= 1 (Math/abs (- b d)))
+ (= b d) (= 1 (Math/abs (- a c)))
+ :else false))
+
+(defn horizontal-pair? [[a b] [c d]]
+ (if (= a c)
+ (= 1 (Math/abs (- b d)))
+ false))
+
+(defn vertical-pair? [[a b] [c d]]
+ (if (= b d)
+ (= 1 (Math/abs (- a c)))
+ false))
+
+(defn- generate-horizontal-for-row [columns row]
+ (take (- columns 1)
+ (for [x (range columns)]
+ [[row x] [row (+ 1 x)]])))
+
+(defn- generate-vertical-for-column [rows column]
+ (take (- rows 1)
+ (for [x (range rows)]
+ [[x column] [(+ 1 x) column]])))
+
+(defn generate-horizontal [rows columns]
+ (mapcat (partial generate-horizontal-for-row columns)
+ (range rows)))
+
+(defn generate-vertical [rows columns]
+ (mapcat (partial generate-vertical-for-column rows)
+ (range columns)))
+
+(defn- two-nil? [coll]
+ (= true (reduce (fn [acc elem]
+ (match/match [acc elem]
+ [true _] true
+ [0 nil] 1
+ [1 nil] true
+ [_ _] 0))
+ 0 coll)))
+
+(defn can-play-horizontal? [board]
+ (boolean
+ (some identity (map two-nil? board))))
+
+(defn can-play-vertical? [board]
+ (can-play-horizontal? (apply map vector board)))
+
+(defn two-d-get [coll [a b]]
+ (get (get coll a) b))
+
+(defn location-empty? [board pos-a pos-b]
+ (and (nil? (two-d-get board pos-a))
+ (nil? (two-d-get board pos-b))))
+
+(defn board [rows columns]
+ (vec (repeat rows
+ (vec
+ (take columns (repeat nil))))))
+
+(defn add-piece [board piece a b]
+ (-> board
+ (assoc-in a piece)
+ (assoc-in b piece)))
View
94 src/crosscram/core.clj
@@ -1,76 +1,7 @@
(ns crosscram.core
- (:require [clojure.core.match :as match]))
+ (:require [crosscram.board :as board]
+ [clojure.core.match :as match]))
-(defn- abs [x]
- (if (< x 0)
- (* -1 x)
- x))
-
-(defn valid-pair? [[a b] [c d]]
- (cond (= a c) (= 1 (abs (- b d)))
- (= b d) (= 1 (abs (- a c)))
- true false))
-
-(defn horizontal-pair? [[a b] [c d]]
- (if (= a c)
- (= 1 (abs (- b d)))
- false))
-
-(defn vertical-pair? [[a b] [c d]]
- (if (= b d)
- (= 1 (abs (- a c)))
- false))
-
-(defn- generate-horizontal-for-row [columns row]
- (take (- columns 1)
- (for [x (range columns)]
- [[row x] [row (+ 1 x)]])))
-
-(defn- generate-vertical-for-column [rows column]
- (take (- rows 1)
- (for [x (range rows)]
- [[x column] [(+ 1 x) column]])))
-
-(defn generate-horizontal [rows columns]
- (mapcat (partial generate-horizontal-for-row columns)
- (range rows)))
-
-(defn generate-vertical [rows columns]
- (mapcat (partial generate-vertical-for-column rows)
- (range columns)))
-
-(defn- two-nil? [coll]
- (= true (reduce (fn [acc elem]
- (match/match [acc elem]
- [true _] true
- [0 nil] 1
- [1 nil] true
- [_ _] 0))
- 0 coll)))
-
-(defn can-play-horizontal? [board]
- (boolean
- (some identity (map two-nil? board))))
-
-(defn can-play-vertical? [board]
- (can-play-horizontal? (apply map vector board)))
-
-(defn two-d-get [coll [a b]]
- (get (get coll a) b))
-
-(defn location-empty? [board pos-a pos-b]
- (and (nil? (two-d-get board pos-a))
- (nil? (two-d-get board pos-b))))
-
-(defn board [rows columns]
- (vec (repeat rows
- (vec
- (take columns (repeat nil))))))
-
-(defn add-piece [board piece a b]
- (-> board
- (assoc-in a piece)
- (assoc-in b piece)))
(defn opposite [player]
(match/match player
@@ -79,8 +10,8 @@
(defn over? [game]
(match/match (:next-player game)
- :horizontal (not (can-play-horizontal? (:board game)))
- :vertical (not (can-play-vertical? (:board game)))))
+ :horizontal (not (board/can-play-horizontal? (:board game)))
+ :vertical (not (board/can-play-vertical? (:board game)))))
(defn winner [game]
(when (over? game)
@@ -93,27 +24,24 @@
;; are the two points valid for this player?
(not (match/match (:next-player game)
- :horizontal (horizontal-pair? pos-a pos-b)
- :vertical (vertical-pair? pos-a pos-b)))
+ :horizontal (board/horizontal-pair? pos-a pos-b)
+ :vertical (board/vertical-pair? pos-a pos-b)))
(throw (Exception. (str "Not a valid vertical or horizontal shape: " pos-a pos-b)))
;; is someone trying to play on a spot that is already
;; occupied?
- (not (location-empty? (:board game) pos-a pos-b)) (throw (Exception.
- "Can't move here, it's occupied"))
+ (not (board/location-empty? (:board game) pos-a pos-b)) (throw (Exception.
+ "Can't move here, it's occupied"))
;; ok, play the piece!
- true
+ :else
(-> game
- ;; (assoc :board (add-piece board {:move-number num-plays
- ;; :location [pos-a pos-b]}
- ;; pos-a pos-b))
- (assoc :board (add-piece (:board game) (inc (count (:history game))) pos-a pos-b))
+ (assoc :board (board/add-piece (:board game) (inc (count (:history game))) pos-a pos-b))
(update-in [:history] #(conj % {:player (:next-player game) :move [pos-a pos-b]}))
(assoc :next-player (opposite (:next-player game))))))
(defn new-game [rows columns start-player]
- {:board (board rows columns)
+ {:board (board/board rows columns)
:rows rows
:columns columns
:next-player start-player

0 comments on commit b00453f

Please sign in to comment.
Something went wrong with that request. Please try again.