Луч атакует на доске
Я пытаюсь вычислить лучевые атаки, учитывая индекс представления 64-битной Long board:
(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))))
Атаки ладьи (прямо вдоль файла или ранга) достаточно легки. Однако проблема с приведенным выше кодом заключается в том, что я получаю следующую возможность для диагональных атак Бишопа:
00000000
00100000
01000000
10000001
00000010
00000100
00001000
00010000
Как следует учитывать случай, когда фигура сходит с края доски? Я использую отображение с прямым порядком байтов (A8 = 0, H1 = 63).
2 ответа
(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))))
Я, вероятно, сделал бы это, используя координаты 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) для рыцарей.....
Я думаю, что это будет более практичным, чем определение отдельных функций для каждого направления пьесы.