説明を見る。00001
00002
00003 #include "osl/checkmate/checkmateIfCapture.h"
00004 #include "osl/checkmate/fixedDepthSearcher.h"
00005 #include "osl/checkmate/immediateCheckmate.h"
00006 #include "osl/move_generator/capture_.h"
00007 #include "osl/effect_util/neighboring8Direct.h"
00008
00009 struct osl::checkmate::CheckmateIfCapture::CallDefense
00010 {
00011 NumEffectState *state;
00012 int depth;
00013 bool result;
00014 void operator()(Square last_to)
00015 {
00016 result = cannotCapture(*state, last_to, depth);
00017 }
00018 };
00019
00020 bool osl::checkmate::
00021 CheckmateIfCapture::effectiveAttackCandidate0(const NumEffectState& state, Move move)
00022 {
00023 using namespace move_classifier;
00024
00025 const Player attacker = state.turn();
00026 const Player defender = alt(attacker);
00027 const Square king = state.kingSquare(defender);
00028 PieceMask pieces = state.effectSetAt(move.to())
00029 & state.piecesOnBoard(defender);
00030 if (pieces.none())
00031 return false;
00032 if (move.to().isNeighboring8(king))
00033 return true;
00034 const Piece captured = state.pieceOnBoard(move.to());
00035 if (move.isCapture()) {
00036 if (Neighboring8Direct::hasEffect(state, captured.ptypeO(),
00037 move.to(), king))
00038 return true;
00039 }
00040 if (! move.isDrop()
00041 && (state.longEffectAt(move.from(), attacker).any()
00042 || (move.from().isNeighboring8(king)
00043 && state.hasEffectAt(attacker, move.from()))))
00044 return true;
00045
00046 const King8Info info = state.king8Info(defender);
00047 const CArray<Square,2> knight_position = {{
00048 Board_Table.nextSquare(defender, king, UUR),
00049 Board_Table.nextSquare(defender, king, UUL)
00050 }};
00051 if (state.inCheck()
00052 && (info.dropCandidate() || info.moveCandidate2()
00053 || info.liberty() == 0))
00054 return true;
00055 if (move.isCapture()) {
00056 if (info.dropCandidate())
00057 return true;
00058 if (info.liberty() == 0) {
00059 for (int i=0; i<2; ++i) {
00060 const Square kp = knight_position[i];
00061 const Piece kpp = state.pieceAt(kp);
00062 if (kpp.isEdge() || state.hasEffectNotBy(defender, captured, kp))
00063 continue;
00064 if (kpp.isEmpty()
00065 && unpromote(move.capturePtype()) == KNIGHT)
00066 return true;
00067 if (state.hasEffectByPiece(captured, kp)
00068 && (unpromote(move.capturePtype()) == KNIGHT
00069 || state.hasPieceOnStand<KNIGHT>(attacker)
00070 || state.hasEffectByPtypeStrict<KNIGHT>(attacker, kp)))
00071 return true;
00072 }
00073 }
00074 } else if (info.liberty() == 0 && state.hasPieceOnStand<KNIGHT>(attacker)) {
00075 for (int i=0; i<2; ++i) {
00076 const Square kp = knight_position[i];
00077 const Piece kpp = state.pieceAt(kp);
00078 if (! kpp.isOnBoardByOwner(defender))
00079 continue;
00080 if (state.hasEffectByPiece(kpp, move.to()))
00081 return true;
00082 }
00083 }
00084
00085 while (pieces.any())
00086 {
00087 const Piece p=state.pieceOf(pieces.takeOneBit());
00088 if (Neighboring8Direct::hasEffectOrAdditional(state, p.ptypeO(), p.square(), king)
00089 || p.square().isNeighboring8(king))
00090 continue;
00091 if (state.longEffectAt(p.square(), attacker).any())
00092 continue;
00093 if (info.liberty() == 0) {
00094 int i=0;
00095 for (; i<2; ++i) {
00096 const Square kp = knight_position[i];
00097 const Piece kpp = state.pieceAt(kp);
00098 if (kpp.isEdge() || state.hasEffectNotBy(defender, p, kp))
00099 continue;
00100 if (p.square() == kp
00101 && state.hasPieceOnStand<KNIGHT>(attacker))
00102 break;
00103 if (state.countEffect(defender, kp) == 1)
00104 if ((kpp.canMoveOn(attacker)
00105 && state.hasEffectByPtypeStrict<KNIGHT>(attacker, kp))
00106 || (kpp.isEmpty()
00107 && state.hasPieceOnStand<KNIGHT>(attacker)))
00108 break;
00109 }
00110 if (i<2)
00111 continue;
00112 }
00113
00114 return false;
00115 }
00116 return true;
00117 }
00118
00119 bool osl::checkmate::
00120 CheckmateIfCapture::effectiveAttack(NumEffectState& state, Move move, int depth)
00121 {
00122 assert(move.player() == state.turn());
00123 CallDefense defense = { &state, depth, false };
00124 state.makeUnmakeMove(move, defense);
00125 #ifdef OSL_DEBUG
00126 if (defense.result && ! effectiveAttackCandidate0(state, move))
00127 std::cerr << state << move << "\n", assert(0);
00128 #endif
00129 return defense.result;
00130 }
00131
00132 bool osl::checkmate::
00133 CheckmateIfCapture::cannotCapture(NumEffectState& state,
00134 Square last_to, int depth)
00135 {
00136 if (state.inCheck(alt(state.turn())))
00137 return false;
00138
00139 using namespace move_generator;
00140 using namespace move_action;
00141 MoveVector moves;
00142 GenerateCapture::generate(state, last_to, moves);
00143
00144 if (moves.empty())
00145 return false;
00146
00147 FixedDepthSearcher searcher(state);
00148 const Square king = state.kingSquare(state.turn());
00149 for (MoveVector::const_iterator p=moves.begin(); p!=moves.end(); ++p)
00150 {
00151 if (state.inCheck()) {
00152 if (state.countEffect(alt(state.turn()), king) > 1
00153 || ! state.hasEffectByPiece(state.pieceOnBoard(last_to), king))
00154 if (p->ptype() != KING)
00155 continue;
00156 }
00157 const bool checkmate
00158 = searcher.hasEscapeByMoveOfTurn(*p, depth).isCheckmateSuccess();
00159 if (! checkmate)
00160 return false;
00161 }
00162
00163 return true;
00164 }
00165
00166
00167
00168
00169
00170