2015-06-15 8 views
0

Я работаю над программой, которая расскажет мне, какие шаги нужно делать в игре с точками и коробками. Я пытаюсь реализовать defrule, который будет проверять, есть ли в ящике 2 возможных удаленных сторон 4. Если это так, то я не хочу брать одну из оставшихся двух строк, так как это даст оппоненту свободный бал.CLIPS defrule проверка, если приняты несколько сторон коробки

(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 (по часовой стрелке, начиная с верхней части коробки пронумерованы: x, x+4, x+7, x+3). Есть ли более простой способ сделать эту проверку, или так будет работать, и я только что испортил код?

ответ

1

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

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>