3 #ifndef OSL_CHECKMATE_FIXED_DEPTH_SERCHER_TCC
4 #define OSL_CHECKMATE_FIXED_DEPTH_SERCHER_TCC
20 #include <boost/foreach.hpp>
26 template<Player P,
bool SetPieces>
47 template<Player P,
bool SetPieces,
bool MayUnsafe=false>
70 template <osl::Player P,
bool SetPieces,
bool HasGu
ide>
75 assert(
state->turn() == P);
77 =
state->template kingSquare<PlayerTraits<P>::opponent>();
78 if (
state->hasEffectAt<P>(target_king))
80 return attack<P,SetPieces,HasGuide>(
depth, best_move, proof_pieces);
83 template <osl::Player P,
bool SetPieces,
bool HasGu
ide>
88 assert(state->turn() == P);
90 || (state->isAlmostValidMove(best_move)
96 = state->template kingSquare<PlayerTraits<P>::opponent>();
97 assert(! state->hasEffectAt<P>(target_king));
99 if ((! state->inCheck())
100 && ImmediateCheckmate::hasCheckmateMove<P>(*state, info, target_king,
107 proof_pieces.
add(best_move.
ptype());
120 helper_t helper(*
this,depth,pdp,proof_pieces);
125 helper.move=best_move;
126 state->makeUnmakeMove(Player2Type<P>(),best_move,helper);
133 minProof = pdp.
proof();
138 = state->template kingSquare<PlayerTraits<P>::opponent>();
140 bool has_pawn_checkmate=
false;
144 (*state,targetKing,
store,has_pawn_checkmate);
146 if (moves.size()==0){
147 if(has_pawn_checkmate)
152 if(has_pawn_checkmate)
154 BOOST_FOREACH(
Move move, moves) {
155 if (HasGuide && move == best_move)
158 state->makeUnmakeMove(Player2Type<P>(), move,helper);
159 int proof=pdp.
proof();
177 template <osl::Player P,
bool SetPieces>
182 Piece attacker_piece,
Square target_position)
const
184 assert(state->turn() ==
alt(P));
196 count += state->countEffect(
alt(P), attack_from);
201 attack_from, target_position);
221 template <osl::Player Defense>
226 assert(state->kingPiece(Defense) == defense_king);
227 using namespace move_generator;
228 using namespace move_action;
231 Store
store(all_moves);
233 generateBlockingKing<Defense,false>(*state, defense_king, attack_from,
store);
236 BOOST_FOREACH(
Move move, all_moves)
240 if (! state->hasEffectAt<Defense>(move.
to()))
248 if (! state->hasMultipleEffectAt(Defense, move.
to()))
252 moves.push_back(move);
256 template <osl::Player Defense>
inline
264 template <osl::Player P,
bool SetPieces>
269 assert(state->turn() ==
alt(P));
273 = state->template kingSquare<P>();
277 if (attackerKing.
isOnBoard() && state->hasEffectAt<Defense>(attackerKing))
279 const Piece target_king
280 = state->template kingPiece<Defense>();
282 assert(state->hasEffectAt<P>(target_position));
283 Piece attacker_piece;
284 state->template findCheckPiece<Defense>(attacker_piece);
287 return defenseEstimation<P, SetPieces>
288 (last_move, proof_pieces, attacker_piece, target_position);
293 bool blockable_check =
false;
296 using namespace move_generator;
297 using namespace move_action;
298 if (attacker_piece.
isEmpty()) {
300 Escape<Store>::template
301 generateEscape<Defense,KING>(*state,target_king,
store);
302 nonblock_moves = moves.size();
309 generateCaptureKing<Defense>(*state, target_king, attack_from,
store);
311 const int num_captures = moves.size();
314 Escape<Store>::template
315 generateEscape<Defense,KING>(*state, target_king,
store);
317 nonblock_moves = moves.size();
320 if ((depth <= 1) && num_captures && (nonblock_moves > 2))
322 if (nonblock_moves > 3)
324 const int block_estimate = blockable_check
325 ? blockEstimation<Defense>(attack_from, target_position)
331 generateBlockingWhenLiberty0<Defense>(target_king, attack_from, moves);
334 const size_t initial_moves = moves.size();
335 if (moves.empty() && !blockable_check) {
344 const bool cut_candidate = (depth <= 1)
345 && (nonblock_moves - (state->hasPieceOnStand<
GOLD>(P)
346 || state->hasPieceOnStand<
SILVER>(P)) > 4);
355 helper_t helper(*
this, depth, pdp, child_proof);
358 size_t i=0, no_promote_moves=0;
360 for (;i<moves.size();i++){
362 const int disproof=pdp.disproof();
363 if (disproof<minDisproof){
368 minDisproof=disproof;
370 sumProof+=pdp.proof();
374 proof_pieces = proof_pieces.
max(child_proof);
378 if (i+1 < moves.size())
381 if ((
int)i < nonblock_moves)
382 sumProof += nonblock_moves - (i+1);
391 if (blockable_check && moves.size() == initial_moves)
393 using namespace move_generator;
394 using namespace move_action;
399 generateBlockingKing<Defense,false>(*state, target_king, attack_from,
store);
401 if ((
int)moves.size() > nonblock_moves)
410 if (no_promote_moves == 0)
412 no_promote_moves = moves.size();
413 for (
size_t i=0; i<no_promote_moves; ++i)
414 if (moves[i].hasIgnoredUnpromote<Defense>())
416 if (moves.size() > no_promote_moves)
419 if (SetPieces && blockable_check)
426 template <osl::Player P>
435 helper_t helper(*
this, depth+1, pdp, proof_pieces);
437 check_move = helper.best_move;
441 template <osl::Player P>
449 helper_t helper(*
this, depth+1, pdp, proof_pieces);
454 template <osl::Player P>
462 const Piece p=state->pieceOnBoard(guide.
to());
466 if (state->template isAlmostValidMove<false>(guide)
468 ::isMember(*state, guide.
ptype(), guide.
from(), guide.
to()))
469 return attack<P,true,true>(
depth, guide, proof_pieces);
470 return attack<P,true,false>(
depth, guide, proof_pieces);