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
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{
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 *,Square ,Action& ,Int2Type<false>,Move ,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 )
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>()){
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
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
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 }
00401 }
00402
00403 #endif
00404
00405
00406
00407
00408