шахматы: слон ход с зажимами - PullRequest
1 голос
/ 16 мая 2011

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

Ранее к этому правилу я написал некоторый код, который создает факт, подобный следующему, для каждой ячейки таблицы, указывая ее содержимое:

(cell-info (coor {i} {j}) (contents {empty|black|white})) 

и факт, показывающий положение фигуры:

 (piece (row {r}) (column {c}) (type {t}) (color {col}))

А вот мое правило (возможно, оно тоже не слишком эффективно):

(defrule bishop-moves
    (declare (salience 30))
    (piece (row ?rb) (column ?cb) (type bishop) (color black))
    (cell-info (coor ?i ?j) (contents empty|white))
=>
    (loop-for-count (?n 1 8)
       (if (or (and (= ?i (+ ?rb ?n)) (= ?j (+ ?cb ?n)))
           (and (= ?i (- ?rb ?n)) (= ?j (- ?cb ?n)))
           (and (= ?i (+ ?rb ?n)) (= ?j (- ?cb ?n)))
           (and (= ?i (- ?rb ?n)) (= ?j (+ ?cb ?n))))
         then (assert (movement-allowed
                     (destination-cell ?i ?j)
                     (type bishop)
                     (start-cell ?rb ?cb))))))

Кто-нибудь теперь, что я мог сделать? Заранее спасибо.

1 Ответ

0 голосов
/ 06 июня 2013
;;; Added deftemplates and deffacts
;;; Replaced rule variable ?i with ?r and ?j with ?c.
;;; Made rule applicable for both black or white bishop
;;; Moved diagonal logic from actions of rule to conditions
;;; Added logic to rule for intervening pieces

(deftemplate piece (slot row) (slot column) (slot type) (slot color))
(deftemplate cell-info (multislot coor) (slot contents))
(deftemplate movement-allowed (multislot destination-cell) (slot type) (multislot start-cell))

(deffacts test-data
   (piece (row 1) (column 1) (type pawn) (color black))
   (cell-info (coor 1 1) (contents black))  ; Invalid - friendly piece
   (cell-info (coor 1 2) (contents empty))  ; Invalid - not on diagonal
   (cell-info (coor 1 3) (contents empty))  ; Valid
   (piece (row 2) (column 2) (type bishop) (color black))
   (cell-info (coor 2 2) (contents black))  ; Invalid - friendly piece
   (cell-info (coor 2 8) (contents empty))  ; Invalid - not on diagonal
   (cell-info (coor 3 1) (contents empty))  ; Valid
   (cell-info (coor 3 3) (contents empty))  ; Valid
   (cell-info (coor 4 4) (contents empty))  ; Valid
   (cell-info (coor 5 5) (contents empty))  ; Valid
   (piece (row 6) (column 6) (type pawn) (color white))
   (cell-info (coor 6 6) (contents white))  ; Valid
   (cell-info (coor 7 7) (contents empty))  ; Invalid - blocked by pawn
   (piece (row 8) (column 8) (type pawn) (color white))
   (cell-info (coor 8 8) (contents white))) ; Invalid - blocked by pawn

(defrule bishop-moves

   (declare (salience 30))

   (piece (row ?rb) (column ?cb) (type bishop) (color ?color))

   ;; The destination cell must be empty or contain 
   ;; an opposing piece

   (cell-info (coor ?r ?c) (contents empty | ~?color))

   ;; If the cell and piece are on the same diagonal, the
   ;; absolute difference between the two should be the same

   (test (= (abs (- ?r ?rb)) (abs (- ?c ?cb))))

   ;; Check that there is not another piece that is within
   ;; the rectangle formed by the bishop and the destination
   ;; cell and is also on the same diagonal as the bishop

   (not (and (piece (row ?ro) (column ?co))

             (test (and (or (< ?rb ?ro ?r) (< ?r ?ro ?rb))
                        (or (< ?cb ?co ?c) (< ?c ?co ?cb))))

             (test (= (abs (- ?ro ?rb)) (abs (- ?co ?cb))))))

   =>

   (assert (movement-allowed
                     (destination-cell ?r ?c)
                     (type bishop)
                     (start-cell ?rb ?cb))))
...