我已经为此工作了很长时间,以至于它不再有趣了。我正在尝试在井字游戏上实现 Minmax,虽然我已经获得了几个可以做出合理初始动作的 AI 版本,但我永远无法做出永远不会失败的版本。
我无法解决的问题之一是启发式价值。它当前在第一次 Minmax 调用时返回 -10,而它应该返回 0(无论发生什么都应该能够绘制)。
另一个问题是它运行了 400,000 次迭代,而 322,000 是最大值,考虑到早期获胜的情况,它甚至应该停止在 250,000 左右。
任何帮助将不胜感激。
int MiniMax(TGameBoard _GameBoard)
{
//Always goes for max of course, just expanded in case you wanted two AIs
int iBestMove;
int iHeuristicReturned = 0;
if (_GameBoard.ePlayer == COMPUTER)
{
iHeuristicReturned = MaxMove(_GameBoard, iBestMove);
}
else
{
iHeuristicReturned = MinMove(_GameBoard, iBestMove);
}
//cout<<"\nHeuristic is "<<iHeuristicReturned<<endl;
g_iHeuristic = iHeuristicReturned;
return iBestMove;
}
int MaxMove(TGameBoard _GameBoard, int& _iMove)
{
//Logic
//If its an end node, calculate the score
//Otherwise, do minmax until the end node, and pass back the value
//If returned value is greater than v, then pass the move back upwards
++g_iIterations;
if(_GameBoard.CheckWinner(_GameBoard) || _GameBoard.IsFull())
{
int x;
x = EvaluateStaticPosition(_GameBoard, MAX);
return EvaluateStaticPosition(_GameBoard, MAX);
}
vector<int> moveList;
GenerateMoveList(_GameBoard, moveList);
int iNumMoves = moveList.size();
int v = -10000;
for(int i = 0; i < iNumMoves; ++i)
{
int iMove = moveList[i];
_GameBoard.Set(iMove, CROSS);
int opponentsBestMove;
++g_iDepth;
int curRating = MinMove(_GameBoard, opponentsBestMove);
--g_iDepth;
if (curRating > v)
{
v = curRating;
_iMove = iMove;
}
RetractMove(&_GameBoard, iMove);
}
return v;
}
int MinMove(TGameBoard _GameBoard, int& _iMove)
{
++g_iIterations;
if (g_iIterations > 320000)
{
int x = 0;
}
if(_GameBoard.CheckWinner(_GameBoard) || _GameBoard.IsFull())
{
return EvaluateStaticPosition(_GameBoard, MIN);
}
vector<int> moveList;
GenerateMoveList(_GameBoard, moveList);
int iNumMoves = moveList.size();
int v = 10000;
for(int i = 0; i < iNumMoves; ++i)
{
int iMove = moveList[i];
_GameBoard.Set(iMove, NAUGHT);
int opponentsBestMove;
++g_iDepth;
int curRating = MaxMove(_GameBoard, opponentsBestMove);
--g_iDepth;
if (curRating < v)
{
v = curRating;
_iMove = iMove;
}
RetractMove(&_GameBoard, iMove);
}
return v;
}
int EvaluateStaticPosition(TGameBoard _GameBoard, EGoal _eGoal)
{
if(_GameBoard.CheckWinner(_GameBoard, COMPUTER))
{
return 10;
}
if(_GameBoard.CheckWinner(_GameBoard, PLAYER))
{
return -10;
}
return 0;
}
其他相关功能可以在这里检查,但我很确定它们没问题。 http://pastebin.com/eyaNfBsq
是的,我知道有一些不必要的参数 - 在我自己的版本失败后,我尝试按照互联网上的教程进行操作。不幸的是,他们给出了相同的结果。
我已经做了 12 个小时,这似乎是一个简单的任务,无法找出问题所在