Skip to content

Instantly share code, notes, and snippets.

@daveray
Created October 18, 2011 03:55
Show Gist options
  • Save daveray/1294571 to your computer and use it in GitHub Desktop.
Save daveray/1294571 to your computer and use it in GitHub Desktop.
Joy of Clojure Chess Example in Familiar/JRuby
# Rough translation from Joy of Clojure refs example in Familiar
# https://github.com/daveray/familiar
# https://github.com/joyofclojure/book-source/blob/master/src/joy/refs.clj
$initial_board = [[:o, :k, :o],
[:o, :o, :o],
[:o, :K, :o]].to_clojure
# (defn board-map [f bd]
# (vec (map #(vec (for [s %] (f s))) bd)))
def board_map(f, bd)
Familiar.with do
vec(map(fn {|v| vec(map f, v)}, bd))
end
end
# (defn reset!
# "Resets the board state. Generally these types of functions are a
# bad idea, but matters of page count force our hand."
# []
# (def board (board-map ref initial-board))
# (def to-move (ref [[:K [2 1]] [:k [0 1]]]))
# (def num-moves (ref 0)))
def reset!
$board = board_map Familiar[:ref], $initial_board
$to_move = Familiar.ref [[:K, [2, 1]], [:k, [0, 1]]].to_clojure
$num_moves = Familiar.ref 0
end
# (defn neighbors
# ([size yx]
# (neighbors [[-1 0] [1 0] [0 -1] [0 1]] size yx))
# ([deltas size yx]
# (filter
# (fn [new-yx] (every? #(< -1 % size) new-yx))
# (map #(vec (map + yx %)) deltas))))
def neighbors(deltas, size, yx)
#deltas = [[-1, 0], [1, 0], [0, -1], [0, 1]].to_clojure
Familiar.with do
plus = self[:+]
on_board = fn {|v| -1 < v && v < size }
filter fn {|new_yx| every? on_board, new_yx},
map(fn {|v| vec(map plus, yx, v)}, deltas)
end
end
#(def king-moves (partial neighbors [[-1 -1] [-1 0] [-1 1] [0 -1] [0 1] [1 -1] [1 0] [1 1]] 3))
$king_moves = Familiar.with do
partial fn(method(:neighbors).to_proc),
[[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]].to_clojure,
3
end
#(defn good-move? [to enemy-sq] (when (not= to enemy-sq) to))
def good_move?(to, enemy_sq)
to != enemy_sq ? to : nil
end
#(defn choose-move [[[mover mpos][_ enemy-pos]]]
# [mover
# (some #(good-move? % enemy-pos) (shuffle (king-moves mpos)))])
def choose_move(tm)
Familiar.with do
mover = ffirst(tm)
mpos = second(first(tm))
enemy_pos = second(second(tm))
vector mover,
some(fn {|v| good_move?(v, enemy_pos)},
shuffle($king_moves.invoke(mpos)))
end
end
#(defn place [from to] to)
$place = Familiar.fn {|from, to| to}
# (defn move-piece [[piece dest] [[_ src] _]]
# (alter (get-in board dest) place piece)
# (alter (get-in board src ) place :o)
# (alter num-moves inc))
def move_piece(move, to_move)
Familiar.with do
piece = first(move)
dest = second(move)
src = second(first(to_move))
alter get_in($board, dest), $place, piece
alter get_in($board, src), $place, :o.to_clojure
alter $num_moves, self[:inc]
end
end
# (defn update-to-move [move]
# (alter to-move #(vector (second %) move)))
def update_to_move(move)
Familiar.with do
alter $to_move, fn {|v| vector(second(v), move)}
end
end
# (defn make-move []
# (dosync
# (let [move (choose-move @to-move)]
# (move-piece move @to-move)
# (update-to-move move))))
def make_move
Familiar.dosync do
move = choose_move $to_move.deref
move_piece move, $to_move.deref
update_to_move move
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment