promote_.tcc
Go to the documentation of this file.
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/direction.h"
00006 #include "osl/directionTraits.h"
00007 #include "osl/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> /*isLong*/, 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         // short move
00037         template <class Action>
00038         static void generateIfValid(const NumEffectState& state,Piece p, Action& action, 
00039                                     Int2Type<false> /*isLong*/,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> /*isLong*/, 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         // short move
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       // promoteの価値の高い順に生成してみる
00203       // PAWNは600-100=500
00204       generateMovesPtype<Action,PAWN>(state,action);
00205       // ROOKは1300-950=350
00206       generateMovesPtype<Action,ROOK>(state,action);
00207       // BISHOPは1150-800=350
00208       generateMovesPtype<Action,BISHOP>(state,action);
00209       // LANCEは600-400=200
00210       generateMovesPtype<Action,LANCE>(state,action);
00211       // KNIGHTは600-400=200
00212       generateMovesPtype<Action,KNIGHT>(state,action);
00213       // SILVERは600-550=50
00214       generateMovesPtype<Action,SILVER>(state,action);
00215       // GOLD,KINGはpromoteしないので除く
00216     }
00217   }
00218 }
00219 #endif /* OSL_MOVE_GENERATOR_PROMOTE_TCC */
00220 // ;;; Local Variables:
00221 // ;;; mode:c++
00222 // ;;; c-basic-offset:2
00223 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines