C# Minimax 进程因 stackoverflowexception 而终止
C# Minimax process terminated due to stackoverflowexception
我一直在尝试用 C# 创建一个具有 minimax 功能的井字游戏。不幸的是,我 运行 遇到了让 minimax 函数正常工作的问题。
static double MiniMax(char[] gameState, int depth)
{
int bestMove = 0;
double bestScore = -double.PositiveInfinity;
if (maxDepth > 0)
{
for (int i = 0; i < 9; i++)
{
if (ValidMove(i, gameState))
{
char[] clone = new char[board.Length];
board.CopyTo(clone, 0);
clone[i] = 'X';
double score = 0;
score += MinPlay(clone, maxDepth--);
if (score > bestScore)
{
bestMove = i;
bestScore = score;
}
}
}
}
return bestMove;
}
static double MinPlay(char[] gameState, int depth)
{
if (Win(gameState)) return -1;
if (Draw(gameState)) return 0;
double bestScore = double.PositiveInfinity;
if (maxDepth > 0)
{
for (int i = 0; i < 9; i++)
{
if (ValidMove(i, gameState))
{
char[] clone = new char[board.Length];
board.CopyTo(clone, 0);
clone[i] = 'O';
double score = 0;
score += MaxPlay(clone, maxDepth--);
if (score > bestScore)
{
bestScore = score;
}
}
}
}
return bestScore;
}
static double MaxPlay(char[] gameState, int depth)
{
if (Win(gameState)) return 1;
if (Draw(gameState)) return 0;
double bestScore = -double.PositiveInfinity;
if (maxDepth > 0)
{
for (int i = 0; i < 9; i++)
{
if (ValidMove(i, gameState))
{
char[] clone = new char[board.Length];
board.CopyTo(clone, 0);
clone[i] = 'X';
double score = 0;
score += MinPlay(clone, maxDepth--);
if (score > bestScore)
{
bestScore = score;
}
}
}
}
return bestScore;
}
我使用此处的指南制作了这些功能:http://giocc.com/concise-implementation-of-minimax-through-higher-order-functions.html
当 运行 程序一切正常,直到轮到计算机。我收到错误 "Process is terminated due to WhosebugException"。
我认为这是由无限递归引起的,但是在浏览了一段时间的程序后,我不知道是什么原因造成的。
我已经编辑了代码,现在有一个深度并且 minplay 和 maxplay 循环中有一个 validmove 检查。计算机现在开始移动,但出于某种原因它只选择了第一个位置。如果玩家选择第一个位置作为他们的第一步,那么计算机会选择它旁边的位置,并且在下一轮它会覆盖第一个位置上的玩家。然后计算机停止移动。我不知道为什么会这样。
如有任何帮助,我们将不胜感激!
这是因为 MaxPlay
调用了函数 MinPlay
,而函数 MinPlay
又调用了函数 MaxPlay
,而您在每次连续调用后都没有做任何改变游戏状态的事情调用使递归结束。您只是在 'o' 和 'x' 之间切换 clone[0],您的函数永远不会完成 for 循环的迭代。
将 MinPlay 和 MaxPlay 中的 for 循环更改为仅考虑空方块。看起来您也没有使用传入的 gameState。我不知道 board 在哪里定义。
for (int i = 0; i < 9; i++)
{
if (ValidMove(i, gameState) {
char[] clone = new char[gameState.Length];
gameState.CopyTo(clone, 0);
clone[i] = 'X';
double score = MinPlay(clone);
if (score > bestScore)
{
bestScore = score;
}
}
}
return bestScore;
编辑:
您将其更改为 score +=,这是不正确的。
另外,您在 MinPlay 中的分数比较不正确。
if (score < bestScore)
{
bestScore = score;
}
我一直在尝试用 C# 创建一个具有 minimax 功能的井字游戏。不幸的是,我 运行 遇到了让 minimax 函数正常工作的问题。
static double MiniMax(char[] gameState, int depth)
{
int bestMove = 0;
double bestScore = -double.PositiveInfinity;
if (maxDepth > 0)
{
for (int i = 0; i < 9; i++)
{
if (ValidMove(i, gameState))
{
char[] clone = new char[board.Length];
board.CopyTo(clone, 0);
clone[i] = 'X';
double score = 0;
score += MinPlay(clone, maxDepth--);
if (score > bestScore)
{
bestMove = i;
bestScore = score;
}
}
}
}
return bestMove;
}
static double MinPlay(char[] gameState, int depth)
{
if (Win(gameState)) return -1;
if (Draw(gameState)) return 0;
double bestScore = double.PositiveInfinity;
if (maxDepth > 0)
{
for (int i = 0; i < 9; i++)
{
if (ValidMove(i, gameState))
{
char[] clone = new char[board.Length];
board.CopyTo(clone, 0);
clone[i] = 'O';
double score = 0;
score += MaxPlay(clone, maxDepth--);
if (score > bestScore)
{
bestScore = score;
}
}
}
}
return bestScore;
}
static double MaxPlay(char[] gameState, int depth)
{
if (Win(gameState)) return 1;
if (Draw(gameState)) return 0;
double bestScore = -double.PositiveInfinity;
if (maxDepth > 0)
{
for (int i = 0; i < 9; i++)
{
if (ValidMove(i, gameState))
{
char[] clone = new char[board.Length];
board.CopyTo(clone, 0);
clone[i] = 'X';
double score = 0;
score += MinPlay(clone, maxDepth--);
if (score > bestScore)
{
bestScore = score;
}
}
}
}
return bestScore;
}
我使用此处的指南制作了这些功能:http://giocc.com/concise-implementation-of-minimax-through-higher-order-functions.html
当 运行 程序一切正常,直到轮到计算机。我收到错误 "Process is terminated due to WhosebugException"。 我认为这是由无限递归引起的,但是在浏览了一段时间的程序后,我不知道是什么原因造成的。
我已经编辑了代码,现在有一个深度并且 minplay 和 maxplay 循环中有一个 validmove 检查。计算机现在开始移动,但出于某种原因它只选择了第一个位置。如果玩家选择第一个位置作为他们的第一步,那么计算机会选择它旁边的位置,并且在下一轮它会覆盖第一个位置上的玩家。然后计算机停止移动。我不知道为什么会这样。
如有任何帮助,我们将不胜感激!
这是因为 MaxPlay
调用了函数 MinPlay
,而函数 MinPlay
又调用了函数 MaxPlay
,而您在每次连续调用后都没有做任何改变游戏状态的事情调用使递归结束。您只是在 'o' 和 'x' 之间切换 clone[0],您的函数永远不会完成 for 循环的迭代。
将 MinPlay 和 MaxPlay 中的 for 循环更改为仅考虑空方块。看起来您也没有使用传入的 gameState。我不知道 board 在哪里定义。
for (int i = 0; i < 9; i++)
{
if (ValidMove(i, gameState) {
char[] clone = new char[gameState.Length];
gameState.CopyTo(clone, 0);
clone[i] = 'X';
double score = MinPlay(clone);
if (score > bestScore)
{
bestScore = score;
}
}
}
return bestScore;
编辑:
您将其更改为 score +=,这是不正确的。 另外,您在 MinPlay 中的分数比较不正确。
if (score < bestScore)
{
bestScore = score;
}