Проблема с MiniMax для альфа-бета-поиска

Хорошо, моя проблема должна звучать довольно знакомо всем, кто играл в программирование настольных игр, так что вот оно:

  • Я реализовал вариант алгоритма MiniMax (возвращающий ходы вместо значений min / max).
  • Я также попытался настроить его как альфа-бета, хотя это закончилось полным провалом.

Итак, вот мой код MiniMax:

Move* Board::miniMax(int depth)
{
return this->maxMove(1, depth);
}

Move* Board::maxMove(int ply, int depth)
{
vector<Move*> moves = this->possibleMoves();
int movesSize = moves.size();

Move* maxMove = new Move(MINUS_INF);

for (int i=0; i<movesSize; i++)
{
Move* move = moves[i];
HASHMAKE(move,this);

move->value = (ply<depth) ? (this->minMove(ply+1, depth))->value
: this->eval();

maxMove = MAXMOVE(maxMove,move);

UNHASHMAKE(move,this);
}

return maxMove;
}

Move* Board::minMove(int ply, int depth)
{
vector<Move*> moves = this->possibleMoves();
int movesSize = moves.size();

Move* minMove = new Move(PLUS_INF);

for (int i=0; i<movesSize; i++)
{
Move* move = moves[i];
HASHMAKE(move,this);

move->value = (ply<depth) ? (this->maxMove(ply+1, depth))->value
: this->eval();

minMove = MINMOVE(minMove,move);

UNHASHMAKE(move,this);
}

return minMove;
}

Есть идеи, как можно настроить вышеуказанную вещь так, чтобы это был альфа-бета-поиск?


И вот моя попытка преобразования альфа-бета (которая терпит неудачу):

Move* Board::alphaBeta(int depth)
{
return this->alphaMax(1,depth,MINUS_INF,PLUS_INF);
}

Move* Board::alphaMax(int ply, int depth, int a, int b)
{
vector<Move*> moves = this->possibleMoves();
int movesSize = moves.size();

Move* maxMove = new Move(MINUS_INF);

for (int i=0; i<movesSize; i++)
{
Move* move = moves[i];
HASHMAKE(move,this);

move->value = (ply<depth) ? (this->alphaMin(ply+1, depth,a,b))->value
: this->eval();

maxMove = MAXMOVE(maxMove,move);
if (maxMove->value>=b) return maxMove;
a = MAXVAL(a,maxMove->value);

UNHASHMAKE(move,this);
}

return maxMove;
}

Move* Board::alphaMin(int ply, int depth, int a, int b)
{
vector<Move*> moves = this->possibleMoves();
int movesSize = moves.size();

Move* minMove = new Move(PLUS_INF);

for (int i=0; i<movesSize; i++)
{
Move* move = moves[i];
HASHMAKE(move,this);

move->value = (ply<depth) ? (this->alphaMax(ply+1, depth,a,b))->value
: this->eval();

minMove = MINMOVE(minMove,move);
if (minMove->value<=a) return minMove;
b = MINVAL(b,minMove->value);

UNHASHMAKE(move,this);
}

return minMove;
}

HINTS (чтобы избежать недоразумений) :

  • this->eval() Функция возвращает счет с точки зрения игрока А. Например. +100 очков означает, что позиция в пользу игрока A, а -100 очков означает, что позиция в пользу игрока B.

  • MINUS_INF а также PLUS_INF были определены как некоторые произвольно малые и большие значения, соответственно.

  • Это не что-то вроде домашней работы или чего-то еще (если бы я, скорее всего, никогда не имел бы интереса играть с такими вещами … смеется)

  • Move простой класс, содержащий сведения о перемещении, а также его соответствующее значение (назначенное eval функция.

  • HASHMAKE а также UNHASHMAKE это всего лишь два макроса перемещения (не) создания и перемещения (не) хэширования, которые не должны иметь большого значения.

  • MAXMOVE определяется так: #define MAXMOVE(A,B) (((A)->value>=(B)->value)?(A):(B))

  • MINMOVE определяется так: #define MINMOVE(A,B) (((A)->value<=(B)->value)?(A):(B))

0

Решение

Не уверен, что это так, но я думаю, что в alphaMin

if (minMove->value<=a) return minMove;
b = MINVAL(b,minMove->value);
UNHASHMAKE(move,this);

должно быть

UNHASHMAKE(move,this);
if (minMove->value<=a) return minMove;
b = MINVAL(b,minMove->value);

а также аналогичные изменения в alphaMax,

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]