13 #include <boost/foreach.hpp> 
   22                                 int black_win, 
int white_win,
 
   23                                 const Move& good_move)
 
   25   const PieceStand black_stand = key.pieceStand();
 
   26   const Player turn = key.turn();
 
   29     if (black_stand.
get(ptype))
 
   34       HashKey new_key = key;
 
   35       new_key.setPieceStand(new_stand);
 
   36       SimpleHashRecord *record = table.
allocate(new_key, LIMIT);
 
   39         const Move record_move = (turn == 
WHITE) ? good_move : Move::INVALID();
 
   40         record->setAbsoluteValue(record_move, white_win, LIMIT);
 
   41         record->qrecord.setHistoryValue(record_move, white_win);
 
   44     if (black_stand.
canAdd(ptype))
 
   52       HashKey new_key = key;
 
   53       new_key.setPieceStand(new_stand);
 
   54       SimpleHashRecord *record = table.
allocate(new_key, LIMIT);
 
   57         const Move record_move = (turn == 
BLACK) ? good_move : Move::INVALID();
 
   58         record->setAbsoluteValue(record_move, black_win, LIMIT);
 
   59         record->qrecord.setHistoryValue(record_move, black_win);
 
   67                             int black_win, 
int draw, 
int white_win)
 
   74   move_history.
push(Move::INVALID());
 
   75   assert(move_history.size() == history.size());
 
   77   HashKeyStack reverse_history;
 
   78   while (! history.empty())
 
   80     const HashKey key = history.top();
 
   82     assert(move_history.hasLastMove());
 
   83     const Move last_move = move_history.lastMove();
 
   86     if (key != HashKey(state.
state()))  
 
   87       reverse_history.push(key);
 
   90     adjustDominance(key, table, black_win, white_win, last_move);
 
   93   while (! reverse_history.empty())
 
   96     const HashKey key = reverse_history.top();
 
   97     reverse_history.pop();
 
   99     SimpleHashRecord *record = table.allocate(key, LIMIT);
 
  101     if (result.first.isDraw())
 
  103       record->setAbsoluteValue(Move::INVALID(), draw*result.second, LIMIT);
 
  104       record->qrecord.setHistoryValue(draw*result.second);
 
  108       assert(result.first.hasWinner());
 
  109       const int value = (result.first.winner() == 
BLACK) ? black_win : white_win;
 
  110       record->setAbsoluteValue(Move::INVALID(), value, LIMIT);
 
  111       record->qrecord.setHistoryValue(value);
 
  123   for (
int i=history.size(); i>0; --i) {
 
  124     const Move m = history.lastMove(i);
 
  125     if (! m.
isNormal() || ! state.isValidMove(m)) {
 
  126       std::cerr << 
"setPV failed " << i << 
" " << m << 
"\n" << state;
 
  128       for (
int j=history.size(); j>0; --j)
 
  129         std::cerr << history.lastMove(j) << 
" ";
 
  130       std::cerr << std::endl;
 
  134     const MoveWithComment& pv = pv_history[(history.size()-i) % pv_history.size()];
 
  135     if (pv.root == key && state.turn() == Turn && !pv.moves.empty()) {
 
  138         BOOST_FOREACH(
Move p, pv.moves)
 
  142       if (! pv.move.isNormal() || ! state.isValidMove(pv.move)) 
 
  144         std::cerr << 
"setPV failed (corrupt pv) " << pv.move << 
"\n";
 
  148         NumEffectState state_copy = state;
 
  149         state_copy.makeMove(pv.move);
 
  150         HashKey cur = key.newHashWithMove(pv.move);
 
  151         BOOST_FOREACH(
Move move, pv.moves) {
 
  152           SimpleHashRecord *record = table.
allocate(cur, 1000);
 
  154             if (move == Move::PASS(state_copy.turn()) 
 
  155                 || state_copy.isValidMove(move)) {
 
  159               std::cerr << 
"setPV failed (corrupt pv) " << i << 
" " << move << 
"\n";
 
  163           state_copy.makeMove(move);
 
  164           cur = cur.newHashWithMove(move);
 
  168     key = key.newHashWithMove(m);