3

鉴于 64 位长位板表示的索引,我正在尝试计算射线攻击:

(defn se [board index]
  "Produces a ray attack from the indexed bit in the south-east direction"
  (reduce bit-or
    (for [bit (rest (range index 0 -7))]
      (bit-flip board bit))))

车攻击(直接沿着文件或等级)很容易。但是,上面代码的问题是我最终得到了对角 Bishop 攻击的以下可能性:

00000000
00100000
01000000
10000001
00000010
00000100
00001000
00010000

当棋子从棋盘边缘脱落时,我应该如何解释?我正在使用大端映射(A8 = 0,H1 = 63)。

4

2 回答 2

1

我可能会使用板上的 x,y 坐标来执行此操作:这使得在板边缘上进行边界条件检查变得更容易,例如

(defn se [x y]
  "Produces a ray attack from the indexed bit in the south-east direction"
  (let [initial (bit-shift-left (bit-shift-left (long 1) x) (* y 8))
        dx 1 ;; x direction
        dy 1 ;; y direction
        distance (min 
                   (- 7 x) 
                   (- 7 y))
        shift (+ dx (* 8 dy))]
    (loop [value 0
           distance distance]
      (if (<= distance 0)
        value
        (recur (bit-or value (bit-shift-left initial (* distance shift))) (dec distance))))))

(defn bits [^long bitboard]
  (map 
    #(if (> (bit-and 1 (bit-shift-right bitboard %)) 0) 1 0)
    (range 64)))

(defn display [bitboard]
  (let [bits (partition 8 (bits bitboard))]
    (doseq [ss bits]
      (println (apply str ss)))))

(display (se 1 3))

00000000
00000000
00000000
00000000
00100000
00010000
00001000
00000100

通过一些额外的工作,您可以将其概括为在任何 (dx, dy) 方向上投射光线,例如 (1,0) 表示向东移动的车。如果您设置距离限制,您甚至可以将 (2,1) 用于骑士.....

我认为这比为每个方向定义单独的功能更实用。

于 2012-05-04T01:32:53.870 回答
1
(defn se [board index]
  "Produces a ray attack from the indexed bit in the south-east direction"
  (reduce bit-or 0
    (for [bit (take (- 7 (rem index 8)) (rest (range index 0 -7)))]
      (bit-flip board bit))))
于 2012-05-04T08:09:57.863 回答