我正在学习Prolog,我想为这个游戏做一个求解器:https://www.learn4good.com/games/puzzle/brainteasers.htm
但是,我无法使其发挥作用。我目前的代码如下:
solve(Balls):-
solve2(Balls, [[]], C),
write(C).
solve2([_],C,C). %Base case
solve2(Balls, CurrentPath,TotalPath):-
%The first two positions should contain a ball, and the third shouldnt.
member(B1,Balls),
member(B2,Balls),
\+ member(B3,Balls),
B1 is [X1,Y1],
B2 is [X2,Y2],
adjacents(B1,B2,B3),
valid(B1),
valid(B2),
valid(B3),
%Recursive call, storing the jump in the current path
solve2(Balls2, [[X1,Y1,X2,Y2]|CurrentPath],TotalPath),
%The ball list is the same except that the first two are removed, and the third one is added.
delete(Balls,[B1,B2],BallsAux),
Balls2 is [BallsAux|B3].
adjacents([X1,Y1],[X2,Y2],[X3,Y3]):- %Checks if 3 balls form a straight line
nextTo(X1,Y1,X2,Y2,D),
nextTo(X2,Y2,X3,Y3,D).
nextTo(X,Y,X,Y+1,1). %Checks if two balls are next to each other, the last parameter is the direction
nextTo(X,Y,X+1,Y+1,2).
nextTo(X,Y,X+1,Y,3).
nextTo(X,Y,X,Y-1,4).
nextTo(X,Y,X-1,Y-1,5).
nextTo(X,Y,X-1,Y,6).
valid([X,Y]):- %Checks if a ball is inside the grid
X @>= 1,
X @=< 5,
Y @>= 1,
Y @=< 5,
X @>= Y.
无论我的输入如何,解算器总会返回它无法解决的问题(基本情况除外)。任何人都对如何使这项工作有所了解?
编辑:输入/输出是这样的:
| ?- solve([[1,1],[2,1]]).
no
基本上,你用一对对象(这是地图上的球坐标)来调用该函数,程序应该写下你需要做的所有跳转以赢得游戏。如果输入只包含一个球,则输出如下:
| ?- solve([[1,1]]).
[[]]
true ?
这里的列表是空的,因为只有一个球开始,程序不需要任何跳跃来赢得比赛。
答案 0 :(得分:0)
当我运行它时,它抱怨B3是一个单例变量。根据您的评论,solve
的递归版本的前3行旨在确保列表在位置1和位置2中有一个球但不在位置3中。但它没有&#39这样做:它验证Balls有一个成员并称之为B1;它验证了Balls有一个成员并将其称为B2;它试图验证Balls没有任何成员,当然这样做,然后失败。这可以解释为什么递归子句失败。
length(Balls,3)
将验证位置1和位置2中的某些内容,但不是位置3。
另请参阅谓词nth1
以从列表中获取特定元素(或使用[]和|相应地)。
因此,我认为问题是对member
所做的事情的误解。