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

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

    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

使用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中创建了一个多类分类项目。该项目可以对…

发表回复

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