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