我有一个谓词list_moves(Move)
,可以为游戏提供所有可能的动作。然后我有以下谓词:
find_best_move:-
nb_setval(best,0),
list_moves(NewMove),
nb_getval(best,OldMove),
better(OldMove,NewMove).
better(OldMove, NewMove):-
NewMove > OldMove,
nb_setval(best,NewMove), !.
better(_,_).
get_best_move(Move):-
find_best_move,
nb_getval(max,Move).
当我打电话给get_best_move(Move)
时,我想只有一个动作:最好的一个。问题是:我确实得到了最好的举动,但我也有很多其他举措。
例如:
让我们说我从list_moves(Move)
按此顺序进行了以下移动(值越大,移动越好):
move1:0
move2:1
move3:2
move4:1
move5:2
move6:0
我将通过致电get_best_move(Move)
得到以下结果:
move1
MOVE2
MOVE3
MOVE3
MOVE3
MOVE3
事情是:我只想获得move3一次。我不在乎移动1-2,也不关心其他3个移动3。
我认为一个解决方案可能是等待"直到find_best_move
中的get_best_move
来电完成,而不是nb_getval
给出的每个答案find_best_move
。
我该怎么做?还有其他解决方案吗?
答案 0 :(得分:0)
是的,当然,有一个解决方案。您将获得一个结果列表,因此您需要按特定谓词对其进行过滤,或者只是采用最后一个,因为您按递增顺序对它们进行排序。
Prolog逐一生成这些解决方案。有时我们想要查询所有解决方案,我们希望它们以一种整洁,可用的形式交给我们。 Prolog有三个内置谓词:findall
,bagof
和setof
。我们首先需要列出所有内容
?- findall(X,get_best_move(Move))
应返回列表[move1, move2, move3, move3, move3, move3]
,然后使用最后一个函数
%% last(?List, ?Last)
%
% Succeeds when Last is the last element of List. This
% predicate is =semidet= if List is a list and =multi= if List is
% a partial list.
%
% @compat There is no de-facto standard for the argument order of
% last/2. Be careful when porting code or use
% append(_, [Last], List) as a portable alternative.
last([X|Xs], Last) :-
last_(Xs, X, Last).
last_([], Last, Last).
last_([X|Xs], _, Last) :-
last_(Xs, X, Last).
类似的东西
?- last(findall(X,get_best_move(Move)), Y)
我不知道你使用哪种实现,但这可能会有所帮助