如何解决我怎样才能返回 alpha-beta 算法的下一步?
我正在实现一个人工智能来玩井字游戏,我正在使用 alpha-beta 算法来搜索最佳移动。下面是我到目前为止的代码。我设法使算法起作用——状态的值似乎是正确的,但我无法返回正确的下一步/棋盘。
当我执行目标 Board = ['-','-','o','-'],alpha_beta(max,Board,V,NB).
时,这是输出:
?- Board = ['-',NB).
Board = [-,-,o,-],V = 0,NB = [-,x].
值 V
是正确的(它表示比赛的结果将是平局),但 NB,代表 'x' 玩家的下一步行动,不是。强>
测试,我击败了 AI,这不应该发生什么。在图像中,我多次执行目标,模拟 Tic Tac Toe 比赛。 AI 播放“x”符号。关于输出:第一个棋盘是当前棋盘,作为输入提供的棋盘,第二个棋盘是NextBoard
,AI 做出的移动:
我尝试了一些东西。我尝试使用 guitracer
,我尝试阅读其他实现,但找不到适合我的实现的解决方案。谁能告诉我我做错了什么?
alpha_beta(max,Value,NextBoard):-
ab_minimax(max,-inf,inf,NextBoard).
ab_minimax(max,_,-1,NextBoard):-
is_winning_state_o(Board),!.
ab_minimax(min,1,NextBoard):-
is_winning_state_x(Board),!.
ab_minimax(_,NextBoard):-
is_a_draw(Board),!.
ab_minimax(max,Alfa,Beta,NextBoard):-
children(Board,max,Children),ab_max_children(Children,NB,NextBoard).
ab_minimax(min,min,ab_min_children(Children,NextBoard).
ab_max_children([],Max,NextBoard,NextBoard).
ab_max_children([H|T],Max1,NextBoard):-
ab_minimax(min,H,NextBoardX),(
Value > Beta -> % Beta cut
Max = Beta,NextBoard = H
; (
max(Value,Alfa1),% updates Alpha
max(Value,Max2),(Max2 == Value -> NB1 = H; NB1 = NB),ab_max_children(T,Alfa1,Max2,NB1,NextBoard)
)
).
ab_min_children([],Min,NextBoard).
ab_min_children([H|T],Min1,(
Alfa > Value -> % Alpha cut
Min = Alfa,NextBoard = H
; (
min(Value,Beta1),% updates Beta
min(Value,Min2),(Min2 == Value -> NB1 = H; NB1 = NB),ab_min_children(T,Beta1,Min2,NextBoard)
)
).
is_winning_state_x(S) :-
winning_state_x(S),!.
winning_state_x(['x','x',_]). % [1,2,3]
winning_state_x([_,_]). % [4,5,6]
winning_state_x([_,'x']). % [7,8,9]
winning_state_x(['x',4,7]
winning_state_x([_,_]). % [2,8]
winning_state_x([_,'x']). % [3,6,'x']). % [1,9]
winning_state_x([_,_]). % [3,7]
is_winning_state_o(S) :-
winning_state_o(S),!.
winning_state_o(['o',3]
winning_state_o([_,6]
winning_state_o([_,'o']). % [7,9]
winning_state_o(['o',7]
winning_state_o([_,8]
winning_state_o([_,'o']). % [3,'o']). % [1,9]
winning_state_o([_,7]
has_empty_position(['-'|_]) :- !.
has_empty_position([_|T]) :- has_empty_position(T).
is_a_draw(S) :-
not(has_empty_position(S)).
children(Board,Player,Children) :-
findall(NewBoard,make_move(Player,NewBoard),Children).
make_move(max,['-'|T],['x'|T]).
make_move(min,['o'|T]).
make_move(Player,[H|T1],[H|T2]) :- make_move(Player,T1,T2).
解决方法
问题是,下一步的“正确”移动是什么,因为通常有多个最佳移动。
您正在做的是评估您董事会的孩子。上表显示了每个孩子的价值、当前的 Alpha 和当前的 Beta:
[[x,-,o,-],-inf,inf]
[[-,x,x],inf]
既然所有的孩子都有相同的价值,那么下一个板当然是最后一个孩子。
有两个问题:
-
您以这样一种方式实施它,即对于每个 Board,您最多有一个 Nextboard,而可能有多个最佳 Nextboard。
-
我认为您对孩子的评价是错误的。当我运行良好的旧极小极大时,我得到:
[x,-] 0
[-,-] -1
[-,-] 0
[-,x] -1
Alpha-beta 剪枝不应该只考虑某些替代方案,从而加快搜索速度,但产生相同的结果吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。