3 #ifndef OSL_QUIESCENCESEARCH2_TCC 
    4 #define OSL_QUIESCENCESEARCH2_TCC 
   30 #ifdef STAT_WIDTH_VS_LIMIT 
   35 #define quiecence_assert(x,m) assert((x) || state.abort(m)) 
   39 #  define QSEARCH_LAST_CHECK_PENALTY 
   41 #  define QSEARCH_PESSIMISTIC_ESCAPE_THREAT 
   43 #  define QSEARCH_THREATMATE 
   46 #ifdef EXTRA_RICH_QSEARCH 
   48 #  define QSEARCH_SET_MINIMUM_MOVES 
   91 #ifdef QSEARCH_SET_MINIMUM_MOVES 
  110     template <
class QSearch2,Player P>
 
  125         result = (*searcher).template searchInternal<PlayerTraits<P>::opponent>
 
  129     template <
class QSearch2,Player P>
 
  142         result = (*searcher).template takeBackValue<PlayerTraits<P>::opponent>
 
  146     template <
class QSearch2,Player P>
 
  159         result = (*searcher).template takeBackOrChase<PlayerTraits<P>::opponent>
 
  163     template <
class Eval, Player P>
 
  179         assert(
state->turn() == Turn);
 
  191     template <
bool has_record>
 
  205 template <
class EvalT>
 
  206 template <osl::Player P> 
 
  213     const int margin = pawn_value2/2;
 
  215                                           base_t::winThreshold(
alt(P)));
 
  218                                           base_t::winThreshold(P));
 
  220     const int val4 = searchInternal<P>(alpha4, beta4, ev, last_move);
 
  222       return val4 - (beta4-beta);
 
  224       return val4 - (alpha4-alpha);
 
  227   return searchInternal<P>(alpha, beta, ev, last_move);
 
  230 template <
class EvalT>
 
  231 template <osl::Player P, osl::Ptype PTYPE> 
 
  237                             int beta1, 
int beta2, 
eval_t const& ev)
 
  239   mask_t pieces = state.state().effectedMask(P).template selectBit<PTYPE>()
 
  247     assert(moves.empty());
 
  250       = examineTakeBack2<P,false,true>(
moves, threat2, threat1, 
 
  260 template <
class EvalT>
 
  261 template <osl::Player P, osl::Ptype PTYPE, 
bool has_record> 
 
  266                eval_t const& ev, 
Piece last_move_piece, 
int additional_depth)
 
  275     SortCaptureMoves::sortByTakeBack(state.state(), 
moves);
 
  277     return examineMoves<P,has_record,has_record,CAPTURE>
 
  278       (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev,
 
  279        additional_depth, last_move_piece.
square());
 
  284 #ifdef STAT_WIDTH_VS_LIMIT 
  293       Reporter() : 
count(0) {}
 
  296         std::cerr << 
"QuiescenceSearch2 " << average.getAverage() << std::endl;
 
  298       void newRoot() { average.add(
count); 
count=0; }
 
  299       void add() { ++
count; }
 
  305 template <
class EvalT>
 
  306 template <
osl::Player P, 
bool has_record, 
bool has_dont_capture, 
 
  310              const Move *first, 
const Move *last, 
 
  311              int& alpha, 
int beta, 
eval_t const& ev,
 
  312              int additional_depth, 
