同一个玩家的连续移动的Alpha-beta剪枝

我在跳棋游戏中实现了Alpha-beta剪枝算法,并以为它已经正常工作,但发现计算机在需要时并未进行连续的多次跳跃。例如:

AI 执行的操作:

O _ _ _ _      _ _ _ _ __ X _ X _  ->  _ _ _ X _  (因为只执行了一次移动而错过了跳跃)_ _ _ _ _      _ _ O _ _

AI 应该 执行的操作:

O _ _ _ _      _ _ _ _ O_ X _ X _  ->  _ _ _ _ _  (意识到当前回合未结束,继续进行)_ _ _ _ _      _ _ _ _ _

我尝试通过检查MovePiece的返回值来修复这个问题,该返回值指示玩家是否完成了回合,取决于移动是否为跳跃以及是否有进一步的跳跃可进行。根据返回值,它将再次运行MaxValue/MinValue(取决于它第一次发现有进一步移动时所处的状态),或者继续在树中前进并切换玩家。

相关代码(C#)如下(retVal是一个包含Value、Depth和要执行的Move的类型):

foreach(var m in moves){    var resultingBoard = board.Clone();    var moveResult = resultingBoard.MovePiece(m.TypeOfMove,                                resultingBoard.GetPieceAtPosition(m.OriginalPieceLocation.X,                                                                  m.OriginalPieceLocation.Y),                                m.FinalPieceLocation.X, m.FinalPieceLocation.Y);    var newDepth = currentDepth;    if(moveResult == TurnResult.NotDone)    {        retVal = MaxValue(resultingBoard, ref alphaValue, ref betaValue, color, ref newDepth, ref maxDepth);    }    else if(moveResult == TurnResult.Finished)    {        newDepth++;         retVal = MinValue(resultingBoard, ref alphaValue, ref betaValue, color == PieceColor.Black ? PieceColor.Red : PieceColor.Black, ref newDepth, ref maxDepth);    }}

然而,这导致了一些…有趣的结果(第一次移动什么也没做,只是进行了最小剪枝),尽管我认为这是正确的修改。

让MaxValue/MinValue再次调用自身并使用新移动是正确的做法吗?


回答:

你的极小极大算法需要“生成”新移动的事实闻起来不对劲(当你需要吃掉第二个棋子时)。

我建议重新设计它 – 你可以扩展movemoves可迭代对象中的一个元素),使其包含移动的元组(或列表),并在极小极大算法阶段避免使用TurnResule.NotDone

采用这种方法 – moves列表将预先扩展,以包含移动(吃棋子,吃棋子),除了单个移动之外。


这种解决方案将使算法更加健壮,并允许你轻松进行未来的修改。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注