checkmateIfCapture.cc
Go to the documentation of this file.
1 /* checkmateIfCapture.cc
2  */
8 
10 {
12  int depth;
13  bool result;
14  void operator()(Square last_to)
15  {
16  result = cannotCapture(*state, last_to, depth);
17  }
18 };
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());
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 
119 bool osl::checkmate::
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 
132 bool osl::checkmate::
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:
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に,promote前の型を返す. promoteしていない型の時はそのまま返す ...
Definition: basic_type.h:157
int countEffect(Player player, Square target) const
利きの数を数える.
bool isOnBoardByOwner() const
piece がプレイヤーPの持ち物でかつボード上にある駒の場合は true.
Definition: basic_type.h:852
深さ固定で,その深さまで depth first searchで読む詰将棋.
bool hasEffectAt(Square target) const
対象とするマスにあるプレイヤーの利きがあるかどうか.
bool canMoveOn() const
Player Pの駒が,thisの上に移動できるか? PIECE_EMPTY 0x00008000 BLACK_PIECE 0x000XxxYY X>=2...
Definition: basic_type.h:980
constexpr Player alt(Player player)
Definition: basic_type.h:13
void makeUnmakeMove(Move move, Function &f)
const Piece pieceAt(Square sq) const
Definition: simpleState.h:167
PtypeO ptypeO() const
Definition: basic_type.h:824
const Piece pieceOnBoard(Square sq) const
Definition: simpleState.h:170
bool hasEffectByPiece(Piece attack, Square target) const
駒attack が target に利きを持つか (旧hasEffectToと統合)
static bool effectiveAttackCandidate0(const NumEffectState &state, Move move)
depth==0でeffectiveAttackになる可能性がなければfalse
const Piece pieceOf(int num) const
Definition: simpleState.h:76
Square kingSquare() const
Definition: simpleState.h:94
const mask_t longEffectAt(Square target) const
const Square from() const
Definition: basic_type.h:1125
bool isNeighboring8(Square to) const
Definition: basic_type.cc:202
圧縮していない moveの表現 .
Definition: basic_type.h:1051
bool hasPieceOnStand(Player player, Ptype ptype) const
Definition: simpleState.h:191
const NumBitmapEffect effectSetAt(Square sq) const
駒番号のビットセット.
Definition: pieceMask.h:20
敵玉の8近傍の状態を表す.
Definition: king8Info.h:28
static void generate(Player p, const NumEffectState &state, Square target, Action &action)
Definition: capture_.h:49
static bool cannotCapture(NumEffectState &state, Square last_to, int depth)
手番の側がSquare の駒を取っても詰みがないか.
unsigned int dropCandidate() const
0-7 bit 目を返す
Definition: king8Info.h:49
Player player() const
Definition: basic_type.h:1195
Player turn() const
Definition: simpleState.h:220
static bool hasEffect(const NumEffectState &state, PtypeO ptypeo, Square from, Square target)
ptypeo の駒がfromからtargetの8近傍に直接の利きを持つか
unsigned int liberty() const
8-15 bit 目を 0-7bitにshiftして返す
Definition: king8Info.h:54
bool isEdge() const
Definition: basic_type.h:919
利きを持つ局面
const checkmate::King8Info king8Info(Player king) const
bool inCheck(Player P) const
Pの玉が王手状態
const Square square() const
Definition: basic_type.h:832
Ptype capturePtype() const
Definition: basic_type.h:1180
bool isDrop() const
Definition: basic_type.h:1150
const Square to() const
Definition: basic_type.h:1132
unsigned int moveCandidate2() const
24-31 bit 目を 0-7bitにshiftして返す
Definition: king8Info.h:69
const PieceMask & piecesOnBoard(Player p) const
bool hasEffectByPtypeStrict(Player attack, Square target) const
target に ptype の利きがあるか? 成不成を区別
static bool effectiveAttack(NumEffectState &state, Move move, int depth)
move を指した後,alt(move.player())が取ると詰みかどうか.
bool isEmpty() const
Definition: basic_type.h:913
const ProofDisproof hasEscapeByMoveOfTurn(Move next_move, int depth)
PtypeO captured(PtypeO ptypeO)
unpromoteすると共に,ownerを反転する.
Definition: basic_type.h:264
const Square nextSquare(Player P, Square pos, Direction dr) const
next position from pos for player P.
Definition: boardTable.h:61
bool hasEffectNotBy(Player player, Piece piece, Square target) const
対象とするマスにあるプレイヤーの(ただしある駒以外)利きがあるかどうか.
bool any() const
Definition: pieceMask.h:57
Player
Definition: basic_type.h:8
static bool hasEffectOrAdditional(const NumEffectState &state, PtypeO ptypeo, Square from, Square target)
ptypeo の駒がfromからtargetの8近傍に直接の利きを持つか そのような駒への追加/影利きになっている ...
bool isCapture() const
Definition: basic_type.h:1148
const BoardTable Board_Table
Definition: tables.cc:95