Что-то не так с моим поиском покоя?
Я продолжаю странно себя вести в своем AI на основе Negamax, когда пытаюсь реализовать QuiesenceSearch. Я основал это на псевдокоде отсюда:
int Quiesce( int alpha, int beta ) {
int stand_pat = Evaluate();
if( stand_pat >= beta )
return beta;
if( alpha < stand_pat )
alpha = stand_pat;
until( every_capture_has_been_examined ) {
MakeCapture();
score = -Quiesce( -beta, -alpha );
TakeBackMove();
if( score >= beta )
return beta;
if( score > alpha )
alpha = score;
}
return alpha;
}
И это мой код:
private double QuiescenceSearch(GameBoard gameBoard, double alpha, double beta, int color)
{
double standPat = color * CalculateBoardScore(gameBoard);
if (standPat >= beta)
{
return beta;
}
else if (alpha < standPat)
{
alpha = standPat;
}
foreach (Move move in GetNoisyMoves(gameBoard))
{
gameBoard.TrustedPlay(move);
double score = -1.0 * QuiescenceSearch(gameBoard, -beta, -alpha, -color);
gameBoard.UndoLastMove();
if (score >= beta)
{
return beta;
}
else if (score > alpha)
{
alpha = score;
}
}
return alpha;
}
А именно, ИИ, похоже, ведет себя так, как будто совершить самый худший ход (убить себя) - это путь.
CalculateBoardScore всегда возвращается со стороны цвета == 1, следовательно, умножается на цвет.
1 ответ
Решение
Я реорганизовал свой код, и теперь это работает правильно:
private double QuiescenceSearch(GameBoard gameBoard, double alpha, double beta, int color)
{
double bestValue = color * CalculateBoardScore(gameBoard);
alpha = Math.Max(alpha, bestValue);
if (alpha >= beta)
{
return bestValue;
}
foreach (Move move in GetNoisyMoves(gameBoard))
{
gameBoard.TrustedPlay(move);
double value = -1 * QuiescenceSearch(gameBoard, -beta, -alpha, -color);
gameBoard.UndoLastMove();
bestValue = Math.Max(bestValue, value);
alpha = Math.Max(alpha, bestValue);
if (alpha >= beta)
{
break;
}
}
return bestValue;
}
Проблема с псевдокодом состоит в том, что он должен возвращать stand_pat/score, если он больше, чем бета, а не бета:
int Quiesce( int alpha, int beta ) {
int stand_pat = Evaluate();
if( stand_pat >= beta )
return stand_pat;
if( alpha < stand_pat )
alpha = stand_pat;
until( every_capture_has_been_examined ) {
MakeCapture();
score = -Quiesce( -beta, -alpha );
TakeBackMove();
if( score >= beta )
return score;
if( score > alpha )
alpha = score;
}
return alpha;
}