MiniMax TicTacToe 不起作用 (c)
MiniMax TicTacToe doesn't work (c)
我已经用 MiniMax 实现了 TicTacToe 算法,但问题是计算机总是只是将 'x' 放在下一个可能的位置而不是评估游戏。有人知道为什么吗? (问题只能出在 MiniMax 函数,或者 nextMove 函数。)
非常感谢!
这是代码:
int MiniMax(struct Game g, enum Symbol pl){
int score;
if (pl==CROSS)
{
score = -98765;
}
else score = 98765;
int temp_cross =0;
int temp_circle =0;
//base case
if (game_over(g) == CROSS)
return 10;
else if (game_over(g) == CIRCLE)
return -10;
else if (game_over(g) == FULL)
return 0;
int x,y;
for (y=0; y<SIZE_Y_AXIS; y++)
{
for (x=0; x<SIZE_X_AXIS; x++)
{
if (g.board.fields[x][y] == NONE)
{
if (pl == CROSS)
g.board.fields[x][y] = CROSS;
else g.board.fields[x][y] = CIRCLE;
if (pl == CROSS)
temp_cross= MiniMax(g, CIRCLE);
else temp_circle = MiniMax(g, CROSS);
g.board.fields[x][y] = NONE;
if ((pl == CROSS) && (temp_cross > score))
score = temp_cross;
else if ((pl == CIRCLE) && (temp_circle < score))
score = temp_circle;
}
}
}
return score;
};
int nextMove(struct Game g, enum Symbol player){
int score_cross = -865435;
int score_cross_temp = 0;
int cross_position = 1;
int score_circle = 876545;
int score_circle_temp = 0;
int circle_position = 1;
int x,y;
for (y=0; y<SIZE_Y_AXIS; y++)
{
for (x=0; x<SIZE_X_AXIS; x++)
{
if (g.board.fields[x][y] == NONE)
{
if (player == CROSS)
{
score_cross_temp = MiniMax(g, CROSS);
printf("%d ",MiniMax(g, CROSS));
if (score_cross_temp > score_cross)
{
score_cross = score_cross_temp;
cross_position = (y)*3 + x+1;
}
}
else if (player == CIRCLE)
{
score_circle_temp = MiniMax(g, CIRCLE);
if (score_cross_temp < score_circle)
{
score_circle = score_circle_temp;
circle_position = (y)*3 + x+1;
}
}
}
}
}
if (player == CROSS)
{
//printf("%d",cross_position);
return cross_position;
}
else
{
//printf("%d",circle_position);
return circle_position;
}
};
我认为您的代码中存在错误。您将分数初始化为 10,并将临时变量初始化为任意高低数字。这是落后的。 TempCircle 和 TempCross 无论如何都会被覆盖,我调用了 minimax。 score 变量必须这样设置。替换
int score = 10;
int temp_cross = -9876543;
int temp_circle = 9876543;
和
int score;
if(pl==cross){
score = 9876543
}
else{
score = -9876543
}
int temp_cross;
int temp_circle;
您的 nextMove 函数中似乎还有另一个错误。我假设它的目的是遍历所有可能的动作,找到具有最高 minimax 值的动作,以及 return 那个动作(如果我错了请纠正我)。这不是函数的作用。它遍历所有动作,但不执行任何动作。 x 和 y 从未被使用过,除了更新移动。您实际上是在多次调用同一个 minimax。相反,我要么完全摆脱这个函数,因为在 minimax 函数中有一种方法可以做到这一点,要么修复这个函数。要修复该功能,我会将其更改为:
int nextMove(struct Game g, enum Symbol player){
int score_cross = -865435;
int score_cross_temp = 0;
int cross_position = 1;
int score_circle = 876545;
int score_circle_temp = 0;
int circle_position = 1;
int x,y;
for (y=0; y<SIZE_Y_AXIS; y++)
{
for (x=0; x<SIZE_X_AXIS; x++)
{
if (g.board.fields[x][y] == NONE)
{
if (player == CROSS)
{
g.board.fields[x][y] = CROSS;
score_cross_temp = MiniMax(g, CIRCLE);
printf("%d ",MiniMax(g, CROSS));
g.board.fields[x][y] = NONE;
if (score_cross_temp > score_cross)
{
score_cross = score_cross_temp;
cross_position = (y)*3 + x+1;
}
}
else if (player == CIRCLE)
{
g.board.fields[x][y] = CIRCLE;
score_circle_temp = MiniMax(g, CROSS);
g.board.fields[x][y] = NONE;
if (score_cross_temp < score_circle)
{
score_circle = score_circle_temp;
circle_position = (y)*3 + x+1;
}
}
}
}
}
if (player == CROSS)
{
//printf("%d",cross_position);
return cross_position;
}
else
{
//printf("%d",circle_position);
return circle_position;
}
};
或者您可以编辑 minimax 以跟踪对函数的调用。如果它是第一个递归调用(根),请跟踪移动本身及其值。然后return移动。
我已经用 MiniMax 实现了 TicTacToe 算法,但问题是计算机总是只是将 'x' 放在下一个可能的位置而不是评估游戏。有人知道为什么吗? (问题只能出在 MiniMax 函数,或者 nextMove 函数。) 非常感谢! 这是代码:
int MiniMax(struct Game g, enum Symbol pl){
int score;
if (pl==CROSS)
{
score = -98765;
}
else score = 98765;
int temp_cross =0;
int temp_circle =0;
//base case
if (game_over(g) == CROSS)
return 10;
else if (game_over(g) == CIRCLE)
return -10;
else if (game_over(g) == FULL)
return 0;
int x,y;
for (y=0; y<SIZE_Y_AXIS; y++)
{
for (x=0; x<SIZE_X_AXIS; x++)
{
if (g.board.fields[x][y] == NONE)
{
if (pl == CROSS)
g.board.fields[x][y] = CROSS;
else g.board.fields[x][y] = CIRCLE;
if (pl == CROSS)
temp_cross= MiniMax(g, CIRCLE);
else temp_circle = MiniMax(g, CROSS);
g.board.fields[x][y] = NONE;
if ((pl == CROSS) && (temp_cross > score))
score = temp_cross;
else if ((pl == CIRCLE) && (temp_circle < score))
score = temp_circle;
}
}
}
return score;
};
int nextMove(struct Game g, enum Symbol player){
int score_cross = -865435;
int score_cross_temp = 0;
int cross_position = 1;
int score_circle = 876545;
int score_circle_temp = 0;
int circle_position = 1;
int x,y;
for (y=0; y<SIZE_Y_AXIS; y++)
{
for (x=0; x<SIZE_X_AXIS; x++)
{
if (g.board.fields[x][y] == NONE)
{
if (player == CROSS)
{
score_cross_temp = MiniMax(g, CROSS);
printf("%d ",MiniMax(g, CROSS));
if (score_cross_temp > score_cross)
{
score_cross = score_cross_temp;
cross_position = (y)*3 + x+1;
}
}
else if (player == CIRCLE)
{
score_circle_temp = MiniMax(g, CIRCLE);
if (score_cross_temp < score_circle)
{
score_circle = score_circle_temp;
circle_position = (y)*3 + x+1;
}
}
}
}
}
if (player == CROSS)
{
//printf("%d",cross_position);
return cross_position;
}
else
{
//printf("%d",circle_position);
return circle_position;
}
};
我认为您的代码中存在错误。您将分数初始化为 10,并将临时变量初始化为任意高低数字。这是落后的。 TempCircle 和 TempCross 无论如何都会被覆盖,我调用了 minimax。 score 变量必须这样设置。替换
int score = 10;
int temp_cross = -9876543;
int temp_circle = 9876543;
和
int score;
if(pl==cross){
score = 9876543
}
else{
score = -9876543
}
int temp_cross;
int temp_circle;
您的 nextMove 函数中似乎还有另一个错误。我假设它的目的是遍历所有可能的动作,找到具有最高 minimax 值的动作,以及 return 那个动作(如果我错了请纠正我)。这不是函数的作用。它遍历所有动作,但不执行任何动作。 x 和 y 从未被使用过,除了更新移动。您实际上是在多次调用同一个 minimax。相反,我要么完全摆脱这个函数,因为在 minimax 函数中有一种方法可以做到这一点,要么修复这个函数。要修复该功能,我会将其更改为:
int nextMove(struct Game g, enum Symbol player){
int score_cross = -865435;
int score_cross_temp = 0;
int cross_position = 1;
int score_circle = 876545;
int score_circle_temp = 0;
int circle_position = 1;
int x,y;
for (y=0; y<SIZE_Y_AXIS; y++)
{
for (x=0; x<SIZE_X_AXIS; x++)
{
if (g.board.fields[x][y] == NONE)
{
if (player == CROSS)
{
g.board.fields[x][y] = CROSS;
score_cross_temp = MiniMax(g, CIRCLE);
printf("%d ",MiniMax(g, CROSS));
g.board.fields[x][y] = NONE;
if (score_cross_temp > score_cross)
{
score_cross = score_cross_temp;
cross_position = (y)*3 + x+1;
}
}
else if (player == CIRCLE)
{
g.board.fields[x][y] = CIRCLE;
score_circle_temp = MiniMax(g, CROSS);
g.board.fields[x][y] = NONE;
if (score_cross_temp < score_circle)
{
score_circle = score_circle_temp;
circle_position = (y)*3 + x+1;
}
}
}
}
}
if (player == CROSS)
{
//printf("%d",cross_position);
return cross_position;
}
else
{
//printf("%d",circle_position);
return circle_position;
}
};
或者您可以编辑 minimax 以跟踪对函数的调用。如果它是第一个递归调用(根),请跟踪移动本身及其值。然后return移动。