checkmate.cc Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
checkmate.cc
Go to the documentation of this file.
1 /* checkmate.cc
2 */
3 #include "osl/rating/feature/checkmate.h"
4 #include "osl/effect_util/neighboring8Direct.h"
5 #include "osl/neighboring8.h"
6
7 struct osl::rating::Threatmate::Helper
8 {
9 bool *result;
10 NumEffectState *state;
11 void operator()(Square)
12 {
13 if (state->inCheck(state->turn())
14 || state->inCheck(alt(state->turn()))) {
15 *result = false;
16 return;
17 }
18 state->changeTurn();
19 *result = ImmediateCheckmate::hasCheckmateMove(state->turn(), *state);
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: