В настоящее время я реализую MiniMax Алгоритм с Альфа бета обрезка для игры в крестики-нолики.
Мой алгоритм принимает пустую доску и, в конце концов, эта доска содержит то же состояние, что и текущая доска, вместе со следующим сделанным ходом. Тогда я просто делаю *this
(текущая доска) равна возвращаемой доске.
Однако по какой-то причине мой алгоритм застревает в бесконечном цикле. Вот моя функция miniMax:
int board::miniMax(int alpha, int beta, board & childWithMaximum)
{
if (checkDone())
return boardScore();
vector<board> children = getChildren();
while (!children.empty())
{
board curr = children.back();
board dummyBoard;
int score = curr.miniMax(alpha, beta, dummyBoard);
if (computerTurn && (beta > score)) {
beta = score;
childWithMaximum = *this;
if (alpha >= beta)
break;
} else if (alpha < score) {
alpha = score;
childWithMaximum = *this;
if (alpha >= beta)
break;
}
}
return computerTurn ? alpha : beta;
}
Я сделал некоторую отладку оператора печати, и кажется, что это getChildren()
вспомогательная функция работает. Я распечатал пару детей, и на дереве были другие состояния доски:
vector<board> board::getChildren()
{
vector<board> children;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (getPosition(i, j) == '*') {
//move not made here
board moveMade(*this);
moveMade.setPosition(i, j);
children.push_back(moveMade);
}
}
}
return children;
}
Тем не менее, мой miniMax()
функция не делает возвратную доску равной следующему ходу.
Инструкции в вашем while
петля никогда не изменяет children
, но остановится только если children.empty()
правда. Поэтому внутренний цикл либо никогда не выполняется, либо выполняется бесконечно.
Также здесь:
int score = curr.miniMax(alpha, beta, dummyBoard);
Вы вызываете функцию рекурсивно с теми же параметрами (кроме третьего, который до этого момента не использовался). Так как состояние this
, alpha
а также beta
кажется неизменным до этого момента (за исключением, может быть, если checkDone()
или же getPosition()
изменяет его), это также приведет к бесконечной рекурсии.
Затем я просто делаю * this (текущую доску) равным возвращенной доске.
Нет, ты только другой board
равно *this
, я не вижу *this =
в любом месте вашего кода.
Других решений пока нет …