我对Clojure还很陌生,所以我决定编写一个连接四的程序,以获得乐趣和学习。
下面的代码是这个位板算法的Clojure实现。
完整的代码可以在这里找到:https://gist.github.com/3639220
我不确定的是函数(插入)和(位检查板):
(defn insert
"Inserts symbol for given player (either 1 or 2) at specified x and
calls bit-insert for corresponding bitboard."
[boards x player-num]
(let [y (get-y (boards 0) x)]
(if (= player-num 1) ; TODO: improve
(vector
(assoc-in (boards 0) [y x] (player player-num))
(bit-insert (boards 1) (- 5 y) x)
(boards 2))
(vector
(assoc-in (boards 0) [y x] (player player-num))
(boards 1)
(bit-insert (boards 2) (- 5 y) x)))))
(defn bit-check-board ; TODO: improve
"Checks whether given bitboard is a win."
[bitboard]
(let [diag1 (bit-and bitboard (bit-shift-right bitboard 6))
hori (bit-and bitboard (bit-shift-right bitboard 7))
diag2 (bit-and bitboard (bit-shift-right bitboard 8))
vert (bit-and bitboard (bit-shift-right bitboard 1))]
(bit-or (bit-and diag1 (bit-shift-right diag1 (* 2 6)))
(bit-and hori (bit-shift-right hori (* 2 7)))
(bit-and diag2 (bit-shift-right diag2 (* 2 8)))
(bit-and vert (bit-shift-right vert (* 2 1))))))发布于 2012-09-06 10:38:40
bit-check-board确实可以改进。这就是我通过把共同的部分连接在一起而得到的结果,尽管我认为它还可以进一步改进:
(defn check [c x]
(bit-and c (bit-shift-right c x)))
(defn bit-check-board
"Checks whether given bitboard is a win."
[bitboard]
(let [positions [6 7 8 1]
coords (mapv (partial check bitboard) positions)]
(apply bit-or (map check coords (map #(* 2 %) positions)))))此外,您还可以通过更好地模块化代码和使用带有预计算转换表的高阶函数来减少insert函数中的重复:
(defn insert* [board x y]
(bit-insert board (- 5 y) x))
(defn get-transforms [num]
(if (= 1 num)
[identity insert* identity]
[identity identity insert*]))
(defn insert
"Inserts symbol for given player (either 1 or 2) at specified x and
calls bit-insert for corresponding bitboard."
[boards x player-num]
(let [y (get-y (boards 0) x)
board0 (assoc-in (boards 0) [y x] (player player-num))
transfv (get-transforms player-num)]
(mapv [board0 (boards 1) (boards 2)] transv)))如果您在Clojure上< 1.4,则必须更改(mapv ...)中的(vector (map ...))
https://codereview.stackexchange.com/questions/15378
复制相似问题