00001 #ifndef OSL_MOVE_GENERATOR_PROMOTE_TCC
00002 #define OSL_MOVE_GENERATOR_PROMOTE_TCC
00003
00004 #include "osl/move_generator/promote_.h"
00005 #include "osl/basic_type.h"
00006 #include "osl/bits/directionTraits.h"
00007 #include "osl/bits/ptypeTraits.h"
00008 namespace osl
00009 {
00010 namespace move_generator
00011 {
00012 namespace promote
00013 {
00014 template<Player P,Ptype T,bool noCapture,Direction Dir>
00015 class AllPromoteDir
00016 {
00017 template <class Action>
00018 static void generateIfValid(const NumEffectState& state,Piece piece, Action& action,
00019 Int2Type<true> , Int2Type<true>)
00020 {
00021 const Square from = piece.square();
00022 const Direction black_direction = longToShort(DirectionPlayerTraits<Dir,P>::directionByBlack);
00023 Square last = state.mobilityOf(black_direction, piece.number());
00024 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00025 assert(! last.isPieceStand());
00026 assert(!offset.zero());
00027 for (Square to=from+offset; to!=last; to+=offset) {
00028 assert(state.pieceAt(to).isEmpty());
00029 action.simpleMove(from,to,PtypeFuns<T>::promotePtype,true,P);
00030 }
00031 const Piece last_piece = state.pieceAt(last);
00032 if (!noCapture && last_piece.canMoveOn<P>()){
00033 action.unknownMove(from,last,last_piece,PtypeFuns<T>::promotePtype,true,P);
00034 }
00035 }
00036
00037 template <class Action>
00038 static void generateIfValid(const NumEffectState& state,Piece p, Action& action,
00039 Int2Type<false> ,Int2Type<true>){
00040 Square pos=p.square();
00041 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00042 Square toPos=pos+offset;
00043 Piece p1=state.pieceAt(toPos);
00044 if (p1.isEmpty()){
00045 action.simpleMove(pos,toPos,PtypeFuns<T>::promotePtype,true,P);
00046 }
00047 else if (!noCapture && p1.canMoveOn<P>()){
00048 action.unknownMove(pos,toPos,p1,PtypeFuns<T>::promotePtype,true,P);
00049 }
00050 }
00051 template <class Action>
00052 static void generateIfValid(const NumEffectState&, Piece, Action&, Int2Type<true>,Int2Type<false>){
00053 }
00054 template <class Action>
00055 static void generateIfValid(const NumEffectState&, Piece, Action&, Int2Type<false>,Int2Type<false>){
00056 }
00057 public:
00058 template<class Action>
00059 static void generate(NumEffectState const& state,Piece p,Action& action){
00060 generateIfValid(state,p,action,
00061 Int2Type<DirectionTraits<Dir>::isLong>(),
00062 Int2Type<(PtypeTraits<T>::moveMask
00063 & DirectionTraits<Dir>::mask) !=0>());
00064 }
00065 };
00069 template<Player P,Ptype T,bool noCapture>
00070 class AllPromote{
00071 public:
00072 template<class Action>
00073 static void generate(NumEffectState const& state,Piece p,Action& action){
00074 AllPromoteDir<P,T,noCapture,UL>::generate(state,p,action);
00075 AllPromoteDir<P,T,noCapture,U>::generate(state,p,action);
00076 AllPromoteDir<P,T,noCapture,UR>::generate(state,p,action);
00077 AllPromoteDir<P,T,noCapture,L>::generate(state,p,action);
00078 AllPromoteDir<P,T,noCapture,R>::generate(state,p,action);
00079 AllPromoteDir<P,T,noCapture,DL>::generate(state,p,action);
00080 AllPromoteDir<P,T,noCapture,D>::generate(state,p,action);
00081 AllPromoteDir<P,T,noCapture,DR>::generate(state,p,action);
00082 AllPromoteDir<P,T,noCapture,UUL>::generate(state,p,action);
00083 AllPromoteDir<P,T,noCapture,UUR>::generate(state,p,action);
00084 AllPromoteDir<P,T,noCapture,LONG_UL>::generate(state,p,action);
00085 AllPromoteDir<P,T,noCapture,LONG_U>::generate(state,p,action);
00086 AllPromoteDir<P,T,noCapture,LONG_UR>::generate(state,p,action);
00087 AllPromoteDir<P,T,noCapture,LONG_L>::generate(state,p,action);
00088 AllPromoteDir<P,T,noCapture,LONG_R>::generate(state,p,action);
00089 AllPromoteDir<P,T,noCapture,LONG_DL>::generate(state,p,action);
00090 AllPromoteDir<P,T,noCapture,LONG_D>::generate(state,p,action);
00091 AllPromoteDir<P,T,noCapture,LONG_DR>::generate(state,p,action);
00092 }
00093 };
00094 template<Player P,Ptype T,bool noCapture,Direction Dir>
00095 class MayPromoteDir
00096 {
00097 template <class Action>
00098 static void generateIfValid(const NumEffectState& state,Piece piece, Action& action,
00099 Int2Type<true> , Int2Type<true>)
00100 {
00101 const Square from = piece.square();
00102 const Direction black_direction = longToShort(DirectionPlayerTraits<Dir,P>::directionByBlack);
00103 Square last = state.mobilityOf(black_direction, piece.number());
00104 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00105 assert(! last.isPieceStand());
00106 assert(! offset.zero());
00107
00108 const Piece last_piece = state.pieceAt(last);
00109 if (!noCapture && last_piece.canMoveOn<P>()){
00110 if (! last.canPromote<P>())
00111 return;
00112 action.unknownMove(from,last,last_piece,PtypeFuns<T>::promotePtype,true,P);
00113 }
00114 for (Square to=last-offset; to!=from; to-=offset) {
00115 assert(state.pieceAt(to).isEmpty());
00116 if (! to.canPromote<P>())
00117 return;
00118 action.simpleMove(from,to,PtypeFuns<T>::promotePtype,true,P);
00119 }
00120 }
00121
00122 template <class Action>
00123 static void generateIfValid(const NumEffectState& state,Piece p, Action& action, Int2Type<false>,Int2Type<true>){
00124 Square pos=p.square();
00125 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00126 Square toPos=pos+offset;
00127 Piece p1=state.pieceAt(toPos);
00128 if (p1.isEmpty()){
00129 action.simpleMove(pos,toPos,PtypeFuns<T>::promotePtype,true,P);
00130 }
00131 else if (!noCapture && p1.canMoveOn<P>()){
00132 action.unknownMove(pos,toPos,p1,PtypeFuns<T>::promotePtype,true,P);
00133 }
00134 }
00135 template <class Action>
00136 static void generateIfValid(const NumEffectState&, Piece, Action&, Int2Type<true>,Int2Type<false>){
00137 }
00138 template <class Action>
00139 static void generateIfValid(const NumEffectState&, Piece, Action&, Int2Type<false>,Int2Type<false>){
00140 }
00141 public:
00142 template<class Action>
00143 static void generate(NumEffectState const& state,Piece p,Action& action){
00144 generateIfValid(state,p,action,
00145 Int2Type<DirectionTraits<Dir>::isLong>(),
00146 Int2Type<(PtypeTraits<T>::moveMask
00147 & DirectionTraits<Dir>::mask) !=0>());
00148 }
00149 };
00153 template<Player P,Ptype T,bool noCapture>
00154 class MayPromote{
00155 public:
00156 template<class Action>
00157 static void generate(NumEffectState const& state,Piece p,Action& action){
00158 MayPromoteDir<P,T,noCapture,UL>::generate(state,p,action);
00159 MayPromoteDir<P,T,noCapture,U>::generate(state,p,action);
00160 MayPromoteDir<P,T,noCapture,UR>::generate(state,p,action);
00161 MayPromoteDir<P,T,noCapture,UUL>::generate(state,p,action);
00162 MayPromoteDir<P,T,noCapture,UUR>::generate(state,p,action);
00163 MayPromoteDir<P,T,noCapture,LONG_UL>::generate(state,p,action);
00164 MayPromoteDir<P,T,noCapture,LONG_U>::generate(state,p,action);
00165 MayPromoteDir<P,T,noCapture,LONG_UR>::generate(state,p,action);
00166 }
00167 };
00168
00169 template<typename Action,Player P,Ptype T,bool noCapture>
00170 struct EachOnBoard
00171 {
00172 const NumEffectState& state;
00173 Action& action;
00174 EachOnBoard(const NumEffectState& state,Action& action):state(state),action(action){}
00175 void operator()(Piece p){
00176 assert(! p.isPromoted());
00177 if (PtypePlayerTraits<T,P>::mayPromote(p.square())){
00178 if (p.square().template canPromote<P>()){
00179 AllPromote<P,T,noCapture>::generate(state,p,action);
00180 }
00181 else{
00182 MayPromote<P,T,noCapture>::generate(state,p,action);
00183 }
00184 }
00185 }
00186 };
00187 }
00188
00189 template<Player P, bool noCapture>
00190 template <class Action, Ptype T>
00191 void Promote<P,noCapture>::
00192 generateMovesPtype(const NumEffectState& state, Action& action){
00193 typedef promote::EachOnBoard<Action,P,T,noCapture> each_t;
00194 each_t eachOnBoard(state,action);
00195 state.template forEachOnBoardPtypeStrict<P,T,each_t>(eachOnBoard);
00196 }
00197
00198 template<Player P,bool noCapture>
00199 template <class Action>
00200 void Promote<P,noCapture>::
00201 generateMoves(const NumEffectState& state, Action& action){
00202
00203
00204 generateMovesPtype<Action,PAWN>(state,action);
00205
00206 generateMovesPtype<Action,ROOK>(state,action);
00207
00208 generateMovesPtype<Action,BISHOP>(state,action);
00209
00210 generateMovesPtype<Action,LANCE>(state,action);
00211
00212 generateMovesPtype<Action,KNIGHT>(state,action);
00213
00214 generateMovesPtype<Action,SILVER>(state,action);
00215
00216 }
00217 }
00218 }
00219 #endif
00220
00221
00222
00223