我正在Prolog中构建一个国际象棋引擎。来自";人工智能的prolog程序;不受深度限制。由于在国际象棋中不可能搜索整棵树,我试图修改书中的代码以限制深度,但它不能正常工作。
这是书的代码:
alphabeta(Pos, Alpha, Beta, GoodPos, Val) :-
moves(Pos, PosList), !,
boundedbest( PosList, Alpha, Beta, GoodPos, Val)
;
get_pos_value(Pos,Val). % static value of Pos
boundedbest([Pos | PosList], Alpha, Beta, GoodPos, GoodVal) :-
alphabeta( Pos, Alpha, Beta, _, Val),
goodenough(PosList, Alpha, Beta, Pos, Val, GoodPos, GoodVal).
goodenough([],_,_,Pos, Val, Pos, Val) :- !. % no other candidate
goodenough(_, Alpha, Beta, Pos, Val, Pos, Val) :-
min_to_move(Pos), Val > Beta, !; % Maximizer attained upper bound
max_to_move(Pos), Val < Alpha, !. % Minimizer attained lower bound
goodenough( PosList, Alpha, Beta, Pos, Val, GoodPos, GoodVal) :-
newbounds( Alpha, Beta, Pos, Val, NewAlpha, NewBeta), % Refine bounds
boundedbest(PosList, NewAlpha, NewBeta, Pos1, Val1),
betterof( Pos, Val, Pos1, Val1, GoodPos, GoodVal).
newbounds(Alpha, Beta, Pos, Val, Val, Beta) :-
min_to_move(Pos), Val > Alpha, !. % Mazximizer increased lower bound
newbounds(Alpha, Beta, Pos, Val, Alpha, Val):-
max_to_move(Pos), Val < Beta, !. % Minimizer decreased upper bound
newbounds( Alpha, Beta, _,_,Alpha, Beta). % otherwise bounds unchanged.
betterof(Pos, Val, Pos1, Val1, Pos, Val) :- % Pos better than Pos1
min_to_move(Pos), Val > Val1, !;
max_to_move(Pos), Val < Val1, !.
betterof(_,_,Pos1,Val1,Pos1,Val1). % otherwise Pos 1 better
我试图将其修改为深度受限:
alphabeta(Pos, Alpha, Beta, Pos, Val, 0) :- % max depth of search recieved
get_pos_value(Pos,Val). % static value of Pos
alphabeta(Pos, Alpha, Beta, GoodPos, Val, Depth) :-
Depth > 0,
moves(Pos, PosList), !,
boundedbest( PosList, Alpha, Beta, GoodPos, Val,Depth).
alphabeta(Pos, Alpha, Beta, Pos, Val, Depth) :-
Depth > 0,
get_pos_value(Pos,Val).
boundedbest([Pos | PosList], Alpha, Beta, GoodPos, GoodVal,Depth) :-
Depth is Depth - 1,
alphabeta( Pos, Alpha, Beta, _, Val,Depth1),
goodenough(PosList, Alpha, Beta, Pos, Val, GoodPos, GoodVal).
goodenough([],_,_,Pos, Val, Pos, Val) :- !. % no other candidate
goodenough(_, Alpha, Beta, Pos, Val, Pos, Val) :-
min_to_move(Pos), Val > Beta, !; % Maximizer attained upper bound
max_to_move(Pos), Val < Alpha, !. % Minimizer attained lower bound
goodenough( PosList, Alpha, Beta, Pos, Val, GoodPos, GoodVal) :-
newbounds( Alpha, Beta, Pos, Val, NewAlpha, NewBeta), % Refine bounds
boundedbest(PosList, NewAlpha, NewBeta, Pos1, Val1,_),
betterof( Pos, Val, Pos1, Val1, GoodPos, GoodVal).
newbounds(Alpha, Beta, Pos, Val, Val, Beta) :-
min_to_move(Pos), Val > Alpha, !. % Mazximizer increased lower bound
newbounds(Alpha, Beta, Pos, Val, Alpha, Val):-
max_to_move(Pos), Val < Beta, !. % Minimizer decreased upper bound
newbounds( Alpha, Beta, _,_,Alpha, Beta). % otherwise bounds unchanged.
betterof(Pos, Val, Pos1, Val1, Pos, Val) :- % Pos better than Pos1
min_to_move(Pos), Val > Val1, !;
max_to_move(Pos), Val < Val1, !.
betterof(_,_,Pos1,Val1,Pos1,Val1). % otherwise Pos 1 better
如果有任何帮助,我将不胜感激。
您的代码中有一个拼写错误。更重要的是,您的代码中存在SWI-Prolog为您发现并诊断的拼写错误不要忽视它的警告。
外观:
Warning: /home/isabelle/chess.pl:1:
Singleton variables: [Alpha,Beta]
Warning: /home/isabelle/chess.pl:11:
Singleton variables: [Alpha,Beta]
Warning: /home/isabelle/chess.pl:16:
Singleton variables: [Depth1]
Warning: /home/isabelle/chess.pl:40:
Singleton variables: [Pos1]
具体而言,在第16行开始的本条款中:
boundedbest([Pos | PosList], Alpha, Beta, GoodPos, GoodVal,Depth) :-
Depth is Depth - 1,
alphabeta( Pos, Alpha, Beta, _, Val,Depth1),
goodenough(PosList, Alpha, Beta, Pos, Val, GoodPos, GoodVal).
您对Depth1
的使用表明,您似乎理解了需要计算一个新值并将其传递到递归中。但是你忘了在前一行使用这个变量:
Depth is Depth - 1,
这应当在左手侧使用CCD_ 2。
甚至尝试测试带有单例警告的代码都是错误的,因为单例警告通常表明存在非常严重的错误。这里就是这样。当您看到一个singleton警告时,您应该做的第一件事就是理解并修复它——与程序的任何其他交互都可能毫无意义。
的确,这些警告中的一些是"错误的";良性":第一行中对该子句的警告似乎并不表示该子句中存在错误。也许你已经看到了其中的一些警告,并认为它们是无害的。恰恰相反的情况是:接受这样的";虚假的";singleton警告意味着您有可能出现严重警告。
(我还没有测试正确的程序,因为它不完整是可以理解的。(