3 #ifndef OSL_SEARCHSTATE2_H
4 #define OSL_SEARCHSTATE2_H
21 #include <boost/shared_ptr.hpp>
22 #include <boost/utility.hpp>
35 FixedCapacityVector<SimpleHashRecord*, SEARCH_DEPTH_MAX>
data;
81 #define search_assert(x) assert(((x) || (SearchState2Core::abort())))
82 #define search_assert2(x, m) assert(((x) || (SearchState2Core::abort(m))))
83 struct AlphaBeta2ParallelCommon;
91 friend struct AlphaBeta2ParallelCommon;
93 enum { MaxDepth = 64 };
100 void setCheckmateSearcher(checkmate_t *new_checkmate) {
101 checkmate_searcher = new_checkmate;
111 boost::shared_ptr<SearchState2Shared>
shared;
113 typedef FixedCapacityVector<Move,MaxDepth>
PVVector;
115 CArray<PVVector,MaxDepth>
pv;
116 enum NodeType { PvNode = 0, AllNode = 1, CutNode = -1, };
126 int curDepth()
const {
return history().size() - root_depth; }
134 virtual void setState(
const NumEffectState& s);
135 void setHistory(
const MoveStack& h);
169 shared->killer_moves.setMove(curDepth(), best_move);
170 const Move last_move = lastMove();
173 shared->bigram_killers.setMove(last_move, best_move);
178 shared->bigram_killers.getMove(state(), lastMove(), moves);
179 #ifdef TRI_PLY_BIGRAM_KILLERS
180 if (move_history.hasLastMove(3))
181 shared->bigram_killers.getMove(state(), lastMove(3), moves);
186 getBigramKillerMoves(moves);
187 shared->killer_moves.getMove(state(), curDepth(), moves);
190 return shared->bigram_killers;
199 current_state.changeTurn();
201 move_history.push(pass);
206 current_state.changeTurn();
216 move_history.push(move);
217 record_stack.
push(0);
218 assert(curDepth() > 0);
219 node_type[curDepth()] =
static_cast<NodeType>(-node_type[curDepth()-1]);
226 : new_hash(h), state(s)
231 state->updateRepetitionCounterAfterMove(new_hash);
234 template <
class Function>
254 repetition_counter.
push(new_hash, current_state);
262 repetition_counter.
pop();
266 void makeMoveHook(
Move);
272 template <Player P,
class Function>
274 Move move, Function& f)
276 pushBeforeApply(move);
279 current_state.makeUnmakeMove(Player2Type<P>(), move, wrapper);
285 HashKey new_hash = currentHash().newHashWithMove(move);
286 pushBeforeApply(move);
287 current_state.makeMove(move);
288 updateRepetitionCounterAfterMove(new_hash);
291 const Move lastMove(
int i=1)
const {
return move_history.lastMove(i); }
292 const MoveStack&
history()
const {
return move_history; }
295 const NumEffectState&
state()
const {
return current_state; }
296 const NumEffectState&
rootState()
const {
return root_state; }
297 void restoreRootState();
300 return repetition_counter;
304 return repetition_counter.
history().top();
310 template <Player P,
class Function>
314 current_state.makeUnmakeMove(Player2Type<P>(), move, f);
324 (node_limit, current_state, currentHash(), path(), lastMove());
331 int node_limit,
Move& checkmate_move,
333 #ifdef OSL_DFPN_SMP_SEARCH
339 assert(P == path.
turn());
340 #ifdef OSL_DFPN_SMP_SEARCH
342 return search.isWinningStateParallel<P>
343 (node_limit, state, key, path, checkmate_move, last_move);
346 (node_limit, state, key, path, checkmate_move, last_move);
351 int node_limit,
Move& checkmate_move,
352 Move last_move,
bool parallel=
false)
354 if (state.turn() ==
BLACK)
355 return isWinningState<BLACK>
356 (search, state, key, path, node_limit, checkmate_move, last_move, parallel);
358 return isWinningState<WHITE>
359 (
search, state, key, path, node_limit, checkmate_move, last_move, parallel);
365 return isWinningState<P>(*checkmate_searcher, current_state, currentHash(),
366 path(), node_limit, checkmate_move, lastMove(), parallel);
381 #ifdef OSL_DFPN_SMP_SEARCH
387 current_state.changeTurn();
388 HashKey threatmate_hash = currentHash();
389 threatmate_hash.changeTurn();
390 const PathEncoding threatmate_path(current_state.turn());
393 #ifdef OSL_DFPN_SMP_SEARCH
395 threatmate = checkmate_searcher->template isWinningStateParallel<Opponent>
396 (node_limit, current_state,
397 threatmate_hash, threatmate_path, threatmate_move,
Move::PASS(P));
401 = checkmate_searcher->template isWinningState<Opponent>
402 (node_limit, current_state,
403 threatmate_hash, threatmate_path, threatmate_move,
Move::PASS(P));
404 current_state.changeTurn();
411 current_state.changeTurn();
419 current_state.changeTurn();
423 virtual bool abort(
Move)
const;
427 const Move last_move = lastMove();
430 const Square king = state().kingSquare(state().turn());
434 (state(), last_move.
ptypeO(), last_move.
to(), king);
440 const int depth = curDepth();
441 makePV(pv[depth], m, pv[depth+1]);
445 const int depth = curDepth();
448 void makePV(PVVector& parent,
Move m, PVVector& pv)
const;
456 assert(((
depth % 2) && state().turn() == turn)
457 || ((
depth % 2) == 0 && state().turn() != turn));
459 for (
int i=
depth;; i+=2) {
460 if (! hasLastRecord(i) || ! lastRecord(i))
462 if (lastRecord(i)->qrecord.threatmate.status(turn).status()
471 assert(((
depth % 2) && state().turn() == turn)
472 || ((
depth % 2) == 0 && state().turn() != turn));
475 for (
int i=
depth;; i+=2) {
476 if (! hasLastRecord(i) || ! lastRecord(i))
478 if (lastRecord(i)->qrecord.threatmate.status(turn).status()
481 if (lastMove(i-1).isCapture())
489 #undef search_assert2
490 #define search_assert(x) assert((x) || SearchState2Core::abort())
491 #define search_assert2(x, m) assert((x) || SearchState2Core::abort(m))
504 SearchState2(
const NumEffectState& s, checkmate_t& checker);
507 void setState(
const NumEffectState& s);
542 #undef search_assert2