2012-05-03 2 views
3

Я пытаюсь вычислить лучевые атаки дали индекс 64-битный Long bitboard представления в:Ray атака на bitboard

(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).

ответ

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)))) 
+0

К сожалению, это не работайте по мере необходимости: https://gist.github.com/2596793 – DanS

+0

@ DanS действительно и сейчас? – cgrand

+0

Да, сейчас работает. Осталось только то, что мне нужно учитывать индекс 0-7 или 63. Выбрасывает эту ошибку: ArityException Неверное количество аргументов (0), переданных в: core $ bit- или clojure.lang.AFn.throwArity. Необходимо поймать это исключение и вернуть пустую доску. – DanS

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) для рыцарей .....

Я думаю, что это будет более практичным, чем определение отдельных функций для каждого направления части.

+0

Похоже, что это был бы лучший подход, спасибо. – DanS

+0

Не знал о типе hint ^, это просто для производительности? – DanS

+0

Я не думаю, что тип подсказки здесь фактически что-то делает в настоящее время, но я помещал их как напоминание себе о типах аргументов и о том, что будущие компиляторы Clojure могут использовать его для оптимизации. – mikera

 Смежные вопросы

  • Нет связанных вопросов^_^