checkmateIfCapture.cc Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
checkmateIfCapture.cc
Go to the documentation of this file.
1 /* checkmateIfCapture.cc
2 */
3 #include "osl/checkmate/checkmateIfCapture.h"
4 #include "osl/checkmate/fixedDepthSearcher.h"
5 #include "osl/checkmate/king8Info.h"
6 #include "osl/checkmate/immediateCheckmate.h"
7 #include "osl/effect_util/effectUtil.h"
8 #include "osl/effect_util/neighboring8Direct.h"
9 #include "osl/move_generator/capture_.h"
10 #include "osl/move_action/store.h"
11 #include "osl/move_classifier/moveAdaptor.h"
12 #include "osl/move_classifier/openCheck.h"
13 #include "osl/neighboring8.h"
14
15 struct osl::checkmate::CheckmateIfCapture::CallDefense
16 {
17 NumEffectState *state;
18 int depth;
19 bool result;
20 void operator()(Square last_to)
21 {
22 result = cannotCapture(*state, last_to, depth);
23 }
24 };
25
26 bool osl::checkmate::
27 CheckmateIfCapture::effectiveAttackCandidate0(const NumEffectState& state, Move move)
28 {
29 using namespace move_classifier;
30 // depth 0 専用の枝刈
31 const Player attacker = state.turn();
32 const Player defender = alt(attacker);
33 const Square king = state.kingSquare(defender);
34 PieceMask pieces = state.effectSetAt(move.to())
35 & state.piecesOnBoard(defender);
36 if (pieces.none())
37 return false;
38 if (Neighboring8::isNeighboring8(move.to(), king))
39 return true;
40 const Piece captured = state.pieceOnBoard(move.to());
41 if (move.isCapture()) {
42 if (Neighboring8Direct::hasEffect(state, captured.ptypeO(),
43 move.to(), king))
44 return true;
45 }
46 if (! move.isDrop()
47 && (state.longEffectAt(move.from(), attacker).any() // todo: refinement 開き王手pinとか8近傍くらい?
48 || (Neighboring8::isNeighboring8(move.from(), king)
49 && state.hasEffectAt(attacker, move.from()))))
50 return true;
51
52 const King8Info info = state.king8Info(defender);
53 const CArray<Square,2> knight_position = {{
54 Board_Table.nextSquare(defender, king, UUR),
55 Board_Table.nextSquare(defender, king, UUL)
56 }};
57 if (state.inCheck()
58 && (info.dropCandidate() || info.moveCandidate2()
59 || /* only when has knight or knight effect */info.liberty() == 0))
60 return true;
61 if (move.isCapture()) {
62 if (info.dropCandidate())
63 return true;
64 if (info.liberty() == 0) {
65 for (int i=0; i<2; ++i) {
66 const Square kp = knight_position[i];
67 const Piece kpp = state.pieceAt(kp);
68 if (kpp.isEdge() || state.hasEffectNotBy(defender, captured, kp))
69 continue;
70 if (kpp.isEmpty()
71 && unpromote(move.capturePtype()) == KNIGHT)
72 return true;
73 if (state.hasEffectByPiece(captured, kp)
74 && (unpromote(move.capturePtype()) == KNIGHT
75 || state.hasPieceOnStand<KNIGHT>(attacker)
76 || state.hasEffectByPtypeStrict<KNIGHT>(attacker, kp)))
77 return true;
78 }
79 }
80 } else if (info.liberty() == 0 && state.hasPieceOnStand<KNIGHT>(attacker)) {
81 for (int i=0; i<2; ++i) {
82 const Square kp = knight_position[i];
83 const Piece kpp = state.pieceAt(kp);
84 if (! kpp.isOnBoardByOwner(defender))
85 continue;
86 if (state.hasEffectByPiece(kpp, move.to()))
87 return true;
88 }
89 }
90 // テストでは出てこないが焦点もあるか?
91 while (pieces.any())
92 {
93 const Piece p=state.pieceOf(pieces.takeOneBit());
94 if (Neighboring8Direct::hasEffectOrAdditional(state, p.ptypeO(), p.square(), king)
95 || Neighboring8::isNeighboring8(p.square(), king))
96 continue; // i.e., need analyses
97 if (state.longEffectAt(p.square(), attacker).any()) // todo: refinement
98 continue;
99 if (info.liberty() == 0) {
100 int i=0;
101 for (; i<2; ++i) {
102 const Square kp = knight_position[i];
103 const Piece kpp = state.pieceAt(kp);
104 if (kpp.isEdge() || state.hasEffectNotBy(defender, p, kp))
105 continue;
106 if (p.square() == kp
107 && state.hasPieceOnStand<KNIGHT>(attacker))
108 break;
109 if (state.countEffect(defender, kp) == 1)
110 if ((kpp.canMoveOn(attacker)
111 && state.hasEffectByPtypeStrict<KNIGHT>(attacker, kp))
112 || (kpp.isEmpty()
113 && state.hasPieceOnStand<KNIGHT>(attacker)))
114 break;
115 }
116 if (i<2)
117 continue;
118 }
119 // now we have safe takeback
120 return false;
121 }
122 return true;
123 }
124
125 bool osl::checkmate::
126 CheckmateIfCapture::effectiveAttack(NumEffectState& state, Move move, int depth)
127 {
128 assert(move.player() == state.turn());
129 CallDefense defense = { &state, depth, false };
130 state.makeUnmakeMove(move, defense);
131 #ifdef OSL_DEBUG
132 if (defense.result && ! effectiveAttackCandidate0(state, move))
133 std::cerr << state << move << "\n", assert(0);
134 #endif
135 return defense.result;
136 }
137
138 bool osl::checkmate::
139 CheckmateIfCapture::cannotCapture(NumEffectState& state,
140 Square last_to, int depth)
141 {
142 if (state.inCheck(alt(state.turn())))
143 return false; // 前の手が自殺
144
145 using namespace move_generator;
146 using namespace move_action;
147 MoveVector moves; // may contain unsafe move
148 GenerateCapture::generate(state, last_to, moves);
149
150 if (moves.empty())
151 return false;
152
153 FixedDepthSearcher searcher(state);
154 const Square king = state.kingSquare(state.turn());
155 for (MoveVector::const_iterator p=moves.begin(); p!=moves.end(); ++p)
156 {
157 if (state.inCheck()) {
158 if (state.countEffect(alt(state.turn()), king) > 1
159 || ! state.hasEffectByPiece(state.pieceOnBoard(last_to), king))
160 if (p->ptype() != KING)
161 continue;
162 }
163 const bool checkmate
164 = searcher.hasEscapeByMoveOfTurn(*p, depth).isCheckmateSuccess();
165 if (! checkmate)
166 return false;
167 }
168
169 return true;
170 }
171
172 /* ------------------------------------------------------------------------- */
173 // ;;; Local Variables:
174 // ;;; mode:c++
175 // ;;; c-basic-offset:2
176 // ;;; End: