同一个玩家的连续移动的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

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

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