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);