Square dont_capture)
 
  318 #if (! defined NDEBUG) && (! defined OSL_SMP) 
  319   const bool in_pv = (alpha != beta);
 
  321   while (first != last)
 
  323     const Move move = *first++;
 
  324     if (move_type == CHECK)
 
  331     if (has_dont_capture)
 
  334       if (to == dont_capture)
 
  337     assert((move_type == KING_ESCAPE) || (move_type == UNKNOWN)
 
  338            || (! ShouldPromoteCut::canIgnoreAndNotDrop<P>(move)));
 
  340     if(MoveStackRejections::probe<P>(state.state(),state.history(),state.curDepth(),move,alpha,state.repetitionCounter().checkCount(
alt(P)))){
 
  344     QuiescenceLog::pushMove(
depth(), move, record);
 
  346     const HashKey new_hash = state.currentHash().newHashWithMove(move);
 
  350       = state.repetitionCounter().isAlmostSennichite(new_hash);
 
  351     if (next_sennichite.
isDraw())
 
  353       result = base_t::drawValue();
 
  357       result = base_t::winByFoul(next_sennichite.
winner());
 
  362 #ifdef STAT_WIDTH_VS_LIMIT 
  363       if (depthFromRoot() == 0)
 
  368       if (has_record && alpha != beta
 
  371         helper_t helper(result, 
this, alpha, alpha, new_ev, move, 
 
  373         state.doUndoMoveOrPass<P,helper_t>(new_hash, move, helper);
 
  376           helper_t helper(result, 
this, alpha, beta, new_ev, move, 
 
  378           state.doUndoMoveOrPass<P,helper_t>(new_hash, move, helper);
 
  383         helper_t helper(result, 
this, alpha, beta, new_ev, move, 
 
  385         state.doUndoMoveOrPass<P,helper_t>(new_hash, move, helper);
 
  389       if (base_t::isWinValue(P, result) && (! move.
isPass())
 
  391           ::isMember(state.state(), move))
 
  393         result = base_t::winByFoul(
alt(P));
 
  404           if (base_t::isWinValue(P, cur_val))
 
  406             Square king = state.state().kingSquare(
alt(P));
 
  408               record->
setLowerBound(QSearchTraits::CheckmateSpecialDepth, cur_val, move);
 
  412               record->
setLowerBound(QSearchTraits::MaxDepth, cur_val, move);
 
  423                    || state.abort(move));
 
  430           state.setKillerMove(move);
 
  433             const int d = 
depth();
 
  434             state.historyTable().add(move, d*d);
 
  450                                        int minusDepthFromRoot,
 
  455         = table.
allocate(key, minusDepthFromRoot);
 
  465 template <
class EvalT>
 
  466 template <osl::Player P, 
bool has_record>
 
  471   const bool in_pv = (alpha != beta);
 
  472 #ifndef DONT_USE_CHECKMATE 
  476         && (state.hasLastRecord(1) && state.lastRecord(1)))
 
  478         = (state.lastRecord(1)->threatmate().status(P).status() == ThreatmateState::CHECK_AFTER_THREATMATE);
 
  480       const int result = ev.value() + base_t::threatmatePenalty(P);
 
  485     const Move last_move = state.lastMove();
 
  486     const Square king = state.state().kingSquare(P);
 
  487     const bool one_hop_prook
 
  491          && ((king.
y() == last_move.
to().
y()
 
  492               && abs(king.
x() - last_move.
to().
x()) < 3)
 
  493              || (king.
x() == last_move.
to().
x()
 
  494                  && abs(king.
y() - last_move.
to().
y()) < 3)));
 
  495     if (one_hop_prook && ! has_record) {
 
  498     if (has_record || record) {
 
  500       Move checkmate_move=Move::INVALID();
 
  501       int threatmate_node = 0;
 
  503         threatmate_node += 50;
 
  504       } 
else if (one_hop_prook) {
 
  505         threatmate_node += 20;
 
  507 #ifdef QSEARCH_THREATMATE 
  508       else if ((depthFromRoot() < QSearch2PrivateTraits::ThreatMateDepthFromRoot)
 
  509                && state.tryThreatmate())
 
  510         threatmate_node += 20;
 
  512       bool lose = state.isThreatmateState<P>
 
  516         lose = state.isThreatmateStateShort<P>(2, checkmate_move);
 
  519         const int result = ev.value() + base_t::threatmatePenalty(P);
 
  520         assert(checkmate_move.
isValid());
 
  523                                QSearchTraits::CheckmateSpecialDepth);
 
  524         assert(result % 2 == 0);
 
  530   if (! in_pv && has_record) {
 
  531     int static_value, static_value_depth;
 
  533     if (record->
hasStaticValue(static_value, static_value_depth, type)) {
 
  536         assert(static_value % 2 == 0);
 
  539       if (type == QuiescenceRecord::EXACT
 
  540           && (static_value_depth >= 
depth())) {
 
  541         assert(static_value % 2 == 0);
 
  546   Move threatmate_move;
 
  548       (state.state(), threatmate_move))
 
  550     const int result = ev.value() + base_t::threatmatePenalty(P);
 
  555                              QSearchTraits::CheckmateSpecialDepth);
 
  557     assert(result % 2 == 0);
 
  562     int expect = ev.value() + ev.captureValue(
newPtypeO(P, 
GOLD));
 
  563     Piece threat = state.state().findThreatenedPiece(P);
 
  565       expect += ev.captureValue(threat.
ptypeO());
 
  569   const int eval_alpha = alpha;
 
  571   const int result = staticValueWithThreat<P>(ev, eval_alpha, threat1, threat2);
 
  575                            ? QuiescenceRecord::UPPER_BOUND
 
  576                            : QuiescenceRecord::EXACT,
 
  580   assert(result % 2 == 0);
 
  584 template <
class EvalT>
 
  585 template <osl::Player P>
 
  590 #ifdef STAT_WIDTH_VS_LIMIT 
  591   if (depthFromRoot() == 0)
 
  595   if (depthFromRoot() == 0)
 
  596     QuiescenceLog::enter(state.state());
 
  598 #ifdef MAKE_PV_IN_QUIESCE2 
  610   if (state.state().inCheck(
alt(P)))
 
  611     return base_t::winByFoul(P);
 
  613   assert(state.hasLastRecord());
 
  615     = 
qallocate(table, state.currentHash(), 
depth()-QSearchTraits::MaxDepth,
 
  618     = (state.hasLastRecord(1) && state.lastRecord(1)) 
 
  619     ? &(state.lastRecord(1)->qrecord) : 0;
 
  620   const bool near_checkmate = parent 
 
  621     && (parent->threatmate.maybeThreatmate(
alt(P))
 
  622         || parent->threatmate.mayHaveCheckmate(P)
 
  623         || (parent->threatmate.status(P).status()
 
  624             == ThreatmateState::CHECK_AFTER_THREATMATE));
 
  625   if (! record && near_checkmate)
 
  633     result = searchMain<P,false>(0, alpha, beta, ev, last_move,
 
  634                                  additional_depth, need_eval_update);
 
  635     if (near_checkmate) {
 
  637            && parent->threatmate.maybeThreatmate(
alt(P)))
 
  639           && parent->threatmate.status(P).status()
 
  640            == ThreatmateState::CHECK_AFTER_THREATMATE)) {
 
  648     const bool is_king_in_check = state.state().inCheck();
 
  651     result = searchMain<P,true>(record, alpha, beta, ev, last_move,
 
  652                                 additional_depth, need_eval_update);
 
  653 #ifdef MAKE_PV_IN_QUIESCE2 
  655       state.makePV(record->bestMove());
 
  659   QuiescenceLog::node(
depth(), alpha, beta, result);
 
  661   assert(result % 2 == 0);
 
  665 template <
class EvalT>
 
  669   int static_value = ev.value();
 
  670   if (! (depthFromRoot() < QSearch2PrivateTraits::EscapeFromLastMoveDepthFromRoot))
 
  673   assert(last_move_piece.
isPiece());
 
  677   EffectUtil::findThreat<EvalT>(state.state(), from, last_move_piece.
ptypeO(),
 
  681   if (targets[0].ptype() == 
KING)
 
  683     if (targets.size() < 2)
 
  686     int threat = eval_t::captureValue(targets[1].ptypeO());
 
  687     if (state.state().hasEffectAt(
alt(P), targets[1].square()))
 
  688       threat += eval_t::captureValue(last_move_piece.
ptypeO());
 
  690     return static_value + threat;
 
  692   int first_threat = eval_t::captureValue(targets[0].ptypeO());
 
  693   if (state.state().hasEffectAt(
alt(P), targets[0].square()))
 
  694     first_threat += eval_t::captureValue(last_move_piece.
ptypeO());
 
  696   first_threat /= SecondThreat;
 
  697   if (targets.size() < 2)
 
  698     return static_value + (first_threat & (~0x1));
 
  700   int second_threat = eval_t::captureValue(targets[1].ptypeO());
 
  701   if (state.state().hasEffectAt(
alt(P), targets[1].square()))
 
  702     second_threat += eval_t::captureValue(last_move_piece.
ptypeO());
 
  704   return static_value + ((first_threat + second_threat) & (~0x1));
 
  707 template <
class EvalT>
 
  708 template <osl::Player P>
 
  715   const Move pass = Move::PASS(P);
 
  718   helper_t helper(result, 
this, alpha, beta, ev, pass, 0);
 
  719   const HashKey new_hash = state.currentHash().newHashWithMove(pass);
 
  721   max_depth -= QSearch2PrivateTraits::PassExtraDepth;
 
  722   state.doUndoMoveOrPass<P,helper_t>(new_hash, pass, helper);
 
  723   max_depth += QSearch2PrivateTraits::PassExtraDepth;
 
  728 template <
class EvalT>
 
  729 template <osl::Player P, 
bool has_record>
 
  732            int alpha, 
int beta, 
eval_t& ev, 
Move last_move,
 
  735   const bool in_pv = (alpha != beta);
 
  736 #if (! defined NDEBUG) && (! defined OSL_USE_RACE_DETECTOR) 
  739   assert((! has_record) || record);
 
  742   assert((last_move == state.lastMove()) 
 
  743          || ! last_move.
isNormal() || ! state.lastMove().isNormal());
 
  744 #if (!defined OSL_USE_RACE_DETECTOR) && (!defined MINIMAL) 
  745   state.depth_node_count_quiesce[state.curDepth()]++;
 
  747 #ifndef DONT_USE_CHECKMATE 
  748   const int node_count_before = node_count;
 
  750   const Square last_to = last_move.
to();
 
  751   int cur_val = base_t::winByCheckmate(
alt(P));
 
  755         || record->
lowerDepth() >= QSearchTraits::HistorySpecialDepth)
 
  765 #if (! defined NDEBUG) && (! defined OSL_USE_RACE_DETECTOR) 
  773 #ifndef DONT_USE_CHECKMATE 
  777       Move checkmate_move=Move::INVALID();
 
  778       if (need_eval_update == BeforeUpdate) {
 
  779         ev.update(state.state(), last_move);
 
  780         need_eval_update = AfterUpdate;
 
  782       bool win = state.isWinningState<P>
 
  785         win = state.isWinningStateShort<P>(2, checkmate_move);
 
  788         const int result = base_t::winByCheckmate(P);
 
  789         assert(checkmate_move.
isValid());
 
  790         assert(state.state().isValidMove(checkmate_move));
 
  792                               result, checkmate_move);
 
  798         || record->
upperDepth() >= QSearchTraits::HistorySpecialDepth)
 
  805 #if (! defined NDEBUG) && (! defined OSL_USE_RACE_DETECTOR) 
  812 #if (! defined NDEBUG) && (! defined OSL_USE_RACE_DETECTOR) 
  816   if (need_eval_update == BeforeUpdate) {
 
  817     ev.update(state.state(), last_move);
 
  818     need_eval_update = AfterUpdate;
 
  820   const bool is_king_in_check = state.state().inCheck();
 
  822   if (is_king_in_check)
 
  830       if (state.lastMove(2).isNormal() 
 
  831           && state.lastMove(3).isNormal()
 
  832           && state.lastMove(4).isNormal()
 
  833           && state.lastMove(2).to() == last_move.
to()
 
  834           && state.lastMove(3).to() == last_move.
to()
 
  835           && state.lastMove(4).to() == last_move.
to())
 
  841       move_order::CaptureSort::sort(moves.begin(), moves.end());
 
  842       examineMoves<P,has_record,false,KING_ESCAPE>
 
  843         (record, cur_val, &*moves.begin(), &*moves.end(),alpha, beta, ev,
 
  853   assert(! is_king_in_check);
 
  855   PieceMask pins = state.state().pin(
alt(P));
 
  856   Move checkmate_move=Move::INVALID();
 
  857   Square kingSquare=state.state().template kingSquare<PlayerTraits<P>::opponent>();
 
  859       ? ImmediateCheckmate::hasCheckmateMove<P>(state.state(), king_info,kingSquare,checkmate_move)
 
  860       : state.isWinningStateShort<P>(2, checkmate_move)) {
 
  861     const int result = base_t::winByCheckmate(P);
 
  862     assert(checkmate_move.
isValid());
 
  865       assert(state.state().isValidMove(checkmate_move));
 
  867                             result, checkmate_move);
 
  873   if (
depth() <= 0 && has_record) {
 
  875       return ev.value() + base_t::threatmatePenalty(P);
 
  877       return ev.value() + base_t::threatmatePenalty(
alt(P));
 
  884   const bool king_escape = (last_ptype == 
KING) && last_capture == 
PTYPE_EMPTY;
 
  887       || (
depth() <= 0 && additional_depth == 0)
 
  889           && ((
depth() + additional_depth <= 0)
 
  891                   && last_ptype != 
KING))))
 
  893     if (ev.progress16().value() == 15
 
  894         && state.tryThreatmate()
 
  895         && ImmediateCheckmate::hasCheckmateMove<PlayerTraits<P>::opponent>(state.state()))
 
  896       return ev.value() + base_t::threatmatePenalty(P);
 
  897     const int base = takeBackValue<P>(alpha, beta, ev, last_move);
 
  898 #ifdef QSEARCH_LAST_CHECK_PENALTY 
  910   const int static_value
 
  912        ? takeBackValue<P>(alpha, beta, ev, last_move)
 
  913 #ifdef QSEARCH_REAL_PASS 
  914        : ((depthFromRoot() < QSearch2PrivateTraits::EscapeDepthFromRoot)
 
  915           && (! last_move.
isPass()))
 
  916        ? passValue<P>(alpha, beta, ev)
 
  918        : staticValue<P,has_record>(ev, alpha, beta, record))
 
  920     + (OslConfig::evalRandom() ? HashRandom::value(state.currentHash()): 0)
 
  923   assert(static_value % 2 == 0);
 
  924   assert(! isWinValue(
alt(P), static_value));
 
  926   QuiescenceLog::staticValue(
depth(), static_value);
 
  930     cur_val = static_value;
 
  952   Piece last_capture_piece = Piece::EMPTY();
 
  955     state.getBigramKillerMoves(moves);
 
  956     if (examineMoves<P,has_record,false,UNKNOWN>
 
  957         (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev,
 
  969       assert(state.state().template isAlmostValidMove<true>(bestmove_in_record));
 
  970       assert(moves.empty());
 
  971       moves.push_back(bestmove_in_record);
 
  972       if (examineMoves<P,has_record,false,UNKNOWN>
 
  973           (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev,
 
  977       last_capture_piece = state.state().pieceOnBoard(bestmove_in_record.
to());
 
  981     state.getBigramKillerMoves(killer_moves);
 
  982     assert(moves.empty());
 
  985     BOOST_FOREACH(
Move move, killer_moves)
 
  987       if (
std::find(record_moves.begin(), record_moves.end(), move)
 
  988           == record_moves.end())
 
  989         moves.push_back(move);
 
  993     if (examineMoves<P,has_record,false,UNKNOWN>
 
  994         (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev,
 
  998     if (examineMoves<P,has_record,false,UNKNOWN>
 
  999         (record, cur_val, &*record_moves.begin(), &*record_moves.end(), alpha, beta, ev, additional_depth))
 
 1005   assert(moves.empty());
 
 1009     last_capture_piece = state.state().pieceOnBoard(last_to);
 
 1012     if (examineMoves<P,has_record,false,CAPTURE>
 
 1013         (record, cur_val, &*moves.begin(), &*moves.end(),alpha, beta, ev,
 
 1026   const bool has_threatmate
 
 1038     if (examineMoves<P,has_record,false,KING_ESCAPE>
 
 1039         (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev,
 
 1045   if (examineCapture<P,ROOK,has_record>
 
 1046       (record, cur_val, moves, alpha, beta, ev, last_capture_piece, additional_depth))
 
 1048   if (examineCapture<P,BISHOP,has_record>
 
 1049       (record, cur_val, moves, alpha, beta, ev, last_capture_piece, additional_depth))
 
 1051   if (examineCapture<P,GOLD,has_record>
 
 1052       (record, cur_val, moves, alpha, beta, ev, last_capture_piece, additional_depth))
 
 1054   if (examineCapture<P,SILVER,has_record>
 
 1055       (record, cur_val, moves, alpha, beta, ev, last_capture_piece, additional_depth))
 
 1057   if ((
depth() >= QSearch2PrivateTraits::KnightCaptureDepth)
 
 1061     if (examineCapture<P,KNIGHT,has_record>
 
 1062         (record, cur_val, moves, alpha, beta, ev, last_capture_piece, additional_depth))
 
 1064     if (examineCapture<P,LANCE,has_record>
 
 1065         (record, cur_val, moves, alpha, beta, ev, last_capture_piece, additional_depth))
 
 1070     const Move suggested = ev.suggestMove(state.state());
 
 1072       assert(state.state().isAlmostValidMove(suggested));
 
 1074       moves.push_back(suggested);
 
 1075       if (examineMoves<P,has_record,false,UNKNOWN>
 
 1076           (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev,
 
 1077            additional_depth)) {
 
 1083   const Move last2_move = state.lastMove(2);
 
 1093                                     (king_info.liberty() == 0),
 
 1098                                     (king_info.liberty() == 0));
 
 1099     if (examineMoves<P,has_record,false,CHECK>
 
 1100         (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev,
 
 1105   const Square my_king = state.state().template kingSquare<P>();
 
 1113   if ((
depth() >= QSearch2PrivateTraits::AttackPinnedDepth)
 
 1119       if (examineMoves<P,has_record,false,ATTACK>
 
 1120           (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev,
 
 1126   if ((depthFromRoot() < QSearch2PrivateTraits::DropDepthFromRoot)
 
 1128           && ((depthFromRoot() < QSearch2PrivateTraits::DropDepthFromRoot+2)
 
 1142         if (! state.state().template hasEffectAt<PlayerTraits<P>::opponent>(drop_again)
 
 1144             && state.state().pieceOnBoard(drop_again) == Piece::EMPTY()
 
 1145             && state.state().template hasPieceOnStand<BISHOP>(P))
 
 1146           moves.push_back(
Move(drop_again, 
BISHOP, P));
 
 1149       if (examineMoves<P,has_record,true,OTHER>
 
 1150           (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev,
 
 1155   if ((
depth() >= QSearch2PrivateTraits::PawnCaptureDepth)
 
 1159     if (examineCapture<P,PAWN,has_record>
 
 1160         (record, cur_val, moves, alpha, beta, ev, last_capture_piece, additional_depth))
 
 1163   if ((
depth() >= QSearch2PrivateTraits::FullPromoteDepth)
 
 1168     if (examineMoves<P,has_record,false,PROMOTE>
 
 1169         (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev, additional_depth))
 
 1177     if (examineMoves<P,has_record,false,PROMOTE>
 
 1178         (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev, additional_depth))
 
 1184     if (examineMoves<P,has_record,false,PROMOTE>
 
 1185         (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev, additional_depth))
 
 1188   if (depthFromRoot() < QSearch2PrivateTraits::EscapeDepthFromRoot)
 
 1193       if (examineMoves<P,has_record,false,ESCAPE>
 
 1194           (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev, additional_depth))
 
 1198   else if ((depthFromRoot() < QSearch2PrivateTraits::EscapeFromLastMoveDepthFromRoot)
 
 1202                && state.state().hasEffectByPiece
 
 1203                (state.state().pieceOnBoard(last_to), last2_move.
to()))
 
 1209       if (examineMoves<P,has_record,false,ESCAPE>
 
 1210           (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev, additional_depth))
 
 1214   if ((depthFromRoot() < QSearch2PrivateTraits::AttackMajorPieceDepthFromRoot)
 
 1217           && last_to.template canPromote<P>())
 
 1218       || (state.state().hasEffectAt(P, last_to)
 
 1220               template hasEffectByPtype<ROOK>(
alt(P), last_to)))
 
 1221       || ((depthFromRoot() < QSearch2PrivateTraits::AttackMajorPieceDepthFromRoot+2)
 
 1230       if (examineMoves<P,has_record,true,ATTACK>
 
 1231           (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev, additional_depth))
 
 1237       = (state.hasLastRecord(1) && state.lastRecord(1)) 
 
 1238       ? &(state.lastRecord(1)->qrecord) : 0;
 
 1239     if ((depthFromRoot() < QSearch2PrivateTraits::AttackKing8DepthFromRoot)
 
 1243              || (king_info.liberty() == 0))
 
 1244             && depthFromRoot() < 2+QSearch2PrivateTraits::AttackKing8DepthFromRoot)
 
 1250         if (examineMoves<P,has_record,false,ATTACK>
 
 1251             (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev, additional_depth))
 
 1256   if ((depthFromRoot() < QSearch2PrivateTraits::AttackGoldSilverDepthFromRoot)
 
 1263       if (examineMoves<P,has_record,false,ATTACK>
 
 1264           (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev, additional_depth))
 
 1268   if ((depthFromRoot() < QSearch2PrivateTraits::AttackKnightDepthFromRoot)
 
 1274       if (examineMoves<P,has_record,false,ATTACK>
 
 1275           (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev, additional_depth))
 
 1279   if ((
depth() >= QSearch2PrivateTraits::UtilizePromotedDepth)
 
 1284       const Piece last_piece = state.state().pieceOnBoard(last2_move.
to());
 
 1286       if (last_piece.
owner() == P)
 
 1290         if (examineMoves<P,has_record,true,OTHER>
 
 1291             (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev, additional_depth))
 
 1297   if ((depthFromRoot() < QSearch2PrivateTraits::AdvanceBishopDepthFromRoot)
 
 1303       if (examineMoves<P,has_record,true,OTHER>
 
 1304           (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev, additional_depth))
 
 1316       if (examineMoves<P,has_record,true,OTHER>
 
 1317           (record, cur_val, &*moves.begin(), &*moves.end(), alpha, beta, ev, additional_depth))
 
 1324   assert(! isWinValue(
alt(P), cur_val));
 
 1325 #ifndef DONT_USE_CHECKMATE 
 1326   const bool threatmate
 
 1328   int check_after_threatmate = 0;
 
 1331           || (check_after_threatmate = state.countCheckAfterThreatmate(
alt(P),2))))
 
 1334     int checkmate_nodes = (node_count - node_count_before)/2;
 
 1335     if (check_after_threatmate)
 
 1337       if (depthFromRoot() == 1) 
 
 1339         const int sacrifice = state.countCheckAfterThreatmateSacrifice(
alt(P),2);
 
 1340         checkmate_nodes = 
std::max(checkmate_nodes, 
 
 1341                                    sacrifice*125+check_after_threatmate*50);
 
 1345         checkmate_nodes = 
std::max(50, checkmate_nodes);
 
 1352       checkmate_nodes = 
std::max(checkmate_nodes, 200);
 
 1355     const bool win = (record && checkmate_nodes >= 50)
 
 1359           || (! has_record && threatmate))
 
 1360          ? state.isWinningStateShort<P>(2, checkmate_move)
 
 1364       const int result = base_t::winByCheckmate(P);
 
 1365       assert(checkmate_move.
isValid());
 
 1366       if (! has_record && ! record)
 
 1368       if (has_record || record) {
 
 1369         assert(state.state().isValidMove(checkmate_move));      
 
 1371                               result, checkmate_move);
 
 1382     Move checkmate_move=Move::INVALID();
 
 1383     AttackOracleAges oracle_age_dummy;
 
 1384     const bool win_found        
 
 1385       = state.isWinningState<P>
 
 1386       (0, checkmate_move, oracle_age_dummy);
 
 1389       const int result = base_t::winByCheckmate(P);
 
 1390       assert(checkmate_move.isValid());
 
 1395                               result, checkmate_move);
 
 1418     my_king = Centering3x3::adjustCenter(my_king);
 
 1419     op_king = Centering3x3::adjustCenter(op_king);
 
 1424       && ((! move.
isDrop() && state.longEffectAt(move.
from()).any())
 
 1430 template <
class EvalT>
 
 1431 template <osl::Player P>
 
 1434                 int& cur_val, 
int& alpha, 
int beta, 
eval_t const& ev)
 
 1441   const Square my_king = state.state().template kingSquare<P>();
 
 1442   const Square op_king = state.state().template kingSquare<PlayerTraits<P>::opponent>();
 
 1444   BOOST_FOREACH(
Move move, moves)
 
 1446 #ifdef QSEARCH_DEBUG 
 1447     QuiescenceLog::pushMove(
depth(), move, 0);
 
 1449     const int see = See::see(state.state(), move, state.state().pin(P), state.state().pin(
alt(P)), &eval_t::Piece_Value);
 
 1451     if (see > 0 && 
importantMove(state.state(), move, my_king, op_king)) 
 
 1456       helper_t helper(result, 
this, alpha, beta, new_ev, move);
 
 1458       state.doUndoMoveLight<P,helper_t>(move, helper);
 
 1465     if (! base_t::isWinValue(
alt(P), result))
 
 1475 template <
class EvalT>
 
 1476 template <osl::Player P, 
bool calm_move_only, 
bool first_normal_move_only>
 
 1480                  int beta1, 
int beta2, 
eval_t const& ev)
 
 1493   assert(state.state().turn() == P);
 
 1495   const Square my_king = state.state().template kingSquare<P>();
 
 1496   const Square op_king = state.state().template kingSquare<PlayerTraits<P>::opponent>();
 
 1498   int best_value = threat2.
value;
 
 1499   BOOST_FOREACH(
Move move, moves)
 
 1502     assert(! ShouldPromoteCut::canIgnoreAndNotDrop<P>(move));
 
 1504         && (state.state().countEffect(
alt(P),to) > state.state().countEffect(P,to)))
 
 1506 #ifdef QSEARCH_DEBUG 
 1507     QuiescenceLog::pushMove(
depth(), move, 0);
 
 1510     const int see = See::see(state.state(), move, state.state().pin(P), state.state().pin(
alt(P)), &eval_t::Piece_Value);
 
 1511     if (see > 0 && 
importantMove(state.state(), move, my_king, op_king)) 
 
 1517       helper_t helper(result, 
this, 
 
 1519       state.doUndoMoveLight<P,helper_t>(move, helper);
 
 1526     if (base_t::isWinValue(
alt(P), result))
 
 1549     if (first_normal_move_only)
 
 1557   assert(! moves.empty());
 
 1560   const Move threat_move = *moves.begin();
 
 1561   if (! first_normal_move_only)
 
 1563     assert(state.lastMove().isPass());
 
 1565     bool cut_by_threat2 = 
false;
 
 1569     move_generator::GenerateAddEffectWithEffect::generate<false>
 
 1570       (Opponent, state.state(), threat_move.
to(), 
moves);
 
 1575         cut_by_threat2 = 
true;
 
 1578     return cut_by_threat2;
 
 1580   else if ((depthFromRoot() < QSearch2PrivateTraits::EscapeFromLastMoveDepthFromRoot)
 
 1584     assert(state.lastMove().isPass());
 
 1586     bool cut_by_threat2 = 
false;
 
 1587     const Square to = threat_move.
to();
 
 1588     const Piece target = state.state().pieceOnBoard(to);
 
 1590       = (depthFromRoot() < QSearch2PrivateTraits::EscapeDepthFromRoot);
 
 1591 #ifdef QSEARCH_PESSIMISTIC_ESCAPE_THREAT 
 1592     if (state.lastMove().isNormal())
 
 1596       const Offset32 offset32(to, state.lastMove().to());
 
 1606       const bool safe_escape
 
 1611       BOOST_FOREACH(
Move move, escape)
 
 1614         new_ev.update(state.state(), Move::PASS(P));
 
 1621           state.doUndoMoveLight<Opponent,helper_t>(move, helper);
 
 1628           state.doUndoMoveLight<Opponent,helper_t>(move, helper);
 
 1643         cut_by_threat2 = 
true;
 
 1649     return cut_by_threat2;
 
 1654 template <
class EvalT>
 
 1655 template <osl::Player P>
 
 1660   int best_value = takeBackValue<P>(alpha, beta, ev, last_move);
 
 1668   BOOST_FOREACH(
Move move, moves)
 
 1673     helper_t helper(&state.state(), 
 
 1674                     state.state().pieceOnBoard(last_move.
to()),
 
 1676     state.doUndoMoveLight<P,helper_t>(move, helper);    
 
 1677     if (helper.is_invalid)
 
 1680     int result = new_ev.value();
 
 1681     if (! helper.has_safe_escape)
 
 1682       result += new_ev.captureValue(last_move.
ptypeO());
 
 1683     if (state.state().template hasEffectByPtype<ROOK>(P, move.from()))
 
 1692 template <
class EvalT>
 
 1693 template <osl::Player P>
 
 1702   if (state.state().inCheck(
alt(P)))
 
 1703     return base_t::winByFoul(P);
 
 1707   const Square last_to = last_move.
to();
 
 1709   const Piece last_move_piece = state.state().pieceOnBoard(last_to);
 
 1711   if (state.state().inCheck())
 
 1713     const bool check_by_lance = state.state().hasEffectByPtypeStrict<
LANCE>
 
 1714       (
alt(P), state.state().template kingSquare<P>());
 
 1715     const bool has_safe_move
 
 1717     cur_val = (has_safe_move 
 
 1718                ? currentValueWithLastThreat(ev, last_move_piece) 
 
 1719                : base_t::winByCheckmate(
alt(P)));
 
 1720     assert(cur_val % 2 == 0);
 
 1724     cur_val = currentValueWithLastThreat(ev, last_move_piece);
 
 1725     assert(cur_val % 2 == 0);
 
 1740   if (examineTakeBack<P>(moves, cur_val, alpha, beta, ev)) {
 
 1741     assert(cur_val % 2 == 0);    
 
 1746   assert(cur_val % 2 == 0);
 
 1750 template <
class EvalT>
 
 1751 template <osl::Player P>
 
 1757   assert(! state.state().inCheck());
 
 1758   const int static_value = ev.value();
 
 1760     return static_value;
 
 1762   const int FirstThreat = QSearchTraits::FirstThreat;
 
 1763   const int SecondThreat
 
 1764     = (depthFromRoot() < QSearch2PrivateTraits::EscapeDepthFromRoot)
 
 1766     : QSearchTraits::SecondThreat;
 
 1770                           static_value - FirstThreat*(static_value - alpha))
 
 1774                           static_value - SecondThreat*(static_value - alpha))
 
 1777   threat1.
value = static_value;
 
 1778   threat2.
value = static_value;
 
 1780   assert(state.state().turn() == P);
 
 1783   assert(! state.state().inCheck());
 
 1789   ev2.update(state.state(), Move::PASS(P));
 
 1792   if (generateAndExamineTakeBack2<O,ROOK>(moves, threat2, threat1, o_beta1, o_beta2, ev2))
 
 1794   if (generateAndExamineTakeBack2<O,BISHOP>(moves, threat2, threat1, o_beta1, o_beta2, ev2))
 
 1796   if (generateAndExamineTakeBack2<O,GOLD>(moves, threat2, threat1, o_beta1, o_beta2, ev2))
 
 1798   if (generateAndExamineTakeBack2<O,SILVER>(moves, threat2, threat1, o_beta1, o_beta2, ev2))
 
 1800   if (generateAndExamineTakeBack2<O,KNIGHT>(moves, threat2, threat1, o_beta1, o_beta2, ev2))
 
 1802   if (generateAndExamineTakeBack2<O,LANCE>(moves, threat2, threat1, o_beta1, o_beta2, ev2))
 
 1806   if (examineTakeBack2<O,true,false>(moves, threat2, threat1, o_beta1, o_beta2, ev2))
 
 1810   if (examineTakeBack2<O,true,false>(moves, threat2, threat1, o_beta1, o_beta2, ev2))
 
 1814   if (examineTakeBack2<O,true,false>(moves, threat2, threat1, o_beta1, o_beta2, ev2))
 
 1817   if (
depth() >= QSearch2PrivateTraits::PawnCaptureDepth 
 
 1820     if (generateAndExamineTakeBack2<O,PAWN>(moves, threat2, threat1, o_beta1, o_beta2, ev2))
 
 1829         && target.
square().template canPromote<O>()) {
 
 1831       assert(threat1.
value % 2 == 0);
 
 1832       return threat1.
value;
 
 1836   const int result1 = (static_value - (static_value - threat1.
value)/FirstThreat);
 
 1837   const int result2 = (static_value - (static_value - threat2.
value)/SecondThreat);
 
 1840   assert(result % 2 == 0);