CLIPS 阻止检查一个盒子的多个面是否被占用

CLIPS defrule checking if multiple sides of a box are taken

我正在开发一个程序,它会告诉我在点阵游戏中应该采取哪些行动。我正在尝试实现一个 defrule 来检查一个盒子是否已经有 2 个可能的 4 面。如果是这种情况,那么我不想采取剩下的两条线中的任何一条,因为那样会给对手一个自由点。

(defrule Player_Move_No_Box_1_1
(next_turn p)
(turn_num ?t_num)
(test(> ?t_num 3))
(line ?l1&~1)
(not(line 1))
=>
(if
   (not(or(and(any-factp ((?l line)) (member$ (+ ?l1 3) ?l:implied))(any-factp ((?l line)) (member$ (+ ?l1 4) ?l:implied)))
       (and(any-factp ((?l line)) (member$ (+ ?l1 3) ?l:implied))(any-factp ((?l line)) (member$ (+ ?l1 7) ?l:implied)))
       (and(any-factp ((?l line)) (member$ (+ ?l1 4) ?l:implied))(any-factp ((?l line)) (member$ (+ ?l1 7) ?l:implied)))))
then
   (printout t "Take line #1" crlf)
   (assert(line 1))
   (assert(next_turn c))))

我一直在尝试很多不同的事情,但这是我最后一次尝试使用的代码,但没有成功。对于这段代码,我正在查看 line 1(从框的顶部开始顺时针编号:xx+4x+7x+3).是否有更简单的方法来进行此检查,或者这种方法是否有效,我只是在某处搞砸了代码?

我会建议将每条可能的线明确表示为事实,并在事实中表示该线是否已被采用。还要在规则的条件而不是操作中进行模式匹配。

CLIPS>  
(deftemplate line
   (slot id)
   (slot taken (default no)))     
CLIPS>       
(defrule Player_Move_Top_Line
   ?take <- (line (id ?l1) (taken no))
   (line (id =(+ ?l1 3)) (taken ?t3))
   (line (id =(+ ?l1 4)) (taken ?t4))
   (line (id =(+ ?l1 7)) (taken ?t7))
   (test (not (or (and (eq ?t3 yes) (eq ?t4 yes) (eq ?t7 no))
                  (and (eq ?t3 yes) (eq ?t4 no) (eq ?t7 yes))
                  (and (eq ?t3 no) (eq ?t4 yes) (eq ?t7 yes)))))
   =>
   (printout t "Take line #" ?l1 crlf)
   (modify ?take (taken yes)))
CLIPS>

为了便于测试,我已经从您的原始规则中删除了转弯信息。

CLIPS> (assert (line (id 0)) (line (id 3)) (line (id 4)) (line (id 7)))
<Fact-4>
CLIPS> (agenda)
0      Player_Move_Top_Line: f-1,f-2,f-3,f-4
For a total of 1 activation.
CLIPS> (reset)
CLIPS> (assert (line (id 0)) (line (id 3)) (line (id 4)) (line (id 7) (taken yes)))
<Fact-4>
CLIPS> (agenda)
0      Player_Move_Top_Line: f-1,f-2,f-3,f-4
For a total of 1 activation.
CLIPS> (reset)
CLIPS> (assert (line (id 0)) (line (id 3)) (line (id 4) (taken yes)) (line (id 7)))
<Fact-4>
CLIPS> (agenda)
0      Player_Move_Top_Line: f-1,f-2,f-3,f-4
For a total of 1 activation.
CLIPS> (reset)
CLIPS> (assert (line (id 0)) (line (id 3) (taken yes)) (line (id 4)) (line (id 7)))
<Fact-4>
CLIPS> (agenda)
0      Player_Move_Top_Line: f-1,f-2,f-3,f-4
For a total of 1 activation.
CLIPS> (reset)
CLIPS> (assert (line (id 0)) (line (id 3) (taken yes)) (line (id 4) (taken yes)) (line (id 7)))
<Fact-4>
CLIPS> (agenda)
CLIPS> (reset)
CLIPS> (assert (line (id 0)) (line (id 3) (taken yes)) (line (id 4)) (line (id 7) (taken yes)))
<Fact-4>
CLIPS> (agenda)
CLIPS> (reset)
CLIPS> (assert (line (id 0)) (line (id 3)) (line (id 4) (taken yes)) (line (id 7) (taken yes)))
<Fact-4>
CLIPS> (agenda)
CLIPS> (reset)
CLIPS> (assert (line (id 0)) (line (id 3) (taken yes)) (line (id 4) (taken yes)) (line (id 7) (taken yes)))
<Fact-4>
CLIPS> (agenda)
0      Player_Move_Top_Line: f-1,f-2,f-3,f-4
For a total of 1 activation.
CLIPS>