提问者:小点点

阿尔法-贝塔为同一玩家修剪连续招式


我已经为 Checkers 实现了 alpha-beta 修剪,并认为我已经工作了,但发现计算机不会连续进行多次跳跃(当它必须时)。例如:

人工智能确实:

O _ _ _ _      _ _ _ _ _

_ X _ X _  ->  _ _ _ X _  (misses a jump because it only does a single move)

_ _ _ _ _      _ _ O _ _

人工智能应该做:

O _ _ _ _      _ _ _ _ O
_ X _ X _  ->  _ _ _ _ _  (sees that it's current turn is not finished, continues)
_ _ _ _ _      _ _ _ _ _

我试图通过检查MovePiece的返回值来修复它,该返回值返回玩家是否完成了他的回合,由移动是否是跳跃以及是否有进一步的跳跃来确定。根据返回值,它要么再次运行MaxValue/MinValue(取决于它第一次看到有进一步的移动要做时所在的位置),要么继续在树上切换玩家。

相关代码(在C#中)如下(retVal的类型包含Value、Depth和移动到做):

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用新的move再次调用自己是正确的做法吗?


共1个答案

匿名用户

事实上,你的最小最大值算法需要“生成”新的动作(当你需要吃第二块时)。

我会尝试重新设计它——你可以扩展move(可迭代的moves中的一个元素),使其包含移动的元组(或列表),并在最小最大算法阶段避免TurnResule.NotDone

使用这种方法-列表< code >移动将被预先扩展,除了单个移动之外,还包含移动< code >(吃块,吃块)。

该解决方案将使算法更加健壮,并允许您将来轻松进行修改。