addEffectWithEffect.tcc
Go to the documentation of this file.
00001 #ifndef _GENERATER_ADD_EFFECT_WITH_EFFECT_TCC
00002 #define _GENERATER_ADD_EFFECT_WITH_EFFECT_TCC
00003 
00004 #include "osl/move_generator/addEffectWithEffect.h"
00005 #include "osl/move_generator/open.h"
00006 #include "osl/move_generator/open.tcc"
00007 #include "osl/move_generator/pieceOnBoard.tcc"
00008 #include "osl/checkmate/king8Info.h"
00009 
00010 //#define GENERATE_PAWNDROP_CHECKMATE
00011 
00012 namespace osl
00013 {
00014   namespace move_generator
00015   {
00016     namespace detail
00017     {
00030       template<osl::Player P,class Action>
00031       void generateMovePiecePtypeMask(const NumEffectState& state,Piece p,Square to,Piece toP,Action& action,unsigned int ptypeMask)
00032       {
00033         assert(p.isOnBoardByOwner<P>());
00034         assert(toP==state.pieceAt(to));
00035         Ptype ptype=p.ptype();
00036         Square from=p.square();
00037         if(canPromote(ptype) &&
00038            (to.canPromote<P>() || from.canPromote<P>())){
00039           Ptype pptype=osl::promote(ptype);
00040           if(((1<<pptype)&ptypeMask)!=0)
00041             action.unknownMove(from,to,toP,pptype,true,P);
00042           if(Move::ignoreUnpromote<P>(ptype,from,to)) return;
00043         }
00044         // 
00045         if(((1<<ptype)&ptypeMask)!=0)
00046           action.unknownMove(p.square(),to,toP,ptype,false,P);
00047       }
00058       template<osl::Player P,class Action>
00059       void generateMoveToPtypeMaskWithPieceMask(const NumEffectState& state,Square to,Piece toP,Action& action,unsigned int ptypeMask,PieceMask pieceMask)
00060       {
00061         if(pieceMask.test(KingTraits<P>::index)){
00062           const Player altP=PlayerTraits<P>::opponent;
00063           if(!state.hasEffectAt<altP>(to)){
00064             action.unknownMove(state.kingSquare<P>(),to,toP,KING,false,P);
00065           }
00066           pieceMask.reset(KingTraits<P>::index);
00067         }
00068         while (pieceMask.any()){
00069           const int num=pieceMask.takeOneBit();
00070           Piece p=state.pieceOf(num);
00071           if(state.pinOrOpen(P).test(num)){
00072             Direction d=state.pinnedDir<P>(p);
00073             Direction d1=Board_Table.template getShort8Unsafe<P>(p.square(),to);
00074             if(primDir(d)!=primDirUnsafe(d1)) continue;
00075           }
00076           generateMovePiecePtypeMask<P,Action>(state,p,to,toP,action,ptypeMask);
00077         }
00078       }
00079       template<osl::Player P,class Action>
00080       void generateMoveToPtypeMask(const NumEffectState& state,Square to,Piece toP,Action& action,unsigned int ptypeMask)
00081       {
00082         PieceMask pieceMask=state.piecesOnBoard(P)&state.effectSetAt(to);
00083         const Player altP=PlayerTraits<P>::opponent;
00084         pieceMask.reset(KingTraits<P>::index); // 玉は除く
00085         pieceMask &= ~state.pinOrOpen(altP); // open atackからのものを除く
00086         generateMoveToPtypeMaskWithPieceMask<P,Action>(state,to,toP,action,ptypeMask,pieceMask);
00087       }
00088 #ifndef GENERATE_PAWNDROP_CHECKMATE
00089 
00092       template<osl::Player P>
00093       bool
00094 #ifdef __GNUC__
00095         __attribute__ ((pure))
00096 #endif
00097       blockingU(const NumEffectState& state,Square pos)
00098       {
00099         const osl::Player altP=PlayerTraits<P>::opponent;
00100         NumBitmapEffect effect=state.effectSetAt(pos);
00101         mask_t mask=(effect.getMask(1)& NumBitmapEffect::longEffectMask());
00102         mask&=state.piecesOnBoard(P).getMask(1)<<8; // ROOK, BISHOPの利きのみのはず
00103         while(mask.any()){
00104           int num=mask.takeOneBit()+NumBitmapEffect::longToNumOffset;
00105           Square from=state.pieceOf(num).square();
00106           if( (P==BLACK ? from.y()>=pos.y() : pos.y()>=from.y()) ){
00107             Square shadowPos=pos+Board_Table.getShortOffset(Offset32(pos,from));
00108             assert((P==BLACK ? shadowPos.y()<=pos.y() : pos.y()<=shadowPos.y()) );
00109             Piece p=state.pieceAt(shadowPos);
00110             if(p.canMoveOn<altP>() && !state.hasMultipleEffectAt(P,shadowPos)){
00111               return true;
00112             }
00113           }
00114         }
00115         return false;
00116       }
00117 #endif
00118 
00124       template<osl::Player P,int DirType,class Action>
00125       void generateDir(const NumEffectState& state,Square target,Action& action,bool& hasPawnCheckmate,Offset dirOffset,Direction Dir,Direction primDir,int ptypeMaskNotKing)
00126       {
00127         const Player altP=PlayerTraits<P>::opponent;
00128         Square pos=target-dirOffset;
00129         if(!pos.isOnBoard()) return;
00130         Piece p=state.pieceAt(pos);
00131         if(p.isOnBoardByOwner<P>()){
00132           if(DirType==0 && state.hasLongEffectAt<LANCE>(P,pos)){
00133             PieceOnBoard<Action>::template generate<P,true>(state,p,action,1<<primDir);
00134           }
00135           return;
00136         }
00137         if((state.Iking8Info(altP)&(1ull<<(40+Dir)))!=0){
00138           // - posに利きがある
00139           // TODO safe moveではない
00140           generateMoveToPtypeMask<P,Action>(state,pos,p,action,
00141                                             ptypeMaskNotKing);
00142         }
00143         if(DirType !=0) return;
00144         if(p.isEmpty()){
00145           Square pos1=state.kingMobilityOfPlayer(altP,Dir);
00146           mask_t lance_mask=state.longEffectAt<LANCE>(pos1,P);
00147           if(lance_mask.any()){
00148             Piece p1=state.pieceAt(pos1);
00149             if(p1.isOnBoardByOwner<P>()){
00150               PieceOnBoard<Action>::template generate<P,true>(state,p1,action,1<<primDir);
00151               // 
00152               if(state.hasEffectByPiece(p1,pos)){
00153                 PieceOnBoard<Action>::template generatePiece<P>(state,p1,pos,Piece::EMPTY(),action);
00154               }
00155             }
00156             else if(p1.isOnBoardByOwner<altP>()){
00157               assert(!lance_mask.hasMultipleBit());
00158               int num=lance_mask.bsf()+PtypeFuns<LANCE>::indexNum*32;
00159               Piece p2=state.pieceOf(num);
00160               if(!state.pinOrOpen(P).test(num) ||
00161                  state.kingSquare<P>().isUD(p2.square())){
00162                 action.unknownMove(p2.square(),pos1,p1,LANCE,false,P);
00163               }
00164             }
00165           }
00166           // - PAWN, LANCEはここで調べる?
00167           //  + ただしPAWNはつみは禁止
00168           if(! state.isPawnMaskSet<P>(target.x()) &&
00169              state.hasPieceOnStand<PAWN>(P)){
00170             // 利きをさえぎるパターンの検証
00171 #ifndef GENERATE_PAWNDROP_CHECKMATE
00172             if(((state.Iking8Info(altP)&(0xff00ull|(1ull<<(U+24))))^(1ull<<(U+24)))!=0 || blockingU<P>(state,pos))
00173               action.dropMove(pos,PAWN,P);
00174             else
00175               hasPawnCheckmate=true;
00176 #else
00177             action.dropMove(pos,PAWN,P);
00178 #endif
00179           }
00180           if(state.hasPieceOnStand<LANCE>(P)){
00181             action.dropMove(pos,LANCE,P);
00182             for(pos-=DirectionPlayerTraits<U,P>::offset();
00183                 pos!=pos1;pos-=DirectionPlayerTraits<U,P>::offset()){
00184               action.dropMove(pos,LANCE,P);
00185             }
00186           }
00187         }
00188       }
00189 
00190       template<osl::Player P,int DirType,class Action,Direction Dir>
00191       void generateDir(const NumEffectState& state,Square target,Action& action,bool& hasPawnCheckmate)
00192       {
00193         generateDir<P,DirType,Action>(state,target,action,hasPawnCheckmate,
00194                                       DirectionPlayerTraits<Dir,P>::offset(),Dir,DirectionTraits<Dir>::primDir,DirectionTraits<Dir>::ptypeMaskNotKing);
00195       }
00202       template<osl::Player P,int DirType,class Action>
00203       void generateDirNotKing(const NumEffectState& state,Square target,Action& action,CArray<unsigned char,8>& pieceMobility, int& spaces, PieceMask const& notPieceMask,Offset dirOffset,Direction Dir,Direction primDir,int ptypeMask,Direction dirByBlack
00204         )
00205       {
00206         const Player altP=PlayerTraits<P>::opponent;
00207         Square pos=target-dirOffset;
00208         if(!pos.isOnBoard()){
00209           pieceMobility[dirByBlack]=pos.uintValue();
00210           return;
00211         }
00212         Piece p=state.pieceAt(pos);
00213         if(p.canMoveOn<P>()){
00214           // - posに利きがある
00215           const PieceMask pieceMask=state.piecesOnBoard(P)&state.effectSetAt(pos)&notPieceMask & ~state.effectSetAt(target);
00216           if(pieceMask.any())
00217             detail:: template generateMoveToPtypeMaskWithPieceMask<P,Action>(state,pos,p,action,
00218                                                                              ptypeMask,pieceMask);
00219         }
00220         Square nextSquare=pos;
00221         if(p.isEmpty()){
00222           spaces|=(1u<<Dir);
00223           if(DirType==0 && ! state.isPawnMaskSet<P>(target.x()) &&
00224              state.hasPieceOnStand<PAWN>(P))
00225             action.dropMove(pos,PAWN,P);
00226           do{
00227             pos-=dirOffset;
00228             p=state.pieceAt(pos);
00229           } while(p.isEmpty());
00230         }
00231         if(p.isOnBoardByOwner<P>() && state.hasEffectByPiece(p,target)){
00232           for(;;){
00233             Piece p1=state.findLongAttackAt(P,p,inverse(Dir));
00234             if(!p1.isOnBoardByOwner<P>()){
00235               break;
00236             }
00237             p=p1;
00238           } 
00239           pos=p.square()-dirOffset;
00240           while((p=state.pieceAt(pos)).isEmpty())
00241             pos-=dirOffset;
00242         }
00243         else if (p.isOnBoardByOwner<altP>() && state.hasEffectByPiece(p,target)){
00244           // shadowは1つだけ見る
00245           Piece p1=state.findLongAttackAt(altP,p,Dir);
00246           if(p1.isOnBoardByOwner<P>()){
00247             if(pos!=nextSquare){
00248               if(p1.ptype()==LANCE){
00249                 int num=p1.number();
00250                 if(!state.pinOrOpen(P).test(num) ||
00251                    p1.square().isUD(state.kingSquare<P>())){
00252                   action.unknownMove(p1.square(),pos,p,LANCE,false,P);
00253                 }
00254               }
00255               else
00256                 PieceOnBoard<Action>::template generatePiece<P>(state,p1,pos,p,action);
00257             }
00258             pos=p1.square();
00259             p=p1;
00260           }
00261           else{
00262             pos=p.square()-dirOffset;
00263             while((p=state.pieceAt(pos)).isEmpty())
00264               pos-=dirOffset;
00265           }
00266         }
00267         pieceMobility[dirByBlack]=pos.uintValue();
00268         if(p.isOnBoardByOwner<P>()){
00269           Piece p1=state.findLongAttackAt(P,p,inverse(Dir));
00270           if(p1.isOnBoardByOwner<P>()){
00271             Open<Action>::template generate<P>(state,p,action,target,primDir);
00272           }
00273         }
00274         else if(p.isOnBoardByOwner<altP>() && pos!=nextSquare){
00275           if(DirType==0){
00276             mask_t lance_mask=state.longEffectAt<LANCE>(pos,P);
00277             if(lance_mask.any()){
00278               assert(!lance_mask.hasMultipleBit());
00279               int num=lance_mask.bsf()+PtypeFuns<LANCE>::indexNum*32;
00280               Piece p2=state.pieceOf(num);
00281               if(!state.pinOrOpen(P).test(num) || 
00282                  state.kingSquare<P>().isUD(p2.square())){
00283                 action.unknownMove(p2.square(),pos,p,LANCE,false,P);
00284               }
00285             }
00286           }
00287           if(DirType <= 1){
00288             mask_t rook_mask=state.allEffectAt<ROOK>(P,pos);
00289             while(rook_mask.any()){
00290               int num=rook_mask.takeOneBit()+PtypeFuns<ROOK>::indexNum*32;
00291               Piece p2=state.pieceOf(num);
00292               if(p2.square()==target) continue;
00293               PieceOnBoard<Action>::template generatePiece<P>(state,p2,pos,p,action);
00294             }
00295           }
00296           if(DirType == 2){
00297             mask_t bishop_mask=state.allEffectAt<BISHOP>(P,pos);
00298             // 利きをチェックする必要あり
00299             while(bishop_mask.any()){
00300               int num=bishop_mask.takeOneBit()+PtypeFuns<BISHOP>::indexNum*32;
00301               Piece p2=state.pieceOf(num);
00302               if(p2.square()==target) continue;
00303               PieceOnBoard<Action>::template generatePiece<P>(state,p2,pos,p,action);
00304             }
00305           }
00306         }
00307 
00308         // - PAWN, LANCEはここで調べる?
00309         //  + ただしPAWNはつみは禁止
00310         if(DirType == 0){
00311           if(state.hasPieceOnStand<LANCE>(P)){
00312             for(pos+=DirectionPlayerTraits<U,P>::offset();
00313                 pos!=target;pos+=DirectionPlayerTraits<U,P>::offset()){
00314               if(state.pieceAt(pos).isEmpty())
00315                 action.dropMove(pos,LANCE,P);
00316             }
00317           }
00318         }
00319       }
00320 
00321       template<osl::Player P,int DirType,class Action,Direction Dir>
00322       void generateDirNotKing(const NumEffectState& state,Square target,Action& action,CArray<unsigned char,8>& pieceMobility, int& spaces, PieceMask const& notPieceMask)
00323       {
00324         generateDirNotKing<P,DirType,Action>(state,target,action,pieceMobility,spaces,notPieceMask,
00325                                              DirectionPlayerTraits<Dir,P>::offset(),Dir,DirectionTraits<Dir>::primDir,DirectionTraits<Dir>::ptypeMask,DirectionPlayerTraits<Dir,P>::directionByBlack);
00326         
00327       }
00328       template<osl::Player P,osl::Direction Dir,class Action,bool hasKnight>
00329       void generateKnightDir(const NumEffectState& state,Square target,Action& action)
00330       {
00331         Square pos=target-DirectionPlayerTraits<Dir,P>::offset();
00332         if(!pos.isOnBoard()) return;
00333         Piece p=state.pieceAt(pos);
00334         if(!p.canMoveOn<P>()) return;
00335         mask_t mask=state.allEffectAt<KNIGHT>(P, pos);
00336         mask &= ~state.promotedPieces().getMask<KNIGHT>();
00337         // pinnedなknightは動けない
00338         mask &= ~state.pinOrOpen(P).getMask(PtypeFuns<KNIGHT>::indexNum);
00339         while(mask.any()){
00340           const int num = mask.takeOneBit()+PtypeFuns<KNIGHT>::indexNum*32;
00341           Piece p1=state.pieceOf(num);
00342           action.unknownMove(p1.square(),pos,p,KNIGHT,false,P);
00343         }
00344         if(hasKnight && p.isEmpty()){
00345           action.dropMove(pos,KNIGHT,P);
00346         }
00347       }
00348       template<osl::Player P,class Action>
00349       void generateKnightAll(const NumEffectState& state,Square target,Action& action)
00350       {
00351         if(state.hasPieceOnStand<KNIGHT>(P)){
00352           detail::generateKnightDir<P,UUL,Action,true>(state,target,action);
00353           detail::generateKnightDir<P,UUR,Action,true>(state,target,action);
00354         }
00355         else{
00356           detail::generateKnightDir<P,UUL,Action,false>(state,target,action);
00357           detail::generateKnightDir<P,UUR,Action,false>(state,target,action);
00358         }
00359       }
00360       template <osl::Player P,class Action>
00361       void generateDrop(Square target,Action& action,int spaceMask,osl::Ptype T,int dirMask,Offset offset)
00362       {
00363         if((spaceMask&dirMask)!=0){
00364           Square pos=target-offset;
00365           action.dropMove(pos,T,P);
00366         }
00367       }
00368       template <osl::Player P,class Action,Direction Dir>
00369       void generateDropDir(Square target,Action& action,int spaceMask,osl::Ptype T)
00370       {
00371         generateDrop<P,Action>(target,action,spaceMask,T,(1<<Dir),DirectionPlayerTraits<Dir,P>::offset());
00372       }
00373       template<Player P,class Action,bool mustCareSilver>
00374       void generateOpenOrCapture(const NumEffectState& state,Square target,Piece p,int num,Action& action)
00375       {
00376         // TODO: pin, captureを作る
00377         Direction d=Board_Table.template getShort8<P>(p.square(),target);
00378         Square mid=state.mobilityOf((P==BLACK ? d : inverse(d)),num);
00379         assert(mid.isOnBoard());
00380         const Player altP=PlayerTraits<P>::opponent;
00381         Square mid1=state.kingMobilityOfPlayer(altP,d);
00382         if(mid==mid1){
00383           Piece p1=state.pieceAt(mid);
00384           assert(p1.isPiece());
00385           Square target_next=target-Board_Table.getShort8OffsetUnsafe(p.square(),target);
00386           if((P==BLACK ? p1.pieceIsBlack() : !p1.pieceIsBlack())){
00387             // open attack
00388             PieceOnBoard<Action>::template generate<P,true>(state,p1,action,(1<<primDir(d)));
00389             // p1がtarget_nextに利きを持つ
00390             if(state.hasEffectByPiece(p1,target_next)){
00391               // silverが斜め下に利きを持つ場合は「成らず」しか生成しない
00392               if(mustCareSilver && p1.ptype()==SILVER && 
00393                  (P==BLACK ? target.y()>mid.y() : target.y()<mid.y())){
00394                 // pinの場合は動ける可能性はない 
00395                 if(!state.pinOrOpen(P).test(p1.number())){
00396                   action.unknownMove(mid,target_next,Piece::EMPTY(),SILVER,false,P);
00397                 }
00398               }
00399               else
00400                 PieceOnBoard<Action>::template generatePiece<P>(state,p1,target_next,Piece::EMPTY(),action);
00401             }
00402           }
00403           else{
00404             // 隣の場合はすでに作っている
00405             if(mid==target_next)
00406               return;
00407             PieceOnBoard<Action>::template generatePiece<P>(state,p,mid,p1,action);
00408           }
00409         }
00410       }
00411 
00412       template<osl::Player P,class Action>
00413       void generateRookLongMove(const NumEffectState& state,Square target,Action& action)
00414       {
00415         const Player altP=PlayerTraits<P>::opponent;
00416         for(int num=PtypeTraits<ROOK>::indexMin;num<PtypeTraits<ROOK>::indexLimit;num++){
00417           // pinの場合はすでに作っている
00418           if(state.pinOrOpen(altP).test(num)) continue;
00419           Piece p=state.pieceOf(num);
00420           if(!p.isOnBoardByOwner<P>()) continue;
00421           if(target.isULRD(p.square())){
00422             generateOpenOrCapture<P,Action,false>(state,target,p,num,action);
00423             continue;
00424           }
00425           int target_x=target.x();
00426           int target_y=target.y();
00427           int rook_x=p.square().x();
00428           int rook_y=p.square().y();
00429           if(p.isPromoted()){
00430             if((unsigned int)(target_x-rook_x+1)>2u){ // abs(target_x-rook_x)>1
00431               if((unsigned int)(target_y-rook_y+1)>2u){ // abs(target_y-rook_y)>1
00432                 {
00433                   Square pos(rook_x,target_y);
00434                   Piece p1=state.pieceAt(pos);
00435                   if(state.effectSetAt(pos).test(num) &&
00436                      p1.canMoveOn<P>() &&
00437                      state.kingMobilityAbs(altP,R).uintValue() >= pos.uintValue() &&
00438                      pos.uintValue() >= state.kingMobilityAbs(altP,L).uintValue() &&
00439                      (!state.pinOrOpen(P).test(num) ||
00440                       p.square().isUD(state.kingSquare<P>()))
00441                     ){
00442                     action.unknownMove(p.square(),pos,p1,PROOK,false,P);
00443                   }
00444                 }
00445                 {
00446                   Square pos(target_x,rook_y);
00447                   Piece p1=state.pieceAt(pos);
00448                   if(state.effectSetAt(pos).test(num) &&
00449                      p1.canMoveOn<P>() &&
00450                      state.kingMobilityAbs(altP,U).uintValue() >= pos.uintValue() &&
00451                      pos.uintValue() >= state.kingMobilityAbs(altP,D).uintValue() &&
00452                      (!state.pinOrOpen(P).test(num) ||
00453                       p.square().isLR(state.kingSquare<P>()))
00454                     ){
00455                     action.unknownMove(p.square(),pos,p1,PROOK,false,P);
00456                   }
00457                 }
00458               }
00459               else{ // (abs(target_x-rook_x)>1 && abs(target_y-rook_y)==1
00460                 int min_x=state.kingMobilityAbs(altP,L).x();
00461                 int max_x=state.kingMobilityAbs(altP,R).x();
00462                 if(target_x>rook_x) max_x=target_x-2;
00463                 else min_x=target_x+2;
00464                 min_x=std::max(min_x,rook_x-1);
00465                 max_x=std::min(max_x,rook_x+1);
00466                 for(int x=min_x;x<=max_x;x++){
00467                   Square pos=Square::makeNoCheck(x,target_y);
00468                   Piece p1=state.pieceAt(pos);
00469                   if(p1.canMoveOn<P>())
00470                     PieceOnBoard<Action>::template generatePiecePtype<P,PROOK>(state,p,pos,p1,action);
00471                 }
00472               }
00473             }
00474             else if((unsigned int)(target_y-rook_y+1)>2u){ // abs(target_y-rook_y)>1, abs(target_x-rook_x)==1
00475               int min_y=state.kingMobilityAbs(altP,D).y();
00476               int max_y=state.kingMobilityAbs(altP,U).y();
00477               if(target_y>rook_y) max_y=target_y-2;
00478               else min_y=target_y+2;
00479               min_y=std::max(min_y,rook_y-1);
00480               max_y=std::min(max_y,rook_y+1);
00481               for(int y=min_y;y<=max_y;y++){
00482                 Square pos=Square::makeNoCheck(target_x,y);
00483                 Piece p1=state.pieceAt(pos);
00484                 if(p1.canMoveOn<P>())
00485                   PieceOnBoard<Action>::template generatePiecePtype<P,PROOK>(state,p,pos,p1,action);
00486               }
00487             }
00488           }
00489           else{ // ROOK
00490             // vertical move
00491             if((unsigned int)(target_x-rook_x+1)>2u){ // abs(target_x-rook_x)>1
00492               Square pos(rook_x,target_y);
00493               Piece p1=state.pieceAt(pos);
00494               if(state.effectSetAt(pos).test(num) &&
00495                  p1.canMoveOn<P>() &&
00496                  state.kingMobilityAbs(altP,R).uintValue() >= pos.uintValue() &&
00497                  pos.uintValue() >= state.kingMobilityAbs(altP,L).uintValue() &&
00498                  (!state.pinOrOpen(P).test(num) ||
00499                   p.square().isUD(state.kingSquare<P>()))
00500                 ){
00501                 if(Square::canPromoteY<P>(rook_y) || Square::canPromoteY<P>(target_y)){
00502                   action.unknownMove(p.square(),pos,p1,PROOK,true,P);
00503                 }
00504                 else action.unknownMove(p.square(),pos,p1,ROOK,false,P);
00505               }
00506             }
00507             // horizontal move
00508             if((unsigned int)(target_y-rook_y+1)>2u){ // abs(target_y-rook_y)>1
00509               Square pos(target_x,rook_y);
00510               Piece p1=state.pieceAt(pos);
00511               if(state.effectSetAt(pos).test(num) &&
00512                  p1.canMoveOn<P>() &&
00513                  state.kingMobilityAbs(altP,U).uintValue() >= pos.uintValue() &&
00514                  pos.uintValue() >= state.kingMobilityAbs(altP,D).uintValue() &&
00515                  (!state.pinOrOpen(P).test(num) ||
00516                   p.square().isLR(state.kingSquare<P>()))
00517                 ){
00518                 if(Square::canPromoteY<P>(rook_y)){
00519                   action.unknownMove(p.square(),pos,p1,PROOK,true,P);
00520                 }
00521                 else
00522                   action.unknownMove(p.square(),pos,p1,ROOK,false,P);
00523               }
00524             }
00525           }
00526         }
00527       }
00528       template<osl::Player P,class Action>
00529       void generateRookLongMoveNotKing(const NumEffectState& state,Square target,Action& action,CArray<unsigned char,8> const& pieceMobility)
00530       {
00531         for(int num=PtypeTraits<ROOK>::indexMin;num<PtypeTraits<ROOK>::indexLimit;num++){
00532           Piece p=state.pieceOf(num);
00533           if(!p.isOnBoardByOwner<P>()) continue;
00534           if(target.isULRD(p.square())){
00535             continue;
00536           }
00537           int dirMask=0; // can move to all direction 
00538           if(state.pin(P).test(num)){
00539             Direction d=state.pinnedDir<P>(p);
00540             dirMask=(~(1<<primDir(d)));
00541           }
00542           int target_x=target.x();
00543           int target_y=target.y();
00544           int rook_x=p.square().x();
00545           int rook_y=p.square().y();
00546           if(p.isPromoted()){
00547             if((unsigned int)(target_x-rook_x+1)>2u){ // abs(target_x-rook_x)>1
00548               if((unsigned int)(target_y-rook_y+1)>2u){ // abs(target_y-rook_y)>1
00549                 {
00550                   Square pos(rook_x,target_y);
00551                   Piece p1=state.pieceAt(pos);
00552                   if(p1.canMoveOn<P>() &&
00553                      pieceMobility[R] > pos.uintValue() &&
00554                      pos.uintValue() > pieceMobility[L] &&
00555                      (dirMask&(1<<U))==0 &&
00556                      state.effectSetAt(pos).test(num)
00557                     ){
00558                     action.unknownMove(p.square(),pos,p1,PROOK,false,P);
00559                   }
00560                 }
00561                 {
00562                   Square pos(target_x,rook_y);
00563                   Piece p1=state.pieceAt(pos);
00564                   if(p1.canMoveOn<P>() &&
00565                      pieceMobility[U] > pos.uintValue() &&
00566                      pos.uintValue() > pieceMobility[D] &&
00567                      (dirMask&(1<<L))==0 &&
00568                      state.effectSetAt(pos).test(num)){
00569                     action.unknownMove(p.square(),pos,p1,PROOK,false,P);
00570                   }
00571                 }
00572               }
00573               else{ // (abs(target_x-rook_x)>1 && abs(target_y-rook_y)==1
00574                 int min_x=Square::makeDirect(pieceMobility[L]).x()+1;
00575                 int max_x=Square::makeDirect(pieceMobility[R]).x()-1;
00576                 if(target_x>rook_x) max_x=target_x-2;
00577                 else min_x=target_x+2;
00578                 min_x=std::max(min_x,rook_x-1);
00579                 max_x=std::min(max_x,rook_x+1);
00580                 for(int x=min_x;x<=max_x;x++){
00581                   Square pos=Square::makeNoCheck(x,target_y);
00582                   if(((1<<primDirUnsafe(Board_Table.getShort8Unsafe<P>(p.square(),pos)))&dirMask)!=0) continue;
00583                   Piece p1=state.pieceAt(pos);
00584                   if(p1.canMoveOn<P>())
00585                     action.unknownMove(p.square(),pos,p1,PROOK,false,P);
00586                 }
00587               }
00588             }
00589             else if((unsigned int)(target_y-rook_y+1)>2u){ // abs(target_y-rook_y)>1, abs(target_x-rook_x)==1
00590               int min_y=Square::makeDirect(pieceMobility[D]).y()+1;
00591               int max_y=Square::makeDirect(pieceMobility[U]).y()-1;
00592               if(target_y>rook_y) max_y=target_y-2;
00593               else min_y=target_y+2;
00594               min_y=std::max(min_y,rook_y-1);
00595               max_y=std::min(max_y,rook_y+1);
00596               for(int y=min_y;y<=max_y;y++){
00597                 Square pos=Square::makeNoCheck(target_x,y);
00598                 if(((1<<primDirUnsafe(Board_Table.getShort8Unsafe<P>(p.square(),pos)))&dirMask)!=0) continue;
00599                 Piece p1=state.pieceAt(pos);
00600                 if(p1.canMoveOn<P>())
00601                   action.unknownMove(p.square(),pos,p1,PROOK,false,P);
00602               }
00603             }
00604           }
00605           else{ // ROOK
00606             // vertical move
00607             if((unsigned int)(target_x-rook_x+1)>2u){ // abs(target_x-rook_x)>1
00608               Square pos(rook_x,target_y);
00609               Piece p1=state.pieceAt(pos);
00610               if(p1.canMoveOn<P>() &&
00611                  pieceMobility[R] > pos.uintValue() &&
00612                  pos.uintValue() > pieceMobility[L] &&
00613                  (dirMask&(1<<U))==0 &&
00614                  state.effectSetAt(pos).test(num)
00615                 ){
00616                 if(Square::canPromoteY<P>(rook_y) || Square::canPromoteY<P>(target_y)){
00617                   action.unknownMove(p.square(),pos,p1,PROOK,true,P);
00618                 }
00619                 else
00620                   action.unknownMove(p.square(),pos,p1,ROOK,false,P);
00621               }
00622             }
00623             // horizontal move
00624             if((unsigned int)(target_y-rook_y+1)>2u){ // abs(target_y-rook_y)>1
00625               Square pos(target_x,rook_y);
00626               Piece p1=state.pieceAt(pos);
00627               if(p1.template canMoveOn<P>() &&
00628                  pieceMobility[U] > pos.uintValue() &&
00629                  pos.uintValue() > pieceMobility[D] &&
00630                  (dirMask&(1<<L))==0 &&
00631                  state.effectSetAt(pos).test(num)
00632                 ){
00633                 if(Square::canPromoteY<P>(rook_y)){
00634                   action.unknownMove(p.square(),pos,p1,PROOK,true,P);
00635                 }
00636                 else
00637                   action.unknownMove(p.square(),pos,p1,ROOK,false,P);
00638               }
00639             }
00640           }
00641         }
00642       }
00643       template<Player P,Ptype T,class Action>
00644       void generateBishopLongMove(const NumEffectState& state,Square target,Action& action,Piece p,int num)
00645       {
00646         const Player altP=PlayerTraits<P>::opponent;
00647         int target_x=target.x();
00648         int target_y=target.y();
00649         int target_xPy=target_x+target_y;
00650         int target_xMy=target_x-target_y;
00651         int bishop_x=p.square().x();
00652         int bishop_y=p.square().y();
00653         int bishop_xPy=bishop_x+bishop_y;
00654         int bishop_xMy=bishop_x-bishop_y;
00655         if(((target_xPy^bishop_xPy)&1)!=0){
00656           if(T==BISHOP) return;
00657           // 市松模様のparityの違う場合も,隣ならOK?
00658           if((unsigned int)(target_xPy-bishop_xPy+1)<=2u){ // abs(target_xPy-bishop_xPy)==1
00659             Square ul=state.kingMobilityAbs(altP,UL);
00660             Square dr=state.kingMobilityAbs(altP,DR);
00661             int min_xMy=ul.x()-ul.y();
00662             int max_xMy=dr.x()-dr.y();
00663             if(target_xMy>bishop_xMy) max_xMy=target_xMy-4;
00664             else min_xMy=target_xMy+4;
00665             min_xMy=std::max(min_xMy,bishop_xMy-1);
00666             max_xMy=std::min(max_xMy,bishop_xMy+1);
00667             for(int xMy=min_xMy;xMy<=max_xMy;xMy+=2){
00668               int pos_x=(target_xPy+xMy)>>1;
00669               int pos_y=(target_xPy-xMy)>>1;
00670               Square pos=Square::makeNoCheck(pos_x,pos_y);
00671               Piece p1=state.pieceAt(pos);
00672               if(p1.canMoveOn<P>())
00673                 PieceOnBoard<Action>::template generatePiecePtype<P,T>(state,p,pos,p1,action);
00674             }
00675           }
00676           else if((unsigned int)(target_xMy-bishop_xMy+1)<=2u){ // abs(target_xMy-bishop_xMy)==1
00677             Square dl=state.kingMobilityAbs(altP,DL);
00678             Square ur=state.kingMobilityAbs(altP,UR);
00679             int min_xPy=dl.x()+dl.y();
00680             int max_xPy=ur.x()+ur.y();
00681             if(target_xPy>bishop_xPy) max_xPy=target_xPy-4;
00682             else min_xPy=target_xPy+4;
00683             min_xPy=std::max(min_xPy,bishop_xPy-1);
00684             max_xPy=std::min(max_xPy,bishop_xPy+1);
00685             for(int xPy=min_xPy;xPy<=max_xPy;xPy+=2){
00686               int pos_x=(xPy+target_xMy)>>1;
00687               int pos_y=(xPy-target_xMy)>>1;
00688               Square pos=Square::makeNoCheck(pos_x,pos_y);
00689               Piece p1=state.pieceAt(pos);
00690               if(p1.canMoveOn<P>())
00691                 PieceOnBoard<Action>::template generatePiecePtype<P,T>(state,p,pos,p1,action);
00692             }
00693           }
00694           return;
00695         }
00696         //  / 方向(dx==dy)から王手をかける
00697         if((unsigned int)(target_xPy-bishop_xPy+2)>4u){ // abs(target_xPy-bishop_xPy)>2
00698           int pos_x=(bishop_xPy+target_xMy)>>1;
00699           int pos_y=(bishop_xPy-target_xMy)>>1;
00700           Square pos=Square::makeNoCheck(pos_x,pos_y);
00701           if(pos.isOnBoard()){
00702             Piece p1=state.pieceAt(pos);
00703             if(state.effectSetAt(pos).test(num) &&
00704                p1.canMoveOn<P>() &&
00705                state.kingMobilityAbs(altP,UR).uintValue() >= pos.uintValue() &&
00706                pos.uintValue() >= state.kingMobilityAbs(altP,DL).uintValue()
00707               ){
00708               PieceOnBoard<Action>::template generatePiecePtype<P,T>(state,p,pos,p1,action);
00709             }
00710           }
00711         }
00712         else if(target_xPy==bishop_xPy){
00713           generateOpenOrCapture<P,Action,true>(state,target,p,num,action);
00714           return;
00715         }
00716         //  \ 方向(dx== -dy)から王手をかける
00717         if((unsigned int)(target_xMy-bishop_xMy+2)>4u){ // abs(target_xMy-bishop_xMy)>2
00718           int pos_x=(target_xPy+bishop_xMy)>>1;
00719           int pos_y=(target_xPy-bishop_xMy)>>1;
00720           Square pos=Square::makeNoCheck(pos_x,pos_y);
00721           if(pos.isOnBoard()){
00722             Piece p1=state.pieceAt(pos);
00723             if(state.effectSetAt(pos).test(num) &&
00724                p1.canMoveOn<P>() &&
00725                state.kingMobilityAbs(altP,DR).uintValue() >= pos.uintValue() &&
00726                pos.uintValue() >= state.kingMobilityAbs(altP,UL).uintValue()
00727               ){
00728               PieceOnBoard<Action>::template generatePiecePtype<P,T>(state,p,pos,p1,action);
00729             }
00730           }
00731         }
00732         else if(target_xMy==bishop_xMy){
00733           generateOpenOrCapture<P,Action,true>(state,target,p,num,action);
00734           return;
00735         }
00736 
00737       }
00738       template<osl::Player P,Ptype T,class Action>
00739       void generateBishopLongMoveNotKing(const NumEffectState& state,Square target,Action& action,CArray<unsigned char,8> const& pieceMobility,Piece p,int num)
00740       {
00741         int target_x=target.x();
00742         int target_y=target.y();
00743         int target_xPy=target_x+target_y;
00744         int target_xMy=target_x-target_y;
00745         int bishop_x=p.square().x();
00746         int bishop_y=p.square().y();
00747         int bishop_xPy=bishop_x+bishop_y;
00748         int bishop_xMy=bishop_x-bishop_y;
00749         if(((target_xPy^bishop_xPy)&1)!=0){
00750           if(T!=PBISHOP) return;
00751           // 市松模様のparityの違う場合も,隣ならOK?
00752           if((unsigned int)(target_xPy-bishop_xPy+1)<=2u){ // abs(target_xPy-bishop_xPy)==1
00753             Square ul=Square::makeDirect(pieceMobility[UL]);
00754             Square dr=Square::makeDirect(pieceMobility[DR]);
00755             int min_xMy=ul.x()-ul.y()+2;
00756             int max_xMy=dr.x()-dr.y()-2;
00757             if(target_xMy>bishop_xMy) max_xMy=target_xMy-4;
00758             else min_xMy=target_xMy+4;
00759             min_xMy=std::max(min_xMy,bishop_xMy-1);
00760             max_xMy=std::min(max_xMy,bishop_xMy+1);
00761             for(int xMy=min_xMy;xMy<=max_xMy;xMy+=2){
00762               int pos_x=(target_xPy+xMy)>>1;
00763               int pos_y=(target_xPy-xMy)>>1;
00764               Square pos=Square::makeNoCheck(pos_x,pos_y);
00765               Piece p1=state.pieceAt(pos);
00766               if(p1.canMoveOn<P>())
00767                 PieceOnBoard<Action>::template generatePiecePtype<P,T>(state,p,pos,p1,action);
00768             }
00769             return;
00770           }
00771           else if((unsigned int)(target_xMy-bishop_xMy+1)<=2u){ // abs(target_xMy-bishop_xMy)==1
00772             Square dl=Square::makeDirect(pieceMobility[DL]);
00773             Square ur=Square::makeDirect(pieceMobility[UR]);
00774             int min_xPy=dl.x()+dl.y()+2;
00775             int max_xPy=ur.x()+ur.y()-2;
00776             if(target_xPy>bishop_xPy) max_xPy=target_xPy-4;
00777             else min_xPy=target_xPy+4;
00778             min_xPy=std::max(min_xPy,bishop_xPy-1);
00779             max_xPy=std::min(max_xPy,bishop_xPy+1);
00780             for(int xPy=min_xPy;xPy<=max_xPy;xPy+=2){
00781               int pos_x=(xPy+target_xMy)>>1;
00782               int pos_y=(xPy-target_xMy)>>1;
00783               Square pos=Square::makeNoCheck(pos_x,pos_y);
00784               Piece p1=state.pieceAt(pos);
00785               if(p1.canMoveOn<P>())
00786                 PieceOnBoard<Action>::template generatePiecePtype<P,T>(state,p,pos,p1,action);
00787             }
00788           }
00789           return;
00790         }
00791         //  / 方向(dx==dy)から王手をかける
00792         if((unsigned int)(target_xPy-bishop_xPy+2)>4u){ // abs(target_xPy-bishop_xPy)>2
00793           int pos_x=(bishop_xPy+target_xMy)>>1;
00794           int pos_y=(bishop_xPy-target_xMy)>>1;
00795           Square pos=Square::makeNoCheck(pos_x,pos_y);
00796           if(pos.isOnBoard()){
00797             if(pieceMobility[UR] > pos.uintValue() &&
00798                pos.uintValue() > pieceMobility[DL] &&
00799                state.effectSetAt(pos).test(num)){
00800               Piece p1=state.pieceAt(pos);
00801               if(p1.canMoveOn<P>())
00802                 PieceOnBoard<Action>::template generatePiecePtype<P,T>(state,p,pos,p1,action);
00803             }
00804           }
00805         }
00806         //  \ 方向(dx== -dy)から王手をかける
00807         if((unsigned int)(target_xMy-bishop_xMy+2)>4u){ // abs(target_xMy-bishop_xMy)>2
00808           int pos_x=(target_xPy+bishop_xMy)>>1;
00809           int pos_y=(target_xPy-bishop_xMy)>>1;
00810           Square pos=Square::makeNoCheck(pos_x,pos_y);
00811           if(pos.isOnBoard()){
00812             if(pieceMobility[DR] > pos.uintValue() &&
00813                pos.uintValue() > pieceMobility[UL] &&
00814                state.effectSetAt(pos).test(num)
00815               ){
00816               Piece p1=state.pieceAt(pos);
00817               if(p1.canMoveOn<P>())
00818                 PieceOnBoard<Action>::template generatePiecePtype<P,T>(state,p,pos,p1,action);
00819             }
00820           }
00821         }
00822       }
00823     
00824       template<Player P,class Action>
00825       void generateDropGold(const NumEffectState& state,Square target,Action& action,int spaces)
00826       {
00827         if(!state.hasPieceOnStand<GOLD>(P)) return;
00828         unsigned int gold_mask=spaces&((1<<U)|(1<<UR)|(1<<UL)|(1<<L)|(1<<R)|(1<<D));
00829         if(gold_mask==0) return;
00830         generateDropDir<P,Action,U>(target,action,gold_mask,GOLD);
00831         generateDropDir<P,Action,UL>(target,action,gold_mask,GOLD);
00832         generateDropDir<P,Action,UR>(target,action,gold_mask,GOLD);
00833         generateDropDir<P,Action,L>(target,action,gold_mask,GOLD);
00834         generateDropDir<P,Action,R>(target,action,gold_mask,GOLD);
00835         generateDropDir<P,Action,D>(target,action,gold_mask,GOLD);
00836       }
00837       template<Player P,class Action>
00838       void generateDropSilver(const NumEffectState& state,Square target,Action& action,int spaces)
00839       {
00840         if(!state.hasPieceOnStand<SILVER>(P)) return;
00841         unsigned int silver_mask=spaces&((1<<U)|(1<<UR)|(1<<UL)|(1<<DL)|(1<<DR));
00842         if(silver_mask ==0) return;
00843 
00844         generateDropDir<P,Action,DL>(target,action,silver_mask,SILVER);
00845         generateDropDir<P,Action,DR>(target,action,silver_mask,SILVER);
00846         generateDropDir<P,Action,U>(target,action,silver_mask,SILVER);
00847         generateDropDir<P,Action,UL>(target,action,silver_mask,SILVER);
00848         generateDropDir<P,Action,UR>(target,action,silver_mask,SILVER);
00849       }
00853       template<Player P,class Action,bool allEmpty>
00854       void generateDropBishop(const NumEffectState& state,Square target,Action& action,Square ul,Square dr,Square ur,Square dl)
00855       {
00856         for(Square pos=dl+DirectionPlayerTraits<DL,P>::offset();
00857             pos!=target;pos+=DirectionPlayerTraits<DL,P>::offset())
00858           if(allEmpty || state.pieceAt(pos).isEmpty())
00859             action.dropMove(pos,BISHOP,P);
00860         for(Square pos=dr-DirectionPlayerTraits<UL,P>::offset();
00861             pos!=target;pos-=DirectionPlayerTraits<UL,P>::offset())
00862           if(allEmpty || state.pieceAt(pos).isEmpty())
00863             action.dropMove(pos,BISHOP,P);
00864         for(Square pos=ul+DirectionPlayerTraits<UL,P>::offset();
00865             pos!=target;pos+=DirectionPlayerTraits<UL,P>::offset())
00866           if(allEmpty || state.pieceAt(pos).isEmpty())
00867             action.dropMove(pos,BISHOP,P);
00868         for(Square pos=ur-DirectionPlayerTraits<DL,P>::offset();
00869             pos!=target;pos-=DirectionPlayerTraits<DL,P>::offset())
00870           if(allEmpty || state.pieceAt(pos).isEmpty())
00871             action.dropMove(pos,BISHOP,P);
00872       }
00873 
00874       template<Player P,class Action,bool allEmpty>
00875       void generateDropRook(const NumEffectState& state,Square target,Action& action,Square l,Square r,Square d,Square u)
00876       {
00877         for(Square pos=u-DirectionPlayerTraits<D,P>::offset();
00878             pos!=target;pos-=DirectionPlayerTraits<D,P>::offset())
00879           if(allEmpty || state.pieceAt(pos).isEmpty())
00880             action.dropMove(pos,ROOK,P);
00881         for(Square pos=l+DirectionPlayerTraits<L,P>::offset();
00882             pos!=target;pos+=DirectionPlayerTraits<L,P>::offset())
00883           if(allEmpty || state.pieceAt(pos).isEmpty())
00884             action.dropMove(pos,ROOK,P);
00885         for(Square pos=r-DirectionPlayerTraits<L,P>::offset();
00886             pos!=target;pos-=DirectionPlayerTraits<L,P>::offset())
00887           if(allEmpty || state.pieceAt(pos).isEmpty())
00888             action.dropMove(pos,ROOK,P);
00889         for(Square pos=d+DirectionPlayerTraits<D,P>::offset();
00890             pos!=target;pos+=DirectionPlayerTraits<D,P>::offset())
00891           if(allEmpty || state.pieceAt(pos).isEmpty())
00892             action.dropMove(pos,ROOK,P);
00893       }
00894       template<osl::Player P,class Action>
00895       void generateKing(const NumEffectState& state,Square target,Action& action,bool &hasPawnCheckmate)
00896       {
00897         
00898         const Player altP=PlayerTraits<P>::opponent;
00899         assert(target==state.kingSquare(altP));
00900         generateDir<P,0,Action,U>(state,target,action,hasPawnCheckmate);
00901         generateKnightAll<P,Action>(state,target,action);
00902         generateDir<P,2,Action,UL>(state,target,action,hasPawnCheckmate);
00903         generateDir<P,2,Action,UR>(state,target,action,hasPawnCheckmate);
00904         generateDir<P,1,Action,L>(state,target,action,hasPawnCheckmate);
00905         generateDir<P,1,Action,R>(state,target,action,hasPawnCheckmate);
00906         generateDir<P,1,Action,D>(state,target,action,hasPawnCheckmate);
00907         generateDir<P,2,Action,DL>(state,target,action,hasPawnCheckmate);
00908         generateDir<P,2,Action,DR>(state,target,action,hasPawnCheckmate);
00909         detail::generateRookLongMove<P,Action>(state,target,action);
00910         for(int num=PtypeTraits<BISHOP>::indexMin;num<PtypeTraits<BISHOP>::indexLimit;num++){
00911           // pinの場合はすでに作っている
00912           if(state.pinOrOpen(altP).test(num)) continue;
00913           Piece p=state.pieceOf(num);
00914           if(!p.isOnBoardByOwner<P>()) continue;
00915           if(p.isPromoted())
00916             generateBishopLongMove<P,PBISHOP,Action>(state,target,action,p,num);
00917           else
00918             generateBishopLongMove<P,BISHOP,Action>(state,target,action,p,num);
00919         }
00920         int spaces=King8Info(state.Iking8Info(altP)).spaces();
00921         generateDropGold<P,Action>(state,target,action,spaces);
00922         generateDropSilver<P,Action>(state,target,action,spaces);
00923         // bishop
00924         if(state.hasPieceOnStand<BISHOP>(P)){
00925           generateDropBishop<P,Action,true>(state,target,action,
00926                                             state.kingMobilityOfPlayer(altP,UL),
00927                                             state.kingMobilityOfPlayer(altP,DR),
00928                                             state.kingMobilityOfPlayer(altP,UR),
00929                                             state.kingMobilityOfPlayer(altP,DL));
00930         }
00931         if(state.hasPieceOnStand<ROOK>(P)){
00932           Square l,r,d,u;
00933           l=state.kingMobilityOfPlayer(altP,L);
00934           r=state.kingMobilityOfPlayer(altP,R);
00935           d=state.kingMobilityOfPlayer(altP,D);
00936           u=state.kingMobilityOfPlayer(altP,U);
00937           generateDropRook<P,Action,true>(state,target,action,l,r,d,u);
00938         }
00939       }
00940       template<osl::Player P,class Action>
00941       void generateNotKing(const NumEffectState& state,Square target,Action& action)
00942       {
00943         int spaces=0;
00944         CArray<unsigned char,8> pieceMobility;
00945         PieceMask notPieceMask;
00946         notPieceMask.setAll();
00947         int num=state.pieceAt(target).number();
00948         if(num != EMPTY_NUM){
00949           notPieceMask.reset(num);
00950         }
00951         generateDirNotKing<P,0,Action,U>(state,target,action,pieceMobility,spaces,notPieceMask);
00952         generateKnightAll<P,Action>(state,target,action);
00953         generateDirNotKing<P,2,Action,UL>(state,target,action,pieceMobility,spaces,notPieceMask);
00954         generateDirNotKing<P,2,Action,UR>(state,target,action,pieceMobility,spaces,notPieceMask);
00955         generateDirNotKing<P,1,Action,L>(state,target,action,pieceMobility,spaces,notPieceMask);
00956         generateDirNotKing<P,1,Action,R>(state,target,action,pieceMobility,spaces,notPieceMask);
00957         generateDirNotKing<P,1,Action,D>(state,target,action,pieceMobility,spaces,notPieceMask);
00958         generateDirNotKing<P,2,Action,DL>(state,target,action,pieceMobility,spaces,notPieceMask);
00959         generateDirNotKing<P,2,Action,DR>(state,target,action,pieceMobility,spaces,notPieceMask);
00960         // rookが移動する手
00961         generateRookLongMoveNotKing<P,Action>(state,target,action,pieceMobility);
00962         // bishopが移動する手
00963         for(int num=PtypeTraits<BISHOP>::indexMin;num<PtypeTraits<BISHOP>::indexLimit;num++){
00964           Piece p=state.pieceOf(num);
00965           if(!p.isOnBoardByOwner<P>()) continue;
00966           if(p.isPromoted())
00967             generateBishopLongMoveNotKing<P,PBISHOP,Action>(state,target,action,pieceMobility,p,num);
00968           else
00969             generateBishopLongMoveNotKing<P,BISHOP,Action>(state,target,action,pieceMobility,p,num);
00970         }
00971         generateDropGold<P,Action>(state,target,action,spaces);
00972         generateDropSilver<P,Action>(state,target,action,spaces);
00973         if(state.hasPieceOnStand<BISHOP>(P)){
00974           Square ul,dr,dl,ur;
00975           ul=Square::makeDirect(pieceMobility[P==BLACK ? UL : DR]);
00976           dr=Square::makeDirect(pieceMobility[P==BLACK ? DR : UL]);
00977           ur=Square::makeDirect(pieceMobility[P==BLACK ? UR : DL]);
00978           dl=Square::makeDirect(pieceMobility[P==BLACK ? DL : UR]);
00979           generateDropBishop<P,Action,false>(state,target,action,ul,dr,ur,dl);
00980         }
00981         if(state.hasPieceOnStand<ROOK>(P)){
00982           Square l,r,d,u;
00983           l=Square::makeDirect(pieceMobility[P==BLACK ? L : R]);
00984           r=Square::makeDirect(pieceMobility[P==BLACK ? R : L]);
00985           d=Square::makeDirect(pieceMobility[P==BLACK ? D : U]);
00986           u=Square::makeDirect(pieceMobility[P==BLACK ? U : D]);
00987           generateDropRook<P,Action,false>(state,target,action,l,r,d,u);
00988         }
00989       }
00990     } // namespace detail
00991     template <class Action>
00992     template <osl::Player P,bool isAttackToKing>
00993     void osl::move_generator::AddEffectWithEffect<Action>::
00994     generate(const NumEffectState& state,Square target,Action& action,bool &hasPawnCheckmate)
00995     {
00996       if(!isAttackToKing){
00997         detail::template generateNotKing<P,Action>(state,target,action);
00998       }
00999       else{
01000         detail::template generateKing<P,Action>(state,target,action,hasPawnCheckmate);
01001       }
01002     }
01003     template<bool isAttackToKing>
01004     void osl::move_generator::GenerateAddEffectWithEffect::
01005     generate(Player player, const NumEffectState& state, Square target, 
01006              move_action::Store& store)
01007     {
01008       using namespace osl::move_action;
01009       bool dummy;
01010       if(player==BLACK){
01011         AddEffectWithEffect<Store>::generate<BLACK,isAttackToKing>(state,target,store,dummy);
01012       }
01013       else{
01014         AddEffectWithEffect<Store>::generate<WHITE,isAttackToKing>(state,target,store,dummy);
01015       }
01016     }
01017 
01018   } // namespace move_generator
01019 } // namespace osl
01020 #endif /* _GENERATER_ADD_EFFECT_WITH_EFFECT_TCC */
01021 // ;;; Local Variables:
01022 // ;;; mode:c++
01023 // ;;; c-basic-offset:2
01024 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines