Я пытался реализовать ИИ для компьютера, используя минимакс с альфа-бета-отсечкой, но столкнулся с неопределяемой ошибкой. Алгоритм должен рассчитать все возможные ходы как своего, так и другого игрока, но он не воспроизводит так, как должен.
Вот мой минимаксный код:
public int minimax(int[] board, char symbol, int alpha, int beta, int depth = 2)
{
int win = util.checkwin(board);
int nsymbol = (symbol == 'X' ? 1 : 2);
int mult = (symbol == compside ? 1 : -1);
if (win != -1)
{
if (win == nsymbol)
return mult;
else if (win != 0)
return (mult * -1);
else
return 0;
}
if (depth == 0)
return 0;
int[] newboard = new int[9];
Array.Copy(board, newboard, 9);
int score, i, pos = -1;
ArrayList emptyboard = new ArrayList();
emptyboard = util.filterboard(newboard);
for (i = 0; i < emptyboard.Count; i++)
{
if (i > 0)
newboard[(int)emptyboard[i - 1]] = 0;
newboard[(int)emptyboard[i]] = nsymbol;
score = minimax(newboard, util.changeside(symbol), alpha, beta, depth - 1);
if (mult == 1)
{
if (score > alpha)
{
alpha = score;
pos = (int)emptyboard[i];
}
if (alpha >= beta)
break;
}
else
{
if (score < beta)
beta = score;
if (alpha >= beta)
break;
}
}
if (depth == origdepth)
return pos;
if (mult == 1)
return alpha;
else
return beta;
}
Сведения о неопределенных функциях:
util.checkwin(int[] board)
= проверяет доску на предмет возможного выигрыша или ничьей за бортом или за неполную доску и возвращает победителя как 1 или 2 (игрок Х или О), 0 за ничью и -1 за неполную доску.
util.filterboard(int[] newboard)
= возвращает массив, содержащий все позиции пустых мест на данной доске.
util.changeside(char symbol)
= просто переключает X на O и O на X и возвращает результат.
Я пробовал с глубиной 2, что означает, что он рассчитает следующие 2 хода (если он выигрывает и если противник может победить). Но результаты оказались не такими, как я ожидал. и иногда он пытается играть на заполненном месте.
Вот вывод (глубина = 2):
Turn: X
| |
1 | 2 | 3
__|___|__
| |
4 | 5 | 6
__|___|__
| |
7 | 8 | 9
| |
Enter Your Choice:
Turn: O
| |
1 | 2 | 3
__|___|__
| |
X | 5 | 6
__|___|__
| |
7 | 8 | 9
| |
Enter Your Choice: 5
Turn: X
| |
1 | 2 | 3
__|___|__
| |
X | O | 6
__|___|__
| |
7 | 8 | 9
| |
Enter Your Choice:
Turn: O
| |
1 | X | 3
__|___|__
| |
X | O | 6
__|___|__
| |
7 | 8 | 9
| |
Enter Your Choice: 1
Turn: X
| |
O | X | 3
__|___|__
| |
X | O | 6
__|___|__
| |
7 | 8 | 9
| |
Enter Your Choice:
Turn: O
| |
O | X | 3
__|___|__
| |
X | O | 6
__|___|__
| |
7 | X | 9
| |
Enter Your Choice: 9
| |
O | X | 3
__|___|__
| |
X | O | 6
__|___|__
| |
7 | X | O
| |
O Wins
Но он все еще не может распознать мой выигрышный ход.
Все остальные функции были протестированы, когда пользователь играл против пользователя, и все они работают нормально. Буду признателен за помощь.
Я рад предоставить свой полный код, если это необходимо, и все остальное, что требуется.