My Project
checkmateIfCapture.cc
Go to the documentation of this file.
1/* checkmateIfCapture.cc
2 */
8
19
22{
23 using namespace move_classifier;
24 // depth 0 専用の枝刈
25 const Player attacker = state.turn();
26 const Player defender = alt(attacker);
27 const Square king = state.kingSquare(defender);
28 PieceMask pieces = state.effectSetAt(move.to())
29 & state.piecesOnBoard(defender);
30 if (pieces.none())
31 return false;
32 if (move.to().isNeighboring8(king))
33 return true;
34 const Piece captured = state.pieceOnBoard(move.to());
35 if (move.isCapture()) {
36 if (Neighboring8Direct::hasEffect(state, captured.ptypeO(),
37 move.to(), king))
38 return true;
39 }
40 if (! move.isDrop()
41 && (state.longEffectAt(move.from(), attacker).any() // todo: refinement 開き王手pinとか8近傍くらい?
42 || (move.from().isNeighboring8(king)
43 && state.hasEffectAt(attacker, move.from()))))
44 return true;
45
46 const King8Info info = state.king8Info(defender);
47 const CArray<Square,2> knight_position = {{
48 Board_Table.nextSquare(defender, king, UUR),
49 Board_Table.nextSquare(defender, king, UUL)
50 }};
51 if (state.inCheck()
52 && (info.dropCandidate() || info.moveCandidate2()
53 || /* only when has knight or knight effect */info.liberty() == 0))
54 return true;
55 if (move.isCapture()) {
56 if (info.dropCandidate())
57 return true;
58 if (info.liberty() == 0) {
59 for (int i=0; i<2; ++i) {
60 const Square kp = knight_position[i];
61 const Piece kpp = state.pieceAt(kp);
62 if (kpp.isEdge() || state.hasEffectNotBy(defender, captured, kp))
63 continue;
64 if (kpp.isEmpty()
65 && unpromote(move.capturePtype()) == KNIGHT)
66 return true;
67 if (state.hasEffectByPiece(captured, kp)
68 && (unpromote(move.capturePtype()) == KNIGHT
69 || state.hasPieceOnStand<KNIGHT>(attacker)
70 || state.hasEffectByPtypeStrict<KNIGHT>(attacker, kp)))
71 return true;
72 }
73 }
74 } else if (info.liberty() == 0 && state.hasPieceOnStand<KNIGHT>(attacker)) {
75 for (int i=0; i<2; ++i) {
76 const Square kp = knight_position[i];
77 const Piece kpp = state.pieceAt(kp);
78 if (! kpp.isOnBoardByOwner(defender))
79 continue;
80 if (state.hasEffectByPiece(kpp, move.to()))
81 return true;
82 }
83 }
84 // テストでは出てこないが焦点もあるか?
85 while (pieces.any())
86 {
87 const Piece p=state.pieceOf(pieces.takeOneBit());
88 if (Neighboring8Direct::hasEffectOrAdditional(state, p.ptypeO(), p.square(), king)
89 || p.square().isNeighboring8(king))
90 continue; // i.e., need analyses
91 if (state.longEffectAt(p.square(), attacker).any()) // todo: refinement
92 continue;
93 if (info.liberty() == 0) {
94 int i=0;
95 for (; i<2; ++i) {
96 const Square kp = knight_position[i];
97 const Piece kpp = state.pieceAt(kp);
98 if (kpp.isEdge() || state.hasEffectNotBy(defender, p, kp))
99 continue;
100 if (p.square() == kp
101 && state.hasPieceOnStand<KNIGHT>(attacker))
102 break;
103 if (state.countEffect(defender, kp) == 1)
104 if ((kpp.canMoveOn(attacker)
105 && state.hasEffectByPtypeStrict<KNIGHT>(attacker, kp))
106 || (kpp.isEmpty()
107 && state.hasPieceOnStand<KNIGHT>(attacker)))
108 break;
109 }
110 if (i<2)
111 continue;
112 }
113 // now we have safe takeback
114 return false;
115 }
116 return true;
117}
118
121{
122 assert(move.player() == state.turn());
123 CallDefense defense = { &state, depth, false };
124 state.makeUnmakeMove(move, defense);
125#ifdef OSL_DEBUG
126 if (defense.result && ! effectiveAttackCandidate0(state, move))
127 std::cerr << state << move << "\n", assert(0);
128#endif
129 return defense.result;
130}
131
134 Square last_to, int depth)
135{
136 if (state.inCheck(alt(state.turn())))
137 return false; // 前の手が自殺
138
139 using namespace move_generator;
140 using namespace move_action;
141 MoveVector moves; // may contain unsafe move
142 GenerateCapture::generate(state, last_to, moves);
143
144 if (moves.empty())
145 return false;
146
147 FixedDepthSearcher searcher(state);
148 const Square king = state.kingSquare(state.turn());
149 for (MoveVector::const_iterator p=moves.begin(); p!=moves.end(); ++p)
150 {
151 if (state.inCheck()) {
152 if (state.countEffect(alt(state.turn()), king) > 1
153 || ! state.hasEffectByPiece(state.pieceOnBoard(last_to), king))
154 if (p->ptype() != KING)
155 continue;
156 }
157 const bool checkmate
158 = searcher.hasEscapeByMoveOfTurn(*p, depth).isCheckmateSuccess();
159 if (! checkmate)
160 return false;
161 }
162
163 return true;
164}
165
166/* ------------------------------------------------------------------------- */
167// ;;; Local Variables:
168// ;;; mode:c++
169// ;;; c-basic-offset:2
170// ;;; End:
const Square nextSquare(Player P, Square pos, Direction dr) const
next position from pos for player P.
Definition boardTable.h:61
圧縮していない moveの表現 .
Player player() const
bool isDrop() const
Ptype capturePtype() const
bool isCapture() const
const Square to() const
const Square from() const
利きを持つ局面
const NumBitmapEffect effectSetAt(Square sq) const
const checkmate::King8Info king8Info(Player king) const
bool hasEffectNotBy(Player player, Piece piece, Square target) const
対象とするマスにあるプレイヤーの(ただしある駒以外)利きがあるかどうか.
int countEffect(Player player, Square target) const
利きの数を数える.
bool hasEffectByPiece(Piece attack, Square target) const
駒attack が target に利きを持つか (旧hasEffectToと統合)
bool hasEffectAt(Square target) const
対象とするマスにあるプレイヤーの利きがあるかどうか.
bool inCheck(Player P) const
Pの玉が王手状態
const mask_t longEffectAt(Square target) const
void makeUnmakeMove(Move move, Function &f)
const PieceMask & piecesOnBoard(Player p) const
bool hasEffectByPtypeStrict(Player attack, Square target) const
target に ptype の利きがあるか? 成不成を区別
駒番号のビットセット.
Definition pieceMask.h:21
bool any() const
Definition pieceMask.h:57
PtypeO ptypeO() const
Definition basic_type.h:824
const Square square() const
Definition basic_type.h:832
bool isEmpty() const
Definition basic_type.h:913
bool isEdge() const
Definition basic_type.h:919
bool canMoveOn() const
Player Pの駒が,thisの上に移動できるか? PIECE_EMPTY 0x00008000 BLACK_PIECE 0x000XxxYY X>=2, YY>0 PIECE_EDGE 0xfff1...
Definition basic_type.h:980
bool isOnBoardByOwner() const
piece がプレイヤーPの持ち物でかつボード上にある駒の場合は true.
Definition basic_type.h:852
const Piece pieceOnBoard(Square sq) const
bool hasPieceOnStand(Player player, Ptype ptype) const
Player turn() const
const Piece pieceOf(int num) const
Definition simpleState.h:76
Square kingSquare() const
Definition simpleState.h:94
const Piece pieceAt(Square sq) const
bool isNeighboring8(Square to) const
深さ固定で,その深さまで depth first searchで読む詰将棋.
const ProofDisproof hasEscapeByMoveOfTurn(Move next_move, int depth)
敵玉の8近傍の状態を表す.
Definition king8Info.h:29
unsigned int liberty() const
8-15 bit 目を 0-7bitにshiftして返す
Definition king8Info.h:54
unsigned int moveCandidate2() const
24-31 bit 目を 0-7bitにshiftして返す
Definition king8Info.h:69
unsigned int dropCandidate() const
0-7 bit 目を返す
Definition king8Info.h:49
@ KING
Definition basic_type.h:93
@ KNIGHT
Definition basic_type.h:97
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に,promote前の型を返す. promoteしていない型の時はそのまま返す
Definition basic_type.h:157
const BoardTable Board_Table
Definition tables.cc:95
@ UUR
Definition basic_type.h:323
@ UUL
Definition basic_type.h:322
Player
Definition basic_type.h:8
constexpr Player alt(Player player)
Definition basic_type.h:13
PtypeO captured(PtypeO ptypeO)
unpromoteすると共に,ownerを反転する.
Definition basic_type.h:264
static bool cannotCapture(NumEffectState &state, Square last_to, int depth)
手番の側がSquare の駒を取っても詰みがないか.
static bool effectiveAttackCandidate0(const NumEffectState &state, Move move)
depth==0でeffectiveAttackになる可能性がなければfalse
static bool effectiveAttack(NumEffectState &state, Move move, int depth)
move を指した後,alt(move.player())が取ると詰みかどうか.