Skip to content

Instantly share code, notes, and snippets.

View mistercam's full-sized avatar

Cameron Donaldson mistercam

  • Toronto, ON, Canada
View GitHub Profile
@mistercam
mistercam / reversi-initialize.clj
Created April 22, 2012 19:08
Reversi game board initialization form
(defn initialize-board []
"Creates a new reversi game board"
[[nil nil nil nil nil nil nil nil]
[nil nil nil nil nil nil nil nil]
[nil nil nil nil nil nil nil nil]
[nil nil nil :w :b nil nil nil]
[nil nil nil :b :w nil nil nil]
[nil nil nil nil nil nil nil nil]
[nil nil nil nil nil nil nil nil]
[nil nil nil nil nil nil nil nil]])
@mistercam
mistercam / reversi-move-valid.clj
Created April 29, 2012 12:55
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
@mistercam
mistercam / reversi-game-over.clj
Created April 29, 2012 13:16
Functions to determine if the Reversi game is over
(defn valid-moves [board piece]
"Returns the set of valid moves for the given piece"
(for [r (range 8) c (range 8) ; for each permutation of r and c
:let [move [r c]]
:when (move-valid? board piece move)]
move))
(defn game-over? [board]
"Returns true if there are no more moves to be made on the board, else returns false"
(and
@mistercam
mistercam / reversi-winner.clj
Created April 29, 2012 13:19
Functions to help determine who the winner is
(defn count-pieces [board piece]
"Returns the number of squares occupied by the specified piece"
(count (filter #(= % piece) (flatten board))))
(defn winner [board]
"Returns the winner, or nil if there's a tie"
(let [w (count-pieces board :w ) b (count-pieces board :b )]
(cond
(> w b) :w (> b w) :b :else nil)))
@mistercam
mistercam / reversi-flip.clj
Created April 29, 2012 13:35
Functions to execute specific moves on the Reversi board
(defn flip [board piece move direction]
"Returns a new board with results of playing the specified move and piece"
(if (flippable? board piece move direction)
(loop [b board m (vec (map + move direction))] ; bind board to b so we can use it in recur
(let [r (m 0)
c (m 1)
p ((board r) c)]
(if (= p piece)
b ; we've come to a piece the same colour as the active piece, so we're done flipping. Return the modified board.
(recur (assoc b r (assoc (b r) c piece)) (vec (map + m direction)))))) ; more flipping to be done, so flip and recur.
@mistercam
mistercam / reversi-opposite-piece.clj
Created April 29, 2012 14:38
A function that returns the opposing piece of the specified piece
(defn opposite-piece [piece]
"Returns the opposing-piece of the specified piece"
(if (= :w piece) :b :w ))
@mistercam
mistercam / reversi-text-board.clj
Created April 29, 2012 15:20
Functions to print a text version of the Reversi board
(def columns
{"A" 0 "B" 1 "C" 2 "D" 3 "E" 4 "F" 5 "G" 6 "H" 7})
(defn print-cols [row]
"Prints the contents of the each square in the specified row to standard
out."
(if (not (empty? row))
(let [c (first row)]
(cond
(= :w c) (print "W")
@mistercam
mistercam / reversi-text-input.clj
Created April 29, 2012 16:08
Functions to verify input for a text game of Reversi
(defn malformed-input? [input]
"Returns true if the input is valid, otherwise false."
(not (re-find (re-matcher #"^([0-7][A-Ha-h])$|^([A-Ha-h][0-7])$" input))))
(defn parse-input [input]
"Converts the user input into a coordinate vector"
(let [f (str (first input)) l (str (last input))]
(if (Character/isDigit (first input))
[(Integer/parseInt f) (columns (string/upper-case l))] ; e.g 2E
[(Integer/parseInt l) (columns (string/upper-case f))]))) ; e.g E2
@mistercam
mistercam / reversi-text-prompt.clj
Created April 29, 2012 16:29
Function that asks for and accepts a Reversi move from the user.
(defn prompt-for-move [piece board]
"Prompts the user for a move. Returns the move, if-valid. Returns nil
if user has quit."
(loop [input (atom "")]
(if (= :w piece) ; Prints an input prompt
(print "White's Turn. Enter move: ")
(print "Black's Turn. Enter move: "))
(flush) ; We printed the prompt with a 'print' instead of 'println'. Flushing forces the prompt to appear.
(reset! input (str (read-line))) ; Read input and store back into 'input'
(cond
@mistercam
mistercam / reversi-text.clj
Created April 29, 2012 16:43
Function to start a text-based Reversi game
(defn print-winner [board]
"Prints game over to standard out and declares the winner"
(let [p (winner board)] ; 'p' is the piece with the most coverage
(cond
(= p :b ) (println "Game over. Black Wins!")
(= p :w ) (println "Game over. White Wins!")
:else (println "Game over. Tie!"))))
(defn reversi-text []
"Starts a text-based Reversi game."