我实现的这个极小化极大算法是否正确?

这是用于跳棋游戏的。查看修订历史以获取代码的旧版本。

    private static Move GetBestMove(Color color, Board board, int depth)    {        var bestMoves = new List<Move>();        var validMoves = board.GetValidMoves(color);        int highestScore = int.MinValue;        Board boardAfterMove;        int tmpScore;        var rand = new Random();        Debug.WriteLine("{0}'s Moves:", color);        foreach (var move in validMoves)        {            boardAfterMove = board.Clone().ApplyMove(move);            if(move.IsJump && !move.IsCrowned && boardAfterMove.GetJumps(color).Any())                tmpScore = NegaMax(color, boardAfterMove, depth);            else                tmpScore = -NegaMax(Board.Opposite(color), boardAfterMove, depth);            Debug.WriteLine("{0}: {1}", move, tmpScore);            if (tmpScore > highestScore)            {                bestMoves.Clear();                bestMoves.Add(move);                highestScore = tmpScore;            }            else if (tmpScore == highestScore)            {                bestMoves.Add(move);            }        }        return bestMoves[rand.Next(bestMoves.Count)];    }    private static int NegaMax(Color color, Board board, int depth)    {        var validMoves = board.GetValidMoves(color);        int highestScore = int.MinValue;        Board boardAfterMove;        if (depth <= 0 || !validMoves.Any())            return BoardScore(color, board);        foreach (var move in validMoves)        {            boardAfterMove = board.Clone().ApplyMove(move);            if(move.IsJump && !move.IsCrowned && boardAfterMove.GetJumps(color).Any())                highestScore = Math.Max(highestScore, NegaMax(color, boardAfterMove, depth));            else                highestScore = Math.Max(highestScore, -NegaMax(Board.Opposite(color), boardAfterMove, depth - 1));        }        return highestScore;    }    private static int BoardScore(Color color, Board board)    {        if (!board.GetValidMoves(color).Any()) return -1000;        return board.OfType<Checker>().Sum(c => (c.Color == color ? 1 : -1) * (c.Class == Class.Man ? 2 : 3));    }

我尝试使用深度 0,在游戏进行到大约一半时,分数是正确的,然后突然开始出错。其中一个玩家会开始声称他的分数比实际高。为什么它只在游戏进行到一半时才有效?!


回答:

找到bug了: 是什么导致它一段时间后开始计算错误?

新代码:

private static Move GetBestMove(Color color, Board board, int depth){    var bestMoves = new List<Move>();    IEnumerable<Move> validMoves = board.GetValidMoves(color);    int highestScore = int.MinValue;    Board boardAfterMove;    int tmpScore;    var rand = new Random();    Debug.WriteLine("{0}'s Moves:", color);    foreach (Move move in validMoves)    {        boardAfterMove = board.Clone().ApplyMove(move);        if (move.IsJump && !move.IsCrowned && boardAfterMove.GetJumps(color).Any())            tmpScore = NegaMax(color, boardAfterMove, depth);        else            tmpScore = -NegaMax(Board.Opposite(color), boardAfterMove, depth);        Debug.WriteLine("{0}: {1}", move, tmpScore);        if (tmpScore > highestScore)        {            bestMoves.Clear();            bestMoves.Add(move);            highestScore = tmpScore;        }        else if (tmpScore == highestScore)        {            bestMoves.Add(move);        }    }    return bestMoves[rand.Next(bestMoves.Count)];}private static int NegaMax(Color color, Board board, int depth){    IEnumerable<Move> validMoves = board.GetValidMoves(color);    int highestScore = int.MinValue;    Board boardAfterMove;    if (depth <= 0 || !validMoves.Any())        return BoardScore(color, board);    foreach (Move move in validMoves)    {        boardAfterMove = board.Clone().ApplyMove(move);        if (move.IsJump && !move.IsCrowned && boardAfterMove.GetJumps(color).Any())            highestScore = Math.Max(highestScore, NegaMax(color, boardAfterMove, depth));        else            highestScore = Math.Max(highestScore, -NegaMax(Board.Opposite(color), boardAfterMove, depth - 1));    }    return highestScore;}private static int BoardScore(Color color, Board board){    if (!board.GetValidMoves(color).Any()) return -1000;    return board.OfType<Checker>().Sum(c => (c.Color == color ? 1 : -1) * (c.Class == Class.Man ? 2 : 3));}

我不能 100% 确定它能完美运行。它似乎在深度 0 时有效,并且通常在深度 1 时也有效……除此之外,我不知道计算机在想什么。看起来仍然不够智能。

编辑: 运行这个并以最大速度… NegaMax 代理对抗随机代理。 NegaMax 总是赢。 观察出现“1000”的分数。 他总是在那之后几回合内获胜,所以它似乎最终可以工作了!

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

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