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