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