00001
00002
00003 #ifndef OSL_MOVE_CLASSIFIER_PAWNDROPCHECKMATE_H
00004 #define OSL_MOVE_CLASSIFIER_PAWNDROPCHECKMATE_H
00005
00006 #include "osl/state/numEffectState.h"
00007 #include "osl/effect_util/effectUtil.h"
00008 #include "osl/checkmate/king8Info.h"
00009 namespace osl
00010 {
00011 namespace move_classifier
00012 {
00017 template <Player P>
00018 struct PawnDropCheckmate
00019 {
00023 static bool canEscape(const NumEffectState& state, Square kingSquare,
00024 Direction dir, Square dropAt);
00026 static bool escape7(const NumEffectState& state,
00027 Square kingSquare, Square to);
00028 static bool isMember(const NumEffectState& state,
00029 Ptype ptype,Square from,Square to)
00030 {
00031
00032 if (! from.isPieceStand())
00033 return false;
00034 if (ptype != PAWN)
00035 return false;
00036 const Player Opponent = PlayerTraits<P>::opponent;
00037 const Piece king = state.template kingPiece<Opponent>();
00038 const Square king_position = king.square();
00039
00040
00041 if (king_position != (to + DirectionPlayerTraits<U,P>::offset()))
00042 return false;
00043
00044 if (! state.hasEffectAt(P, to))
00045 return false;
00046 if (King8Info(state.Iking8Info(Opponent)).liberty() != 0)
00047 return false;
00048
00049 if (EffectUtil::template safeCaptureNotByKing<Opponent>
00050 (state, to, king)
00051 != Piece::EMPTY())
00052 return false;
00053
00054 return escape7(state, king_position, to);
00055 }
00056 };
00057 }
00058 }
00059
00060 template <osl::Player P>
00061 bool
00062 #ifdef __GNUC__
00063 __attribute__ ((pure))
00064 #endif
00065 osl::move_classifier::PawnDropCheckmate<P>::
00066 canEscape(const NumEffectState& state, Square kingSquare,
00067 Direction dir, Square dropAt)
00068 {
00069 const Player Opponent = PlayerTraits<P>::opponent;
00070 const Square target
00071 = kingSquare + Board_Table.getOffset(Opponent, dir);
00072 const Piece p = state.pieceAt(target);
00073 if (p.isOnBoardByOwner<Opponent>())
00074 return false;
00075 if (target.isEdge())
00076 return false;
00077 Piece attacker;
00078 if (! state.template hasEffectAt<P>(target, attacker))
00079 return true;
00080 if (attacker == Piece::EMPTY())
00081 return false;
00082 assert(attacker.owner() == P);
00083
00084
00085
00086
00087 const Offset shortOffset
00088 = Board_Table.getShortOffsetNotKnight(Offset32(target,dropAt));
00089 if (shortOffset.zero())
00090 return false;
00091 const Square attackFrom = attacker.square();
00092 return shortOffset
00093 == Board_Table.getShortOffsetNotKnight(Offset32(dropAt,attackFrom));
00094 }
00095
00096 template <osl::Player P>
00097 bool
00098 #ifdef __GNUC__
00099 __attribute__ ((pure))
00100 #endif
00101 osl::move_classifier::PawnDropCheckmate<P>::
00102 escape7(const NumEffectState& state, Square king_position, Square to)
00103 {
00104
00105 if (canEscape(state, king_position, UL, to))
00106 return false;
00107 if (canEscape(state, king_position, UR, to))
00108 return false;
00109 if (canEscape(state, king_position, L, to))
00110 return false;
00111 if (canEscape(state, king_position, R, to))
00112 return false;
00113 if (canEscape(state, king_position, DL, to))
00114 return false;
00115 if (canEscape(state, king_position, D, to))
00116 return false;
00117 if (canEscape(state, king_position, DR, to))
00118 return false;
00119 return true;
00120 }
00121
00122
00123 #endif
00124
00125
00126
00127