All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
checkmate.cc
Go to the documentation of this file.
1 /* checkmate.cc
2  */
5 #include "osl/neighboring8.h"
6 
8 {
9  bool *result;
10  NumEffectState *state;
12  {
13  if (state->inCheck(state->turn())
14  || state->inCheck(alt(state->turn()))) {
15  *result = false;
16  return;
17  }
18  state->changeTurn();
20  state->changeTurn();
21  }
22 };
23 
24 bool osl::rating::
25 Threatmate::knight2Step(const NumEffectState& state, Move move, Square king)
26 {
27  if (move.ptype() != KNIGHT)
28  return false;
29  const int y = king.y() + playerToMul(state.turn())*4;
30  if (y != move.to().y())
31  return false;
32  const int x = move.to().x();
33  return (x == king.x() || abs(king.x() - x) == 2);
34 }
35 bool osl::rating::
36 Threatmate::captureForKnightCheck(const NumEffectState& state, Move move, Square king)
37 {
38  const Player defender = alt(state.turn());
39  const CArray<Square,2> knight_position = {{
40  Board_Table.nextSquare(defender, king, UUR),
41  Board_Table.nextSquare(defender, king, UUL)
42  }};
43  const Piece captured = state.pieceOnBoard(move.to());
44  assert(captured.isPiece());
45  for (int i=0; i<2; ++i) {
46  const Square kp = knight_position[i];
47  const Piece p = state.pieceAt(kp);
48  if (state.hasEffectNotBy(defender, captured, kp))
49  continue;
50  if (p.isEmpty()
51  && (unpromote(move.capturePtype()) == KNIGHT
52  || state.hasPieceOnStand<KNIGHT>(state.turn())))
53  return true;
54  if (p.canMoveOn(state.turn())
55  && state.hasEffectByPtypeStrict<KNIGHT>(state.turn(), kp))
56  return true;
57  }
58  return false;
59 }
60 
61 bool osl::rating::Threatmate::isCandidate(const NumEffectState& state, Move move)
62 {
63  const Player defender = alt(state.turn());
64  const Square king = state.kingSquare(defender);
65  if (Neighboring8Direct::hasEffectOrAdditional(state, move.ptypeO(), move.to(), king)
66  || Neighboring8::isNeighboring8(move.to(), king)
67  || state.longEffectAt(move.to(), alt(state.turn())).any() // todo: refinement
68  || (! move.isDrop() && state.longEffectAt(move.from(), state.turn()).any()) // todo: refinement
69  )
70  return true;
71  if (move.capturePtype() != PTYPE_EMPTY
72  && Neighboring8Direct::hasEffectOrAdditional(state, move.capturePtypeO(), move.to(), king))
73  return true;
74 
75  const King8Info info(state.king8Info(defender));
76  if (move.capturePtype() != PTYPE_EMPTY
77  && (info.dropCandidate()
78  || (info.liberty() == 0 && captureForKnightCheck(state, move, king))))
79  return true;
80  if (state.inCheck()
81  && (info.dropCandidate() || info.moveCandidate2()
82  || /* only when hand knight or knight effect */info.liberty() == 0))
83  return true;
84  if (info.liberty() == 0
85  && (knight2Step(state, move, king)
86  || (! move.isDrop()
87  && ((state.hasPieceOnStand<KNIGHT>(state.turn())
88  && state.hasEffectIf(newPtypeO(state.turn(),KNIGHT), move.from(), king))
89  || state.hasEffectByPtypeStrict<KNIGHT>(state.turn(), move.from())))))
90  return true;
91  return false;
92 }
93 
94 bool osl::rating::Threatmate::match(const NumEffectState& cstate, Move move,
95  const RatingEnv&) const
96 {
97  NumEffectState& state = const_cast<NumEffectState&>(cstate);
98  if (! isCandidate(cstate, move))
99  return false;
100  bool result = false;
101  Helper helper = { &result, &state };
102  state.makeUnmakeMove(move, helper);
103 #ifdef OSL_DEBUG
104  if (result && ! isCandidate(cstate, move))
105  std::cerr << cstate << move << "\n", assert(0);
106 #endif
107  return result;
108 }
109 
110 /* ------------------------------------------------------------------------- */
111 // ;;; Local Variables:
112 // ;;; mode:c++
113 // ;;; c-basic-offset:2
114 // ;;; End: