checkmate.cc
Go to the documentation of this file.
00001 /* checkmate.cc
00002  */
00003 #include "osl/rating/feature/checkmate.h"
00004 #include "osl/effect_util/neighboring8Direct.h"
00005 #include "osl/neighboring8.h"
00006 
00007 struct osl::rating::Threatmate::Helper
00008 {
00009   bool *result;
00010   NumEffectState *state;
00011   void operator()(Square) 
00012   {
00013     if (state->inCheck(state->turn())
00014         || state->inCheck(alt(state->turn()))) {
00015       *result = false;
00016       return;
00017     }
00018     state->changeTurn();
00019     *result = ImmediateCheckmate::hasCheckmateMove(state->turn(), *state);
00020     state->changeTurn();
00021   }
00022 };
00023 
00024 bool osl::rating::
00025 Threatmate::knight2Step(const NumEffectState& state, Move move, Square king) 
00026 {
00027   if (move.ptype() != KNIGHT)
00028     return false;
00029   const int y = king.y() + playerToMul(state.turn())*4;
00030   if (y != move.to().y())
00031     return false;
00032   const int x = move.to().x();
00033   return (x == king.x() || abs(king.x() - x) == 2);
00034 }
00035 bool osl::rating::
00036 Threatmate::captureForKnightCheck(const NumEffectState& state, Move move, Square king)
00037 {
00038   const Player defender = alt(state.turn());
00039   const CArray<Square,2> knight_position = {{
00040       Board_Table.nextSquare(defender, king, UUR),
00041       Board_Table.nextSquare(defender, king, UUL)
00042     }};
00043   const Piece captured = state.pieceOnBoard(move.to());
00044   assert(captured.isPiece());
00045   for (int i=0; i<2; ++i) {
00046     const Square kp = knight_position[i];
00047     const Piece p = state.pieceAt(kp);
00048     if (state.hasEffectNotBy(defender, captured, kp))
00049       continue;
00050     if (p.isEmpty()
00051         && (unpromote(move.capturePtype()) == KNIGHT
00052             || state.hasPieceOnStand<KNIGHT>(state.turn())))
00053       return true;
00054     if (p.canMoveOn(state.turn())
00055         && state.hasEffectByPtypeStrict<KNIGHT>(state.turn(), kp))
00056       return true;
00057   }
00058   return false;
00059 }
00060 
00061 bool osl::rating::Threatmate::isCandidate(const NumEffectState& state, Move move) 
00062 {
00063   const Player defender = alt(state.turn());
00064   const Square king = state.kingSquare(defender);
00065   if (Neighboring8Direct::hasEffectOrAdditional(state, move.ptypeO(), move.to(), king)
00066       || Neighboring8::isNeighboring8(move.to(), king)
00067       || state.longEffectAt(move.to(), alt(state.turn())).any() // todo: refinement
00068       || (! move.isDrop() && state.longEffectAt(move.from(), state.turn()).any()) // todo: refinement
00069     )
00070     return true;
00071   if (move.capturePtype() != PTYPE_EMPTY
00072       && Neighboring8Direct::hasEffectOrAdditional(state, move.capturePtypeO(), move.to(), king))
00073     return true;
00074 
00075   const King8Info info(state.king8Info(defender));
00076   if (move.capturePtype() != PTYPE_EMPTY
00077       && (info.dropCandidate()
00078           || (info.liberty() == 0 && captureForKnightCheck(state, move, king))))
00079     return true;
00080   if (state.inCheck()
00081       && (info.dropCandidate() || info.moveCandidate2() 
00082           || /* only when hand knight or knight effect */info.liberty() == 0))
00083     return true;
00084   if (info.liberty() == 0
00085       && (knight2Step(state, move, king)
00086           || (! move.isDrop()
00087               && ((state.hasPieceOnStand<KNIGHT>(state.turn())
00088                    && state.hasEffectIf(newPtypeO(state.turn(),KNIGHT), move.from(), king))
00089                   || state.hasEffectByPtypeStrict<KNIGHT>(state.turn(), move.from())))))
00090     return true;
00091   return false;
00092 }
00093 
00094 bool osl::rating::Threatmate::match(const NumEffectState& cstate, Move move, 
00095                                     const RatingEnv&) const
00096 {
00097   NumEffectState& state = const_cast<NumEffectState&>(cstate);
00098   if (! isCandidate(cstate, move))
00099     return false;
00100   bool result = false;
00101   Helper helper = { &result, &state };
00102   state.makeUnmakeMove(move, helper);
00103 #ifdef OSL_DEBUG
00104   if (result && ! isCandidate(cstate, move))
00105     std::cerr << cstate << move << "\n", assert(0);
00106 #endif
00107   return result;
00108 }
00109 
00110 /* ------------------------------------------------------------------------- */
00111 // ;;; Local Variables:
00112 // ;;; mode:c++
00113 // ;;; c-basic-offset:2
00114 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines