ajedrez: movimiento del alfil con CLIPS

Estoy tratando de implementar los posibles movimientos de un alfil en una mesa de ajedrez, que puede tener otras piezas en celdas aleatorias. He podido hacer un boceto de una respuesta, pero no detecta otras piezas.

Anteriormente a esta regla, escribí un código que crea un hecho como el siguiente para cada celda de la tabla, indicando su contenido:

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

y un hecho que muestra la posición de una pieza:

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

Y esta es mi regla hasta ahora (probablemente tampoco sea demasiado eficiente):

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

¿Alguien ahora qué podría hacer? Gracias por adelantado.

preguntado el 16 de mayo de 11 a las 18:05

1 Respuestas

;;; 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))))

Respondido el 06 de junio de 13 a las 00:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.