prolog中的深度限制alpha-beta

prolog中的深度限制alpha-beta,prolog,chess,minimax,alpha-beta-pruning,Prolog,Chess,Minimax,Alpha Beta Pruning,我正在用Prolog构建一个国际象棋引擎。 “人工智能prolog编程”的alpha-beta版没有深度限制。 由于无法在国际象棋中搜索整棵树,我试图将书中的代码修改为深度限制,但它不能正常工作 以下是图书代码: alphabeta(Pos, Alpha, Beta, GoodPos, Val) :- moves(Pos, PosList), !, boundedbest( PosList, Alpha, Beta, GoodPos, Val) ; get_pos_value

我正在用Prolog构建一个国际象棋引擎。 “人工智能prolog编程”的alpha-beta版没有深度限制。 由于无法在国际象棋中搜索整棵树,我试图将书中的代码修改为深度限制,但它不能正常工作

以下是图书代码:

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、GoodPos、Val):-
移动(位置、位置列表)!,
boundedbest(PosList、Alpha、Beta、GoodPos、Val)
;
获取位置值(位置,值)。%Pos的静态值
boundedbest([Pos | PosList]、Alpha、Beta、GoodPos、GoodVal):-
阿尔法贝塔(位置、阿尔法、贝塔、瓦尔),
足够好(PosList,Alpha,Beta,Pos,Val,GoodPos,GoodVal)。
足够好了([],,,Pos,Val,Pos,Val):-!%没有其他候选人
足够好了(u,Alpha,Beta,Pos,Val,Pos,Val):-
最小移动(Pos),Val>Beta,!;%最大化子上界
最大移动量(位置),ValAlpha,!.%马西咪嗪增加了下限
新边界(Alpha、Beta、Pos、Val、Alpha、Val):-
最大移动量(位置),ValVal1!;
最大移动(位置),Val
我试图将其修改为深度受限的方式有:

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
alphabeta(Pos,Alpha,Beta,Pos,Val,0):-%接收到的最大搜索深度
获取位置值(位置,值)。%Pos的静态值
阿尔法贝塔(位置、阿尔法、贝塔、好位置、Val、深度):-
深度>0,
移动(位置、位置列表)!,
boundedbest(PosList、Alpha、Beta、GoodPos、Val、Depth)。
阿尔法贝塔(位置、阿尔法、贝塔、位置、Val、深度):-
深度>0,
获取位置值(位置,值)。
boundedbest([Pos | PosList]、Alpha、Beta、GoodPos、GoodVal、Depth):-
深度是深度-1,
阿尔法贝塔(位置、阿尔法、贝塔、u、瓦尔、深度1),
足够好(PosList,Alpha,Beta,Pos,Val,GoodPos,GoodVal)。
足够好了([],,,Pos,Val,Pos,Val):-!%没有其他候选人
足够好了(u,Alpha,Beta,Pos,Val,Pos,Val):-
最小移动(Pos),Val>Beta,!;%最大化子上界
最大移动量(位置),ValAlpha,!.%马西咪嗪增加了下限
新边界(Alpha、Beta、Pos、Val、Alpha、Val):-
最大移动量(位置),ValVal1!;
最大移动(位置),Val

如果有任何帮助,我将不胜感激。

您的代码有误。更重要的是,SWI Prolog发现并为您诊断的代码中有一个输入错误。不要忽略它的警告

看:

具体而言,在第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,
这应该在左侧使用
Depth1

甚至尝试测试具有单例警告的代码都是错误的,因为单例警告通常表示存在非常严重的错误。这里就是这样。当您看到单例警告时,您应该做的第一件事就是理解并修复它——与程序的任何其他交互可能都是毫无意义的

诚然,其中一些警告是“良性的”:第一行中针对该子句的警告似乎并不表示该子句中存在错误。也许你已经看到了其中的一些警告,并认为它们是无害的。情况恰恰相反:接受这种“虚假”的单例警告意味着你有可能冒着严重警告溜进来的风险


(我没有测试修改过的程序,因为它不完整是可以理解的。)

您的代码中有一个输入错误。更重要的是,SWI Prolog发现并为您诊断的代码中有一个输入错误。不要忽略它的警告

看:

具体而言,在第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,
这应该在左侧使用
Depth1

甚至尝试测试具有单例警告的代码都是错误的,因为单例警告通常表示存在非常严重的错误。这里就是这样。当您看到单例警告时,您应该做的第一件事就是理解并修复它——与程序的任何其他交互可能都是毫无意义的

诚然,其中一些警告是“善意的”:第一行中针对该条款的警告似乎并不正确