NegaScout

на главную страницу


int AlphaBetaWhite(int alpha, int beta, int depth)// поиск за белых
{
  int tmp;
  int max = -INFINITY;// устанавливаем локальный максимум в минус бесконечность
  if(depth <= 0) return Evaluate();// на предельной глубине считаем оценку позиции
  GenerateWhite ();// генерируем список ходов за белых
  while(moveList)// списки ходов локальные, т.е. действуют только в узле
  {
     MakeMoveWhite;// делаем ход
     if(i== 0)// первый ход перебираем с полным окном, потому что априорно считаем его лучшим
    {
        tmp = AlphaBetaBlack (alpha, beta, depth-1);
     }else{
        tmp = AlphaBetaBlack (alpha, (alpha+1), depth-1);// остальные пытаемся отсечь перебором с нулевым окном
        if ((value > alpha)&&(value < beta))// если результат все-таки улучшает alpha и beta,то перебираем снова
       {
          tmp = AlphaBetaBlack (tmp, beta, depth-1);// считаем от tmp до beta, так как найденный tmp – наш минимум
       }
     }
  UnMakeMoveWhite;// откатываем ход
  if(tmp > max) max = tmp; //
  if(tmp > alpha) alpha = tmp; //
  if(max >= beta) return max; //
  }
  return max;
}

int AlphaBetaBlack (int alpha, int beta, int depth)// поиск за черных
{
  int tmp;
  int min = INFINITY;
  if(depth <= 0) return Evaluate();
  GenerateBlack ();
  while(moveList)
  {
     MakeMoveBlack;
     tmp = AlphaBetaWhite (alpha, beta, depth-1);
     if(i== 0)// первый ход перебираем с полным окном, потому что априорно считаем его лучшим
    {
       tmp = AlphaBetaWhite (alpha, beta, depth-1);
     }else{
       tmp = AlphaBetaWhite ((beta-1), beta, depth-1);// остальные пытаемся отсечь перебором с нулевым окном
       if ((value > alpha)&&(value < beta))// если результат все таки улучшает alpha и beta,то перебираем снова
      {
         tmp = AlphaBetaWhite (alpha, tmp, depth-1);// считаем от alpha до tmp, так как найденный tmp – наш максимум
      }
    }
    UnMakeMoveBlack;
    if(tmp < min) min = tmp; //
    if(tmp < beta) beta = tmp; //
    if(min <=alpha) return min; //
  }
  return min;
}

Весь алгоритм строится на том, что мы пробуем перебрать с нулевым окном, т.е. beta = alpha
+ 1. Считается, что при нулевом окне отсечек будет гораздо больше и это позволит быстрее
просмотреть неинтересные ветки.

Почему alpha + 1, а не alpha + 2 или alpha + 0.1 - я не знаю. Тут надо думать. Также,
почему диапазон alpha,alpha + 1 назвали нулевым окном для меня загадка. Может умные люди
подскажут, в чем тут дело.

Считается, что NegaScout дает до 50% ускорения. Звучит довольно заманчиво особенно на
длинных контролях. Однако, меня ждал облом.
Надо сказать, что NegaScout в моей программе почти не дает ускорения, а в некоторых позициях
даже слегка притормаживает. В большинстве случаев речь идет об 5-10% , так что можно было бы
и не напрягаться. Несмотря на то, что он почти бесполезен, выкинуть жалко, тем более что он
все-таки слегка ускоряет счет.