3 #ifndef OSL_CHECKMATE_FIXED_DEPTH_SERCHER2_TCC
4 #define OSL_CHECKMATE_FIXED_DEPTH_SERCHER2_TCC
20 #include <boost/foreach.hpp>
22 template <osl::Player P,
bool SetPieces,
bool HasGu
ide>
28 assert(state->turn() == P);
30 = state->template kingSquare<PlayerTraits<P>::opponent>();
31 if (state->hasEffectAt<P>(target_king))
33 return attack<P,SetPieces,HasGuide>(
depth, best_move, proof_pieces);
36 template <osl::Player P,
bool SetPieces,
bool HasGu
ide>
41 NumEffectState* state= &states[
depth];
42 assert(state->turn() == P);
44 || (state->isAlmostValidMove(best_move)
50 = state->template kingSquare<PlayerTraits<P>::opponent>();
51 assert(! state->hasEffectAt<P>(target_king));
53 if ((! state->inCheck())
54 && ImmediateCheckmate::hasCheckmateMove<P>(*state, info, target_king,
75 states[depth-1].copyFrom(states[depth]);
76 states[depth-1].makeMove(best_move);
77 pdp=defense<P,SetPieces>(best_move,depth-1,proof_pieces);
84 minProof = pdp.
proof();
89 = state->template kingSquare<PlayerTraits<P>::opponent>();
91 bool has_pawn_checkmate=
false;
92 move_generator::GenerateAddEffectWithEffect::generate<true>
93 (P,*state,targetKing,
moves,has_pawn_checkmate);
96 if(has_pawn_checkmate)
101 if(has_pawn_checkmate)
103 BOOST_FOREACH(
Move move, moves) {
104 if (HasGuide && move == best_move)
106 states[depth-1].copyFrom(states[depth]);
107 states[depth-1].makeMove(move);
108 pdp=defense<P,SetPieces>(move,depth-1,proof_pieces);
109 int proof=pdp.
proof();
127 template <osl::Player P,
bool SetPieces>
132 Piece attacker_piece,
Square target_position)
const
134 const NumEffectState* state= &states[
depth];
135 assert(state->turn() ==
alt(P));
147 count += state->countEffect(
alt(P), attack_from);
152 attack_from, target_position);
172 template <osl::Player Defense>
175 MoveVector&
moves)
const
177 const NumEffectState* state= &states[
depth];
178 assert(state->kingPiece(Defense) == defense_king);
179 using namespace move_generator;
180 using namespace move_action;
181 MoveVector all_moves;
183 Store
store(all_moves);
185 generateBlockingKing<Defense,false>(*state, defense_king, attack_from,
store);
187 BOOST_FOREACH(
Move move, all_moves)
191 if (! state->hasEffectAt<Defense>(move.
to()))
199 if (! state->hasMultipleEffectAt(Defense, move.
to()))
203 moves.push_back(move);
207 template <osl::Player Defense>
inline
215 template <osl::Player P,
bool SetPieces>
220 NumEffectState* state= &states[
depth];
221 assert(state->turn() ==
alt(P));
225 = state->template kingSquare<P>();
229 if (attackerKing.
isOnBoard() && state->hasEffectAt<Defense>(attackerKing))
231 const Piece target_king
232 = state->template kingPiece<Defense>();
234 assert(state->hasEffectAt<P>(target_position));
235 Piece attacker_piece;
236 state->template findCheckPiece<Defense>(attacker_piece);
239 return defenseEstimation<P, SetPieces>
240 (
depth,last_move, proof_pieces, attacker_piece, target_position);
245 bool blockable_check =
false;
248 using namespace move_generator;
249 using namespace move_action;
250 if (attacker_piece.
isEmpty()) {
253 Escape<Store>::template
254 generateEscape<Defense,KING>(*state,target_king,
store);
256 nonblock_moves = moves.size();
263 generateCaptureKing<Defense>(*state, target_king, attack_from,
store);
265 const int num_captures = moves.size();
268 Escape<Store>::template
269 generateEscape<Defense,KING>(*state, target_king,
store);
271 nonblock_moves = moves.size();
274 if ((depth <= 1) && num_captures && (nonblock_moves > 2))
276 if (nonblock_moves > 3)
278 const int block_estimate = blockable_check
279 ? blockEstimation<Defense>(attack_from, target_position)
285 generateBlockingWhenLiberty0<Defense>(depth,target_king, attack_from, moves);
298 const bool cut_candidate = (depth <= 1)
299 && (nonblock_moves - (state->hasPieceOnStand<
GOLD>(P)
300 || state->hasPieceOnStand<
SILVER>(P)) > 4);
312 for (;i<moves.size();i++){
313 states[depth-1].copyFrom(states[depth]);
314 states[depth-1].makeMove(moves[i]);
315 pdp=attack<P,SetPieces,false>(depth-1, moves[i], child_proof);
316 const int disproof=pdp.disproof();
317 if (disproof<minDisproof){
322 minDisproof=disproof;
324 sumProof+=pdp.proof();
328 proof_pieces = proof_pieces.
max(child_proof);
332 if (i+1 < moves.size())
335 if ((
int)i < nonblock_moves)
336 sumProof += nonblock_moves - (i+1);
343 if ((sumProof == 0) && blockable_check
344 && ((
int)moves.size() == nonblock_moves))
346 using namespace move_generator;
347 using namespace move_action;
352 generateBlockingKing<Defense,false>(*state, target_king, attack_from,
store);
354 if ((
int)moves.size() > nonblock_moves)
358 if (SetPieces && (sumProof == 0) && blockable_check)
366 template <osl::Player P>
374 states[depth-1].copyFrom(states[depth]);
375 states[depth-1].makeMove(next_move);
376 pdp=attackMayUnsafe<P,true,false>(depth-1, check_move, proof_pieces);
380 template <osl::Player P>
387 states[depth-1].copyFrom(states[depth]);
388 states[depth-1].makeMove(next_move);
389 pdp=attack<P,false,false>(depth-1, next_move, proof_pieces);
393 template <osl::Player P>
398 NumEffectState* state= &states[
depth];
402 const Piece p=state->pieceOnBoard(guide.
to());
406 if (state->template isAlmostValidMove<false>(guide)
408 ::isMember(*state, guide.
ptype(), guide.
from(), guide.
to()))
409 return attack<P,true,true>(
depth, guide, proof_pieces);
410 return attack<P,true,false>(
depth, guide, proof_pieces);