首页 > 解决方案 > Prolog - findall 返回一个未实例化的变量列表,而不是值

问题描述

我正在 Prolog 中编写一个跳棋游戏,我想编写一个谓词来打印所有可能的移动。

我有一个谓词来检查所有可以做出的合法动作 -

is_move_legal(Board,p(X1,Y1),p(X2,Y2),DoEat, Player):-
    Player = w,             % making sure the "right" player is playing here - white
    get(Board,p(X1,Y1),w),
    (
    get(Board,p(X2,Y2),1); % make sure no player is in the dest cell
    get(Board,p(X2,Y2),0) % make sure no player is in the dest cell
    ),
    between(1,8,X1),between(1,8,X2),between(1,8,Y1),between(1,8,Y2),
    (
    (DoEat = 0, X2 is X1-1,Y2 is Y1-1); % we don't eat
    (DoEat = 0, X2 is X1-1,Y2 is Y1+1);
    (DoEat = 1, X2 is X1-2, Y2 is Y1-2, X3 is X1-1, Y3 is Y1-1, (get(Board,p(X3,Y3),b);get(Board,p(X3,Y3),bk)),remove(Board,p(X3,Y3))); % eat the black soldier
    (DoEat = 1, X2 is X1-2, Y2 is Y1+2, X3 is X1-1, Y3 is Y1+1, (get(Board,p(X3,Y3),b);get(Board,p(X3,Y3),bk)),remove(Board,p(X3,Y3))) % eat the black soldier
    ).

我对黑人士兵和“国王”士兵有类似的谓词。

这是 findall 谓词 -

% find all possible moves   
moves(Board,Moves):-
    findall((X->Y),is_move_legal(Board,P1,P2,_,b),Moves).

似乎它确实找到了动作,但是这是我得到的输出 -

[(_8090->_8092),(_8078->_8080),(_8066->_8068),(_8054->_8056),(_8042->_8044),(_8030->_8032),(_8018->_8020),(_8006->_8008)]

我想要做的是满足is_move_legal谓词中的 p(X1,Y1), p(X2,Y2) 参数。

编辑:

从这里的评论中我意识到了错误-而不是(X-> Y),写-

    findall((P1->P2),is_move_legal(Board,P1,P2,_,b),Moves).

非常感谢您的帮助。

谢谢!

标签: prologprolog-findall

解决方案


推荐阅读