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 namespace osl
00014 {
00015 namespace move_classifier
00016 {
00021 template <Player P>
00022 struct PawnDropCheckmate
00023 {
00027 template <class State>
00028 static bool canEscape(const State& state, Position kingPosition,
00029 Direction dir, Position dropAt);
00031 template <class State>
00032 static bool escape7(const State& state,
00033 Position kingPosition, Position to);
00034 static bool isMember(const NumEffectState& state,
00035 Ptype ptype,Position from,Position to)
00036 {
00037
00038 if (! from.isPieceStand())
00039 return false;
00040 if (ptype != PAWN)
00041 return false;
00042 const Player Opponent = PlayerTraits<P>::opponent;
00043 const Piece king = state.template getKingPiece<Opponent>();
00044 const Position king_position = king.position();
00045
00046
00047 if (king_position != (to + Board_Table.template getOffset<P>(U)))
00048 return false;
00049
00050 if (! state.hasEffectBy(P, to))
00051 return false;
00052
00053 if (EffectUtil::template safeCaptureNotByKing<Opponent,NumEffectState>
00054 (state, to, king)
00055 != Piece::EMPTY())
00056 return false;
00057
00058 return escape7(state, king_position, to);
00059 }
00060 };
00061 }
00062 }
00063
00064 template <osl::Player P>
00065 template <class State>
00066 bool osl::move_classifier::PawnDropCheckmate<P>::
00067 canEscape(const State& state, Position kingPosition,
00068 Direction dir, Position dropAt)
00069 {
00070 const Player Opponent = PlayerTraits<P>::opponent;
00071 const Position target
00072 = kingPosition + Board_Table.getOffset(Opponent, dir);
00073 const Piece p = state.getPieceAt(target);
00074 if (p.isOnBoardByOwner<Opponent>())
00075 return false;
00076 if (! target.isOnBoard())
00077 return false;
00078 Piece attacker;
00079 if (! state.template hasEffectBy<P>(target, attacker))
00080 return true;
00081 if (attacker == Piece::EMPTY())
00082 return false;
00083 assert(attacker.owner() == P);
00084
00085
00086
00087
00088 const Offset shortOffset
00089 = Board_Table.getShortOffsetNotKnight(Offset32(target,dropAt));
00090 if (shortOffset.zero())
00091 return false;
00092 const Position attackFrom = attacker.position();
00093 return shortOffset
00094 == Board_Table.getShortOffsetNotKnight(Offset32(dropAt,attackFrom));
00095 }
00096
00097 template <osl::Player P>
00098 template <class State>
00099 bool osl::move_classifier::PawnDropCheckmate<P>::
00100 escape7(const State& state, Position king_position, Position to)
00101 {
00102
00103 if (canEscape(state, king_position, UL, to))
00104 return false;
00105 if (canEscape(state, king_position, UR, to))
00106 return false;
00107 if (canEscape(state, king_position, L, to))
00108 return false;
00109 if (canEscape(state, king_position, R, to))
00110 return false;
00111 if (canEscape(state, king_position, DL, to))
00112 return false;
00113 if (canEscape(state, king_position, D, to))
00114 return false;
00115 if (canEscape(state, king_position, DR, to))
00116 return false;
00117 return true;
00118 }
00119
00120
00121 #endif
00122
00123
00124
00125