pieceOnBoard.tcc
Go to the documentation of this file.
00001 #ifndef _GENERATE_PIECE_MOVES_TCC
00002 #define _GENERATE_PIECE_MOVES_TCC
00003 #include "osl/move_generator/promoteType.h"
00004 #include "osl/move_action/store.h"
00005 #include "osl/move_generator/pieceOnBoard.h"
00006 #include "osl/move_action/concept.h"
00007 #include "osl/checkmate/king8Info.h"
00008 #include <iostream>
00009 namespace osl
00010 {
00011   namespace move_generator
00012   {
00013     namespace piece_on_board
00014     {
00022       template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
00023       inline void 
00024       generateLong(NumEffectState const& state,Piece p,const Piece *ptr,Square from,Action& action,Int2Type<true>,Move moveBase,Ptype ptype)
00025       {
00026         int num=p.number();
00027         const Direction shortDir=longToShort(Dir);
00028         Square limit=state.mobilityOf((P==BLACK ? shortDir : inverse(shortDir)),num);
00029         const Piece *limitPtr=state.getPiecePtr(limit);
00030         assert(ptype!=LANCE);
00031         const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00032         assert(!offset.zero());
00033         ptr+=offset.intValue();
00034         Square to=from+offset;
00035         Move m=moveBase.newAddTo(offset);
00036         if(CanP==CheckPromoteType || CanP==CanPromoteType){
00037           if(CanP==CheckPromoteType){
00038             // promoteできない数
00039             int count=(P==BLACK ? from.y1()-5 : 7-from.y1()); 
00040             for(int i=0;i<count;i++){
00041               if(ptr==limitPtr){
00042                 Piece p1= *limitPtr;
00043                 if(!notPromoteCapture && p1.canMoveOn<P>())
00044                   action.unknownMove(from,to,p1,ptype,false,P,m.newAddCapture(p1));
00045                 return;
00046               }
00047               action.simpleMove(from,to,ptype,false,P,m);
00048               ptr+=offset.intValue();
00049               to+=offset; m=m.newAddTo(offset);
00050             }
00051           }
00052           if(notPromoteCapture) return;
00053           while(ptr!=limitPtr){
00054             assert(from.canPromote<P>() || to.canPromote<P>());
00055             action.simpleMove(from,to,promote(ptype),true,P,m.promote());
00056             ptr+=offset.intValue();
00057             to+=offset;
00058             m=m.newAddTo(offset);
00059           }
00060           Piece p1= *limitPtr;
00061           if(p1.canMoveOn<P>()){
00062             m=m.newAddCapture(p1);
00063             assert(from.canPromote<P>() || to.canPromote<P>());
00064             action.unknownMove(from,to,p1,promote(ptype),true,P,m.promote());
00065           }
00066         }
00067         else{ // NoPromote
00068           while(ptr!=limitPtr){
00069             action.simpleMove(from,to,ptype,false,P,m);
00070             ptr+=offset.intValue();
00071             to+=offset; m=m.newAddTo(offset);
00072           }
00073           if(notPromoteCapture) return;
00074           Piece p1= *limitPtr;
00075           if(p1.canMoveOn<P>()){
00076             m=m.newAddCapture(p1);
00077             action.unknownMove(from,to,p1,ptype,false,P,m);
00078           }
00079         }
00080       }
00081       template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
00082       inline void 
00083       generateLong(NumEffectState const&,Piece,const Piece *, Square,Action&,Int2Type<false>,Move,Ptype)
00084       {
00085       }
00086 
00087       template <Player P,Ptype T,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
00088       inline void
00089       generateLong(NumEffectState const& state,Piece p,const Piece *ptr, Square pos,Action& action,Move moveBase,Ptype ptype)
00090       {
00091         generateLong<P,Action,
00092           (CanP != CheckPromoteType ? CanP : (DirectionTraits<Dir>::canPromoteTo ? CheckPromoteType : NoPromoteType)),
00093           Dir,notPromoteCapture>(state,p,ptr,pos,action,
00094                Int2Type<(PtypeTraits<T>::moveMask & DirectionTraits<Dir>::mask) !=0>(),moveBase,ptype);
00095     }
00096 
00102       template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
00103       void 
00104       generateShort(const Piece *ptr,Square from,Action& action,Int2Type<true>,Move moveBase,Ptype ptype)
00105       {
00106         const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00107         Piece p1=ptr[offset.intValue()];        
00108         Square to=from+offset;
00109         Move m=moveBase.newAddTo(offset).newAddCapture(p1);
00110         if ((notPromoteCapture ? p1.isEmpty() : p1.canMoveOn<P>())){
00111           if (!notPromoteCapture && (CanP==CanPromoteType || CanP==MustPromoteType))
00112             action.unknownMove(from,to,p1,promote(ptype),true,P,m.promote());
00113           if (CanP!=MustPromoteType)
00114             action.unknownMove(from,to,p1,ptype,false,P,m);
00115         }
00116       }
00117 
00118       template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
00119     void 
00120       generateShort(const Piece */*ptr*/,Square /*from*/,Action& /*action*/,Int2Type<false>,Move /*moveBase*/,Ptype /*ptype*/)
00121     {
00122     }
00123 
00124       template <Player P,Ptype T,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
00125     void 
00126       generateShort(const Piece *ptr,Square from,Action& action,Move moveBase,Ptype /*ptype*/)
00127     {
00128       generateShort<P,Action,
00129         (CanP != CheckPromoteType ? CanP : (DirectionTraits<Dir>::canPromoteTo ? CanPromoteType : NoPromoteType)),
00130         Dir,notPromoteCapture>(ptr,from,action,
00131              Int2Type<(PtypeTraits<T>::moveMask & DirectionTraits<Dir>::mask) !=0>(),
00132              moveBase,T);
00133   }
00134 
00135       template <Player P,Ptype T,class Action,PromoteType CanP,bool useDirMask,bool notPromoteCapture>
00136     inline void
00137     generatePtypePromote(const NumEffectState& state,Piece p, Action& action,Square from,int dirMask)
00138     {
00139       const Ptype ptype=(T==GOLD ? p.ptype() : T);
00140       Move moveBase=Move(from,from,ptype,(Ptype)0,false,P);
00141       const Piece *ptr=state.getPiecePtr(from);
00142       if(!useDirMask || (dirMask&(1<<UL))==0){
00143         generateShort<P,T,Action,CanP,UL,notPromoteCapture>(ptr,from,action,moveBase,ptype);
00144         generateShort<P,T,Action,CanP,DR,notPromoteCapture>(ptr,from,action,moveBase,ptype);
00145         generateLong<P,T,Action,CanP,LONG_UL,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
00146         generateLong<P,T,Action,CanP,LONG_DR,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
00147       }
00148       if(!useDirMask || (dirMask&(1<<UR))==0){
00149         generateShort<P,T,Action,CanP,UR,notPromoteCapture>(ptr,from,action,moveBase,ptype);
00150         generateShort<P,T,Action,CanP,DL,notPromoteCapture>(ptr,from,action,moveBase,ptype);
00151         generateLong<P,T,Action,CanP,LONG_UR,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
00152         generateLong<P,T,Action,CanP,LONG_DL,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
00153       }
00154       if(!useDirMask || (dirMask&(1<<U))==0){
00155         generateShort<P,T,Action,CanP,U,notPromoteCapture>(ptr,from,action,moveBase,ptype);
00156         generateShort<P,T,Action,CanP,D,notPromoteCapture>(ptr,from,action,moveBase,ptype);
00157         generateLong<P,T,Action,CanP,LONG_U,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
00158         generateLong<P,T,Action,CanP,LONG_D,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
00159       }
00160       if(!useDirMask || (dirMask&(1<<L))==0){
00161         generateShort<P,T,Action,CanP,L,notPromoteCapture>(ptr,from,action,moveBase,ptype);
00162         generateShort<P,T,Action,CanP,R,notPromoteCapture>(ptr,from,action,moveBase,ptype);
00163         generateLong<P,T,Action,CanP,LONG_L,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
00164         generateLong<P,T,Action,CanP,LONG_R,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
00165       }
00166       generateShort<P,T,Action,CanP,UUL,notPromoteCapture>(ptr,from,action,moveBase,ptype);
00167       generateShort<P,T,Action,CanP,UUR,notPromoteCapture>(ptr,from,action,moveBase,ptype);
00168     }
00169       
00170       template <Player P,Direction Dir,class Action,bool notPromoteCapture>
00171   inline void
00172   generateKingDir(const Piece *ptr, Square from,Action& action,unsigned int liberty,Move const& moveBase)
00173   {
00174     if((liberty&(1<<Dir))!=0){
00175       const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00176       Move m=moveBase.newAddTo(offset);
00177       Square to=from+offset;
00178       Piece p1=ptr[offset.intValue()];
00179       assert(p1.canMoveOn<P>());
00180       if(notPromoteCapture && !p1.isEmpty()) return;
00181       m=m.newAddCapture(p1);
00182       action.unknownMove(from,to,p1,KING,false,P,m);
00183     }
00184   }
00185 
00186       template <Player P,class Action,bool useDirMask,bool notPromoteCapture>
00187   inline void
00188   generateKing(const NumEffectState& state, Action& action,Square pos,int dirMask)
00189   {
00190     King8Info king8info(state.Iking8Info(P));
00191     unsigned int liberty=king8info.liberty();
00192     Move moveBase(pos,pos,KING,(Ptype)0,false,P);
00193     const Piece *ptr=state.getPiecePtr(pos);
00194     if(!useDirMask || (dirMask&(1<<UL))==0){
00195       generateKingDir<P,UL,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
00196       generateKingDir<P,DR,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
00197     }
00198     if(!useDirMask || (dirMask&(1<<U))==0){
00199       generateKingDir<P,U,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
00200       generateKingDir<P,D,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
00201     }
00202     if(!useDirMask || (dirMask&(1<<UR))==0){
00203       generateKingDir<P,UR,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
00204       generateKingDir<P,DL,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
00205     }
00206     if(!useDirMask || (dirMask&(1<<L))==0){
00207       generateKingDir<P,L,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
00208       generateKingDir<P,R,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
00209     }
00210   }
00211 
00212       template <Player P,class Action,bool useDirMask,bool notPromoteCapture>
00213   inline void
00214   generateLance(const NumEffectState& state, Piece p,Action& action,Square from,int dirMask)
00215   {
00216     if(!useDirMask || (dirMask&(1<<U))==0){
00217       const Offset offset=DirectionPlayerTraits<U,P>::offset();
00218       Square limit=state.mobilityOf((P==BLACK ? U : D),p.number());
00219       Square to=limit;
00220       Piece p1=state.pieceAt(to);
00221       int limity=(P==BLACK ? to.y() : 10-to.y());
00222       int fromy=(P==BLACK ? from.y() : 10-from.y());
00223       int ycount=fromy-limity-1;
00224       Move m(from,to,LANCE,(Ptype)0,false,P);
00225       switch(limity){
00226       case 4: case 5: case 6: case 7: case 8: case 9:{
00227         if(!notPromoteCapture && p1.canMoveOn<P>())
00228           action.unknownMove(from,to,p1,LANCE,false,P,m.newAddCapture(p1));
00229         m=m.newAddTo(-offset); to-=offset;
00230         goto escape4;
00231       }
00232       case 3:
00233         if(!notPromoteCapture && p1.canMoveOn<P>()){
00234           Move m1=m.newAddCapture(p1);
00235           action.unknownMove(from,to,p1,PLANCE,true,P,m1.promote());
00236           action.unknownMove(from,to,p1,LANCE,false,P,m1);
00237         }
00238         m=m.newAddTo(-offset); to-=offset;
00239         goto escape4;
00240       case 2:
00241         if(!notPromoteCapture && p1.canMoveOn<P>()){
00242           Move m1=m.newAddCapture(p1);
00243           action.unknownMove(from,to,p1,PLANCE,true,P,m1.promote());
00244         }
00245         if(fromy==3) return;
00246         m=m.newAddTo(-offset); to-=offset;
00247         ycount=fromy-4;
00248         goto escape2;
00249       case 0: 
00250         m=m.newAddTo(-offset); to-=offset;
00251         if(!notPromoteCapture)
00252           action.simpleMove(from,to,PLANCE,true,P,m.promote());
00253         goto join01;
00254       case 1: 
00255         if(!notPromoteCapture && p1.canMoveOn<P>()){
00256           action.unknownMove(from,to,p1,PLANCE,true,P,m.newAddCapture(p1).promote());
00257         }
00258       join01:
00259         if(fromy==2) return;
00260         m=m.newAddTo(-offset); to-=offset;
00261         if(fromy==3){
00262           if(!notPromoteCapture)
00263             action.simpleMove(from,to,PLANCE,true,P,m.promote());
00264           return;
00265         }
00266         ycount=fromy-4;
00267         goto escape01;
00268       default: assert(0);
00269       }
00270     escape01:
00271       if(!notPromoteCapture)
00272         action.simpleMove(from,to,PLANCE,true,P,m.promote());
00273       m=m.newAddTo(-offset); to-=offset;
00274     escape2:
00275       if(!notPromoteCapture)
00276         action.simpleMove(from,to,PLANCE,true,P,m.promote());
00277       action.simpleMove(from,to,LANCE,false,P,m);
00278       m=m.newAddTo(-offset); to-=offset;
00279     escape4:
00280       while(ycount-->0){
00281         action.simpleMove(from,to,LANCE,false,P,m);
00282         m=m.newAddTo(-offset);
00283         to-=offset;
00284       }
00285     }
00286     return;
00287   }
00288 
00289       template <Player P,class Action,bool useDirMask,bool notPromoteCapture>
00290   inline void
00291   generatePawn(const NumEffectState& state, Piece p,Action& action,Square from,int dirMask)
00292   {
00293     assert(from == p.square());
00294     if(!useDirMask || (dirMask&(1<<U))==0){
00295       if(notPromoteCapture && (P==BLACK ? from.yLe<4>() : from.yGe<6>())) return;
00296       const Offset offset=DirectionPlayerTraits<U,P>::offset();
00297       Square to=from+offset;
00298       Piece p1=state.pieceAt(to);
00299       if(notPromoteCapture){
00300         if(p1.isEmpty())
00301           action.simpleMove(from,to,PAWN,false,P);
00302         return;
00303       }
00304       if(p1.canMoveOn<P>()){
00305         if(P==BLACK ? to.yLe<3>() : to.yGe<7>()){ // canPromote
00306           if(notPromoteCapture) return;
00307           Move m(from,to,PPAWN,PTYPE_EMPTY,true,P);
00308           action.unknownMove(from,to,p1,PPAWN,true,P,
00309                              m.newAddCapture(p1));
00310         }
00311         else{
00312           Move m(from,to,PAWN,PTYPE_EMPTY,false,P);
00313           action.unknownMove(from,to,p1,PAWN,false,P,m.newAddCapture(p1));
00314         }
00315       }
00316     }
00317   }
00318 }
00319     template <class Action,bool notPromoteCapture>
00320   template <Player P,Ptype T,bool useDirMask>
00321     void PieceOnBoard<Action,notPromoteCapture>::
00322   generatePtypeUnsafe(const NumEffectState& state,Piece p, Action& action,int dirMask)
00323   {
00324     using piece_on_board::generatePtypePromote;
00325     using piece_on_board::generateKing;
00326     using piece_on_board::generateLance;
00327     using piece_on_board::generatePawn;
00328     const Square from=p.square();
00329     if(T==KING){
00330       generateKing<P,Action,useDirMask,notPromoteCapture>(state,action,from,dirMask);
00331     }
00332     else if(T==LANCE){
00333       generateLance<P,Action,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
00334     }
00335     else if(T==PAWN){
00336       generatePawn<P,Action,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
00337     }
00338     else if(canPromote(T)){
00339       if(PtypePlayerTraits<T,P>::mustPromote(from))
00340         generatePtypePromote<P,T,Action,MustPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
00341       else if(PtypePlayerTraits<T,P>::canPromote(from))
00342         generatePtypePromote<P,T,Action,CanPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
00343       else if(PtypePlayerTraits<T,P>::checkPromote(from))
00344         generatePtypePromote<P,T,Action,CheckPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
00345       else
00346         generatePtypePromote<P,T,Action,NoPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
00347     }
00348     else
00349       generatePtypePromote<P,T,Action,NoPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
00350   }
00351 
00352     template <class Action,bool notPromoteCapture>
00353 template <Player P,Ptype T,bool useDirMask>
00354     void PieceOnBoard<Action,notPromoteCapture>::
00355 generatePtype(const NumEffectState& state,Piece p, Action& action,int dirMask)
00356 {
00357   int num=p.number();
00358 //  if(T==SILVER) std::cerr << "p=" << p << std::endl;
00359   if(state.pin(P).test(num)){
00360     if(T==KNIGHT) return;
00361     Direction d=state.pinnedDir<P>(p);
00362     dirMask|=(~(1<<primDir(d)));
00363 //    std::cerr << "pinned direction=" << d << ",dirMask=" << dirMask << std::endl;
00364     generatePtypeUnsafe<P,T,true>(state,p,action,dirMask);
00365   }
00366   else{
00367     generatePtypeUnsafe<P,T,useDirMask>(state,p,action,dirMask);
00368   }
00369 }
00370     template <class Action,bool notPromoteCapture>
00371 template <Player P,bool useDirmask>
00372     void PieceOnBoard<Action,notPromoteCapture>::
00373 generate(const NumEffectState& state,Piece p, Action& action,int dirMask)
00374 {
00375       
00376   switch(p.ptype()){
00377   case PPAWN: case PLANCE: case PKNIGHT: case PSILVER: case GOLD:
00378     generatePtype<P,GOLD,useDirmask>(state,p,action,dirMask); break;
00379   case PAWN: 
00380     generatePtype<P,PAWN,useDirmask>(state,p,action,dirMask); break;
00381   case LANCE: 
00382     generatePtype<P,LANCE,useDirmask>(state,p,action,dirMask); break;
00383   case KNIGHT: 
00384     generatePtype<P,KNIGHT,useDirmask>(state,p,action,dirMask); break;
00385   case SILVER: 
00386     generatePtype<P,SILVER,useDirmask>(state,p,action,dirMask); break;
00387   case BISHOP: 
00388     generatePtype<P,BISHOP,useDirmask>(state,p,action,dirMask); break;
00389   case PBISHOP: 
00390     generatePtype<P,PBISHOP,useDirmask>(state,p,action,dirMask); break;
00391   case ROOK: 
00392     generatePtype<P,ROOK,useDirmask>(state,p,action,dirMask); break;
00393   case PROOK: 
00394     generatePtype<P,PROOK,useDirmask>(state,p,action,dirMask); break;
00395   case KING: 
00396     generatePtype<P,KING,useDirmask>(state,p,action,dirMask); break;
00397   default: break;
00398   }
00399 }
00400 } // namespace move_generator
00401 } // namespace osl
00402 
00403 #endif /* _GENERATE_PIECE_MOVES_TCC */
00404 // ;;; Local Variables:
00405 // ;;; mode:c++
00406 // ;;; c-basic-offset:2
00407 // ;;; End:
00408 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines