src/makebook.cpp
// Compute a recommended relative weight for a set of book
// moves from a given position
Compute a recommended relative weight for a set of book
moves from a given position
Compute a recommended relative weight for a set of book moves from a given position
static void computeWeights(const hash_t hashCode, BookEntry *be) 
{
   int total = 0;
   BookEntry *p;
   for (p = be; p; p = p->next) {
      if ((p->count >= minFrequency) || p->first) {
          total += p->count;
      }
   }
   if (total == 0) return;
   int bestWinWeight = -1;
   const int black_to_move = BoardHash::sideToMove(hashCode) == Black;
   for (p = be; p; p = p->next) {
       p->relativeFreq = book::MAX_WEIGHT*(p->count)/total;
       int winloss;
       if (black_to_move) {
           winloss = (-p->white_win_loss*100)/(int)(p->count);
       }
       else {
           winloss = (p->white_win_loss*100)/(int)(p->count);
       }
       p->winWeight = (winloss+100)/2;
       if (p->winWeight > bestWinWeight) bestWinWeight = p->winWeight;
#ifdef _TRACE
       cout << "win weight=" << p->winWeight << endl;
#endif
   }
   int totalWeight = 0;
   for (p = be; p; p = p->next) {
      int w;
      if (p->rec != book::NO_RECOMMEND) {
         w = p->rec*book::MAX_WEIGHT/100;
#ifdef _TRACE
         cout << "explicit weight: " << w << endl;
#endif
      }
      else if (p->moveEval == BLUNDER_MOVE ||
               p->moveEval == POOR_MOVE) {
         w = 0;
#ifdef _TRACE
         cout << "avoid move: " << w << endl;
#endif
      }
      else if (p->moveEval == VERY_GOOD_MOVE) {
         w = book::MAX_WEIGHT;
#ifdef _TRACE
         cout << "best move: " << w << endl;
#endif
      }
      else {
#ifdef _TRACE
          cout << "count=" << p->count << " moveEval=" <<
              (int)p->moveEval << " posEval=" << (int)p->eval << endl;
#endif
          if (p->first && p->count < (unsigned)Util::Max(2,minFrequency) && 
              (p->moveEval != NO_MOVE_EVAL || p->eval != NO_POSITION_EVAL)) {
             w = book::MAX_WEIGHT/2;
#ifdef _TRACE
             cout << "using neutral eval, w=" << w << endl;
#endif
         }
         else if (bestWinWeight == 0) {
#ifdef _TRACE
             cout << "bestWinWeight = 0, so w=0" << endl;
#endif
             w = 0;
         } else {
             int winWeight = p->winWeight;
             if (winWeight <= 9*bestWinWeight/10) {
                winWeight = winWeight*winWeight/bestWinWeight;
             }
             w = (p->relativeFreq*winWeight)/50;
         }
#ifdef _TRACE
         cout << " computed weight=" << w << endl;
         int w1 = w;
#endif 
         if (p->moveEval != NO_MOVE_EVAL) {
            const int ev = (int)p->moveEval-(int)NEUTRAL_EVAL-1;
            w = w*(100-25*ev)/100;
         }
         else if (p->eval != NO_POSITION_EVAL) {
            const int ev = (int)p->eval-(int)EQUAL_POSITION;
            const int div = 1 + p->count/10;
            if (black_to_move) {
                w = w*(100-25*ev/div)/100;
            } else {
                w = w*(100+25*ev/div)/100;
            }
         }
#ifdef _TRACE
         if (w1 != w) cout << "adjusted weight: " << w << endl;
#endif 
      }
      w = Util::Min(w,2*book::MAX_WEIGHT);
      p->weight = w;
      totalWeight += w;
   }
   for (p = be; p; p = p->next) {
      if (totalWeight) {
         p->weight = p->weight*book::MAX_WEIGHT/totalWeight;
      }
      else {
         p->weight = 0;
      }
   }
}
static void computeWeights ( const hash_t hashCode , BookEntry * be ) { int total = 0 ; BookEntry * p ; for ( p = be ; p ; p = p -> next ) { if ( ( p -> count >= minFrequency ) || p -> first ) { total += p -> count ; } } if ( total == 0 ) return ; int bestWinWeight = -1 ; const int black_to_move = BoardHash :: sideToMove ( hashCode ) == Black ; for ( p = be ; p ; p = p -> next ) { p -> relativeFreq = book :: MAX_WEIGHT * ( p -> count ) / total ; int winloss ; if ( black_to_move ) { winloss = ( - p -> white_win_loss * 100 ) / ( int ) ( p -> count ) ; } else { winloss = ( p -> white_win_loss * 100 ) / ( int ) ( p -> count ) ; } p -> winWeight = ( winloss + 100 ) / 2 ; if ( p -> winWeight > bestWinWeight ) bestWinWeight = p -> winWeight ; #ifdef _TRACE cout << " " << p -> winWeight << endl ; #endif } int totalWeight = 0 ; for ( p = be ; p ; p = p -> next ) { int w ; if ( p -> rec != book :: NO_RECOMMEND ) { w = p -> rec * book :: MAX_WEIGHT / 100 ; #ifdef _TRACE cout << " " << w << endl ; #endif } else if ( p -> moveEval == BLUNDER_MOVE || p -> moveEval == POOR_MOVE ) { w = 0 ; #ifdef _TRACE cout << " " << w << endl ; #endif } else if ( p -> moveEval == VERY_GOOD_MOVE ) { w = book :: MAX_WEIGHT ; #ifdef _TRACE cout << " " << w << endl ; #endif } else { #ifdef _TRACE cout << " " << p -> count << " " << ( int ) p -> moveEval << " " << ( int ) p -> eval << endl ; #endif if ( p -> first && p -> count < ( unsigned ) Util :: Max ( 2 , minFrequency ) && ( p -> moveEval != NO_MOVE_EVAL || p -> eval != NO_POSITION_EVAL ) ) { w = book :: MAX_WEIGHT / 2 ; #ifdef _TRACE cout << " " << w << endl ; #endif } else if ( bestWinWeight == 0 ) { #ifdef _TRACE cout << " " << endl ; #endif w = 0 ; } else { int winWeight = p -> winWeight ; if ( winWeight <= 9 * bestWinWeight / 10 ) { winWeight = winWeight * winWeight / bestWinWeight ; } w = ( p -> relativeFreq * winWeight ) / 50 ; } #ifdef _TRACE cout << " " << w << endl ; int w1 = w ; #endif if ( p -> moveEval != NO_MOVE_EVAL ) { const int ev = ( int ) p -> moveEval - ( int ) NEUTRAL_EVAL - 1 ; w = w * ( 100 - 25 * ev ) / 100 ; } else if ( p -> eval != NO_POSITION_EVAL ) { const int ev = ( int ) p -> eval - ( int ) EQUAL_POSITION ; const int div = 1 + p -> count / 10 ; if ( black_to_move ) { w = w * ( 100 - 25 * ev / div ) / 100 ; } else { w = w * ( 100 + 25 * ev / div ) / 100 ; } } #ifdef _TRACE if ( w1 != w ) cout << " " << w << endl ; #endif } w = Util :: Min ( w , 2 * book :: MAX_WEIGHT ) ; p -> weight = w ; totalWeight += w ; } for ( p = be ; p ; p = p -> next ) { if ( totalWeight ) { p -> weight = p -> weight * book :: MAX_WEIGHT / totalWeight ; } else { p -> weight = 0 ; } } }
Compute a recommended relative weight for a set of book
moves from a given position
Compute a recommended relative weight for a set of book moves from a given position
// compute total frequency for eligible moves // white is on move // Now compute the weights // don't play these moves // This move is in the first annotated book file but // occurs elsewhere with very low frequency. If we have // information about it from an annotation, start // it with a neutral eval and modify that based on // the annotation (even if it has 0 winning results). // If however there is no NAG associated with the move, // use the win/loss frequency to set the weight as usual. // moves that are relatively worse than the best move // get bumped lower in weight // if there is an eval (from a NAG) for the move, use that // to modify the weight // move evals are -1..2 // if there is an eval (from a NAG) for the position, use // that to modify the weight. Note though position evals // are generally at the end of a line, and we do not want // to modify high-frequency moves, because the basic book // is incomplete and there will be branches between those // moves and the eval point. // Note: ev is range -4..4 // This weight is not normalized yet, so allow it to exceed max weight // last pass: normalize the weights // no moves have non-zero weight