00001
00002
00003 #include "osl/numEffectState.h"
00004 #include "osl/numEffectState.tcc"
00005 #include "osl/simpleState.tcc"
00006 #include "osl/bits/numSimpleEffect.tcc"
00007 #include "osl/move_classifier/moveAdaptor.h"
00008 #include "osl/move_classifier/check_.h"
00009 #include "osl/move_classifier/safeMove.h"
00010 #include "osl/move_classifier/pawnDropCheckmate.h"
00011 #include "osl/move_generator/allMoves.h"
00012 #include "osl/move_generator/escape_.h"
00013 #include "osl/move_generator/move_action.h"
00014 #include "osl/move_generator/effect_action.h"
00015
00016 #include <iostream>
00017 #if (defined(__i386__) || defined(__x86_64__)) && !defined(OSL_NO_SSE)
00018 #include <emmintrin.h>
00019 typedef __v2di v2di;
00020 #endif
00021
00022 bool osl::operator==(const NumEffectState& st1,
00023 const NumEffectState& st2)
00024 {
00025 assert(st1.isConsistent(true));
00026 assert(st2.isConsistent(true));
00027 if (!(st1.effects == st2.effects))
00028 return false;
00029 if (!(st1.pieces_onboard == st2.pieces_onboard))
00030 return false;
00031 if (!(st1.promoted == st2.promoted))
00032 return false;
00033 if (!(st1.pin_or_open == st2.pin_or_open))
00034 return false;
00035 if (!(st1.king_mobility == st2.king_mobility))
00036 return false;
00037 if (!(st1.king8infos == st2.king8infos))
00038 return false;
00039 return (static_cast<const SimpleState&>(st1)
00040 == static_cast<const SimpleState&>(st2));
00041 }
00042
00043 const osl::checkmate::King8Info osl::
00044 NumEffectState::king8Info(Player king) const
00045 {
00046 return King8Info(Iking8Info(king));
00047 }
00048
00049 template<osl::Player P>
00050 void osl::NumEffectState::makeKing8Info()
00051 {
00052 const Player altP=alt(P);
00053 #ifdef ALLOW_KING_ABSENCE
00054 if (kingSquare<P>().isPieceStand())
00055 return;
00056 #endif
00057 king8infos[P]=King8Info::make<altP>(*this,kingSquare<P>()).uint64Value();
00058 }
00059
00060 osl::
00061 NumEffectState::NumEffectState(const SimpleState& st)
00062 : SimpleState(st),effects(st)
00063 {
00064 pieces_onboard[0].resetAll();
00065 pieces_onboard[1].resetAll();
00066 promoted.resetAll();
00067 effects.effected_mask[0].resetAll();
00068 effects.effected_mask[1].resetAll();
00069 effects.effected_changed_mask[0].resetAll();
00070 effects.effected_changed_mask[1].resetAll();
00071 for(int num=0;num<40;num++){
00072 Piece p=pieceOf(num);
00073 if (p.isOnBoard()){
00074 pieces_onboard[p.owner()].set(num);
00075 if (p.isPromoted())
00076 promoted.set(num);
00077 for(int i=0;i<2;i++){
00078 Player pl=indexToPlayer(i);
00079 if(hasEffectAt(pl,p.square()))
00080 {
00081 effects.effected_mask[i].set(num);
00082 effects.effected_changed_mask[i].set(num);
00083 }
00084 }
00085 }
00086 }
00087 makePinOpen(BLACK);
00088 makePinOpen(WHITE);
00089 if(kingSquare<BLACK>().isOnBoard())
00090 makeKing8Info<BLACK>();
00091 if(kingSquare<WHITE>().isOnBoard())
00092 makeKing8Info<WHITE>();
00093 }
00094 osl::
00095 NumEffectState::~NumEffectState()
00096 {
00097 }
00098
00099 const osl::Piece osl::
00100 NumEffectState::selectCheapPiece(PieceMask effect) const
00101 {
00102 if (! effect.any())
00103 return Piece::EMPTY();
00104 mask_t pieces = effect.selectBit<PAWN>(), ppieces;
00105 if (pieces.any())
00106 {
00107 ppieces = pieces & promoted.getMask<PAWN>();
00108 pieces &= ~ppieces;
00109 if (pieces.any())
00110 return pieceOf(pieces.bsf()+PtypeFuns<PAWN>::indexNum*32);
00111 return pieceOf(ppieces.bsf()+PtypeFuns<PAWN>::indexNum*32);
00112 }
00113 pieces = effect.selectBit<LANCE>();
00114 if (pieces.any())
00115 {
00116 ppieces = pieces & promoted.getMask<LANCE>();
00117 pieces &= ~ppieces;
00118 if (pieces.any())
00119 return pieceOf(pieces.bsf()+PtypeFuns<LANCE>::indexNum*32);
00120 return pieceOf(ppieces.bsf()+PtypeFuns<LANCE>::indexNum*32);
00121 }
00122 mask_t king = effect.selectBit<KING>();
00123 effect.clearBit<KING>();
00124 if (effect.none())
00125 return pieceOf(king.bsf()+PtypeFuns<KING>::indexNum*32);
00126
00127 const int index = 0;
00128 ppieces = effect.getMask(index) & promoted.getMask(index);
00129 pieces = effect.getMask(index) & ~ppieces;
00130 if (pieces.none() || ppieces.none())
00131 return pieceOf(pieces.any() ? pieces.bsf() : ppieces.bsf());
00132 const int num = pieces.bsf(), nump = ppieces.bsf();
00133 if (Piece_Table.getPtypeOf(num) == Piece_Table.getPtypeOf(nump))
00134 return pieceOf(num);
00135 return pieceOf(std::min(num, nump));
00136 }
00137
00138 const osl::Piece osl::
00139 NumEffectState::findThreatenedPiece(Player P) const
00140 {
00141 assert(! inCheck(P));
00142 PieceMask pieces = piecesOnBoard(P) & effectedMask(alt(P));
00143 PieceMask nolance = pieces; nolance.clearBit<LANCE>();
00144 int pp=-1, npp=-1, ret=-1;
00145 const int lance_index = PtypeFuns<LANCE>::indexNum;
00146 for (int i=lance_index; i>=0; --i) {
00147 mask_t all = nolance.getMask(i);
00148 mask_t promoted = all & promotedPieces().getMask(i);
00149 mask_t notpromoted = all & ~promoted;
00150 if (promoted.any()) {
00151 pp = promoted.bsr() + i*32;
00152 notpromoted &= ~Ptype_Table.getMaskLow(Piece_Table.getPtypeOf(pp));
00153 }
00154 if (notpromoted.any())
00155 npp = notpromoted.bsr() + i*32;
00156 ret = std::max(pp, npp);
00157 if (ret >= PtypeTraits<KNIGHT>::indexMin)
00158 return pieceOf(ret);
00159 }
00160 mask_t lance = pieces.selectBit<LANCE>();
00161 if (lance.any()) {
00162 mask_t plance = lance & promotedPieces().getMask(lance_index);
00163 if (plance.any())
00164 return pieceOf(plance.bsr()+lance_index*32);
00165 return pieceOf(lance.bsr()+lance_index*32);
00166 }
00167 if (ret >= 0) {
00168 assert(Piece_Table.getPtypeOf(ret) == PAWN);
00169 return pieceOf(ret);
00170 }
00171 return Piece::EMPTY();
00172 }
00173
00174 bool osl::
00175 NumEffectState::wasCheckEvasion(Move last_move) const
00176 {
00177 if (! last_move.isNormal())
00178 return false;
00179 const Square from = last_move.from(), to = last_move.to();
00180 if (last_move.ptype() == KING) {
00181 if (last_move.isCapture()
00182 && hasEffectIf(last_move.capturePtypeO(), to, from))
00183 return true;
00184 return hasEffectAt(turn(), from);
00185 }
00186 if (last_move.isCapture())
00187 return hasEffectIf(last_move.capturePtypeO(), to,
00188 kingSquare(alt(turn())))
00189 && !Board_Table.isBetweenSafe(from, to,
00190 kingSquare(alt(turn())));
00191 const Piece piece = pieceOnBoard(to);
00192 if (! pin(alt(turn())).test(piece.number()))
00193 return false;
00194 if (last_move.isDrop() || last_move.oldPtype() == KNIGHT)
00195 return true;
00196 const Direction d=pinnedDir(piece);
00197 return primDir(d)
00198 !=primDirUnsafe(Board_Table.getShort8Unsafe(piece.owner(), from,to));
00199 }
00200
00201 void osl::NumEffectState::makeMove(Move move)
00202 {
00203 assert(turn() == move.player());
00204 if (move.isPass()) {
00205 makeMovePass();
00206 return;
00207 }
00208
00209 assert(isAlmostValidMove(move));
00210 const Square from=move.from();
00211 const Square to=move.to();
00212 if (from.isPieceStand())
00213 {
00214 doDropMove(to,move.ptype());
00215 }
00216 else
00217 {
00218 const Piece captured = pieceOnBoard(to);
00219 if (captured != Piece::EMPTY())
00220 {
00221 doCaptureMove(from,to,captured,move.promoteMask());
00222 }
00223 else
00224 {
00225 doSimpleMove(from,to,move.promoteMask());
00226 }
00227 }
00228 changeTurn();
00229 }
00230
00231 void osl::NumEffectState::
00232 doSimpleMove(Square from, Square to, int promoteMask)
00233 {
00234 Piece oldPiece;
00235 int num;
00236 PtypeO oldPtypeO, newPtypeO;
00237 CArray<PieceMask,2> pin_or_open_backup;
00238 KingMobility king_mobility_backup;
00239 PieceMask promoted_backup;
00240 CArray<PieceMask,2> effected_mask_backup;
00241 CArray<PieceMask,2> effected_changed_mask_backup;
00242 CArray<uint64_t,2> king8infos_backup;
00243 mobility::MobilityTable mobilityTable;
00244 if (turn()==BLACK){
00245 prologueSimple(Player2Type<BLACK>(), from, to, promoteMask,
00246 oldPiece, num, oldPtypeO, newPtypeO,
00247 pin_or_open_backup, king_mobility_backup,
00248 promoted_backup, effected_mask_backup, effected_changed_mask_backup,king8infos_backup,mobilityTable);
00249 }
00250 else{
00251 prologueSimple(Player2Type<WHITE>(), from, to, promoteMask,
00252 oldPiece, num, oldPtypeO, newPtypeO,
00253 pin_or_open_backup, king_mobility_backup,
00254 promoted_backup, effected_mask_backup, effected_changed_mask_backup,king8infos_backup,mobilityTable);
00255 }
00256 if (promoteMask!=0 && num < PtypeTraits<PAWN>::indexLimit)
00257 clearPawn(turn(),from);
00258 }
00259 void osl::NumEffectState::
00260 doCaptureMove(Square from, Square to, Piece target, int promoteMask)
00261 {
00262 Piece oldPiece;
00263 PtypeO oldPtypeO, capturePtypeO, newPtypeO;
00264 int num0, num1, num1Index;
00265 mask_t num1Mask;
00266 CArray<PieceMask,2> pin_or_open_backup;
00267 KingMobility king_mobility_backup;
00268 PieceMask promoted_backup;
00269 CArray<PieceMask,2> effected_mask_backup;
00270 CArray<PieceMask,2> effected_changed_mask_backup;
00271 CArray<uint64_t,2> king8infos_backup;
00272 mobility::MobilityTable mobilityTable;
00273 if(turn()==BLACK){
00274 prologueCapture(Player2Type<BLACK>(), from, to, target, promoteMask, oldPiece, oldPtypeO,
00275 capturePtypeO, newPtypeO, num0, num1, num1Index,num1Mask,
00276 pin_or_open_backup, king_mobility_backup,
00277 promoted_backup, effected_mask_backup, effected_changed_mask_backup,king8infos_backup,mobilityTable);
00278 }
00279 else{
00280 prologueCapture(Player2Type<WHITE>(), from, to, target, promoteMask, oldPiece, oldPtypeO,
00281 capturePtypeO, newPtypeO, num0, num1, num1Index,num1Mask,
00282 pin_or_open_backup, king_mobility_backup,
00283 promoted_backup, effected_mask_backup, effected_changed_mask_backup,king8infos_backup,mobilityTable);
00284 }
00285 const Ptype capturePtype=target.ptype();
00286 if (capturePtype==PAWN)
00287 clearPawn(alt(turn()),to);
00288 if (promoteMask!=0 && num0<PtypeTraits<PAWN>::indexLimit)
00289 clearPawn(turn(),from);
00290 }
00291
00292 void osl::NumEffectState::
00293 doDropMove(Square to,Ptype ptype)
00294 {
00295 Piece oldPiece;
00296 PtypeO ptypeO;
00297 int num, numIndex;
00298 mask_t numMask;
00299 CArray<PieceMask,2> pin_or_open_backup;
00300 KingMobility king_mobility_backup;
00301 CArray<PieceMask,2> effected_mask_backup;
00302 CArray<PieceMask,2> effected_changed_mask_backup;
00303 CArray<uint64_t,2> king8infos_backup;
00304 mobility::MobilityTable mobilityTable;
00305 if(turn()==BLACK){
00306 prologueDrop(Player2Type<BLACK>(), to, ptype, oldPiece, num, ptypeO, numIndex, numMask,
00307 pin_or_open_backup, king_mobility_backup,
00308 effected_mask_backup, effected_changed_mask_backup,king8infos_backup,mobilityTable);
00309 }
00310 else{
00311 prologueDrop(Player2Type<WHITE>(), to, ptype, oldPiece, num, ptypeO, numIndex, numMask,
00312 pin_or_open_backup, king_mobility_backup,
00313 effected_mask_backup, effected_changed_mask_backup,king8infos_backup,mobilityTable);
00314 }
00315 if (ptype==PAWN)
00316 setPawn(turn(),to);
00317 }
00318
00319 template<osl::Player P>
00320 void osl::NumEffectState::
00321 prologueSimple(Player2Type<P>, Square from, Square to, int promoteMask,
00322 Piece& oldPiece, int& num,
00323 PtypeO& oldPtypeO, PtypeO& new_ptypeo,
00324 CArray<PieceMask,2>& pin_or_open_backup,
00325 KingMobility& king_mobility_backup,
00326 PieceMask& promoted_backup,
00327 CArray<PieceMask,2>& effected_mask_backup,
00328 CArray<PieceMask,2>& effected_changed_mask_backup,
00329 CArray<uint64_t,2>& king8infos_backup,
00330 MobilityTable &mobility_backup)
00331 {
00332 mobility_backup = effects.mobilityTable;
00333 pin_or_open_backup = pin_or_open;
00334 king_mobility_backup = king_mobility;
00335 effected_mask_backup = effects.effected_mask;
00336 effected_changed_mask_backup = effects.effected_changed_mask;
00337 king8infos_backup=king8infos;
00338
00339 oldPiece=pieceAt(from);
00340 Piece newPiece=oldPiece.promoteWithMask(promoteMask);
00341 newPiece+=(to-from);
00342 num=oldPiece.number();
00343
00344 oldPtypeO=oldPiece.ptypeO();
00345 new_ptypeo=newPiece.ptypeO();
00346
00347 setPieceOf(num,newPiece);
00348 effects.clearChangedEffects();
00349 effects.clearEffectedChanged();
00350 effects.template doEffect<NumBitmapEffect::Sub,true>(*this,oldPtypeO,from,num);
00351
00352
00353 effects.effectedNumTable[num].clear();
00354 setBoard(to,newPiece);
00355 effects.template doBlockAt<NumBitmapEffect::Sub,true>(*this,to,num);
00356 setBoard(from,Piece::EMPTY());
00357 effects.template doBlockAt<NumBitmapEffect::Add,true>(*this,from,num);
00358 effects.template doEffect<NumBitmapEffect::Add,true>(*this,new_ptypeo,to,num);
00359
00360 if (oldPtypeO == newPtypeO(P,KING))
00361 makePinOpen(P);
00362 else {
00363 Direction lastD=UL;
00364 pin_or_open[P].reset(num);
00365 recalcPinOpen(from,lastD,P);
00366 recalcPinOpen(to,lastD,P);
00367 }
00368 {
00369 Direction lastD=UL;
00370 pin_or_open[alt(P)].reset(num);
00371 recalcPinOpen(from,lastD,alt(P));
00372 recalcPinOpen(to,lastD,alt(P));
00373 }
00374 promoted_backup = promoted;
00375 if (promoteMask)
00376 promoted.set(num);
00377 if(hasEffectAt(BLACK,to))
00378 effects.effected_mask[BLACK].set(num);
00379 else
00380 effects.effected_mask[BLACK].reset(num);
00381 if(hasEffectAt(WHITE,to))
00382 effects.effected_mask[WHITE].set(num);
00383 else
00384 effects.effected_mask[WHITE].reset(num);
00385 effects.effected_changed_mask[BLACK].set(num);
00386 effects.effected_changed_mask[WHITE].set(num);
00387 {
00388 BoardMask changed=changedEffects(BLACK)|changedEffects(WHITE);
00389 changed.set(from);
00390 changed.set(to);
00391 if(changed.anyInRange(Board_Mask_Table3x3.mask(kingSquare<BLACK>()))
00392 || pin_or_open[BLACK]!=pin_or_open_backup[BLACK])
00393 makeKing8Info<BLACK>();
00394 if(changed.anyInRange(Board_Mask_Table3x3.mask(kingSquare<WHITE>()))
00395 || pin_or_open[WHITE]!=pin_or_open_backup[WHITE])
00396 makeKing8Info<WHITE>();
00397 }
00398 }
00399
00400 void osl::NumEffectState::
00401 epilogueSimple(Square from, Square to, Piece oldPiece,
00402 int num, PtypeO oldPtypeO, PtypeO newPtypeO,
00403 const CArray<PieceMask,2>& pin_or_open_backup,
00404 const KingMobility& king_mobility_backup,
00405 const PieceMask& promoted_backup,
00406 const CArray<PieceMask,2>& effected_mask_backup,
00407 const CArray<PieceMask,2>& effected_changed_mask_backup,
00408 const CArray<uint64_t,2>& king8infos_backup,
00409 const MobilityTable & mobility_backup)
00410 {
00411 setPieceOf(num,oldPiece);
00412 effects.doEffect<NumBitmapEffect::Sub,false>(*this,newPtypeO,to,num);
00413 setBoard(from,oldPiece);
00414 effects.effectedNumTable[num].clear();
00415 effects.doBlockAt<NumBitmapEffect::Sub,false>(*this,from,num);
00416 setBoard(to,Piece::EMPTY());
00417 effects.doBlockAt<NumBitmapEffect::Add,false>(*this,to,num);
00418 effects.doEffect<NumBitmapEffect::Add,false>(*this,oldPtypeO,from,num);
00419 effects.invalidateChangedEffects();
00420 pin_or_open = pin_or_open_backup;
00421 king_mobility = king_mobility_backup;
00422 promoted = promoted_backup;
00423 effects.effected_mask = effected_mask_backup;
00424 effects.effected_changed_mask = effected_changed_mask_backup;
00425 effects.mobilityTable = mobility_backup;
00426 king8infos = king8infos_backup;
00427 }
00428
00429 template<osl::Player P>
00430 void osl::NumEffectState::
00431 prologueDrop(Player2Type<P>, Square to, Ptype ptype,
00432 Piece& oldPiece, int& num, PtypeO& ptypeO,
00433 int& numIndex, mask_t& numMask,
00434 CArray<PieceMask,2>& pin_or_open_backup,
00435 KingMobility& king_mobility_backup,
00436 CArray<PieceMask,2>& effected_mask_backup,
00437 CArray<PieceMask,2>& effected_changed_mask_backup,
00438 CArray<uint64_t,2>& king8infos_backup,
00439 MobilityTable &mobility_backup)
00440 {
00441 king8infos_backup = king8infos;
00442 mobility_backup = effects.mobilityTable;
00443 pin_or_open_backup = pin_or_open;
00444 king_mobility_backup = king_mobility;
00445 effected_mask_backup = effects.effected_mask;
00446 effected_changed_mask_backup = effects.effected_changed_mask;
00447 #if OSL_WORDSIZE == 64
00448 numIndex=0;
00449 #elif OSL_WORDSIZE == 32
00450 numIndex=Ptype_Table.getIndex(ptype);
00451 #endif
00452 const mask_t ownMochigoma=
00453 standMask(P).getMask(numIndex) & Ptype_Table.getMaskLow(ptype);
00454 assert(ownMochigoma.any());
00455 numMask=ownMochigoma.lowestBit();
00456 int numLow = ownMochigoma.bsf();
00457 num = numLow|(numIndex<<5);
00458 oldPiece=pieceOf(num);
00459 Piece newPiece=oldPiece;
00460 newPiece+=to-Square::STAND();
00461 ptypeO=newPiece.ptypeO();
00462 setPieceOf(num,newPiece);
00463 effects.clearChangedEffects();
00464 effects.clearEffectedChanged();
00465 effects.template doBlockAt<NumBitmapEffect::Sub,true>(*this,to,num);
00466 effects.template doEffect<NumBitmapEffect::Add,true>(*this,ptypeO,to,num);
00467 setBoard(to,newPiece);
00468 standMask(P).xorMask(numIndex,numMask);
00469 stand_count[P][ptype-PTYPE_BASIC_MIN]--;
00470 pieces_onboard[P].xorMask(numIndex,numMask);
00471 {
00472 Direction lastD=UL;
00473 recalcPinOpen(to,lastD,P);
00474 }
00475 {
00476 Direction lastD=UL;
00477 recalcPinOpen(to,lastD,alt(P));
00478 }
00479 if(hasEffectAt(BLACK,to))
00480 effects.effected_mask[BLACK].set(num);
00481 else
00482 effects.effected_mask[BLACK].reset(num);
00483 if (hasEffectAt(WHITE,to))
00484 effects.effected_mask[WHITE].set(num);
00485 else
00486 effects.effected_mask[WHITE].reset(num);
00487 effects.effected_changed_mask[BLACK].set(num);
00488 effects.effected_changed_mask[WHITE].set(num);
00489 {
00490 BoardMask changed=changedEffects(BLACK)|changedEffects(WHITE);
00491 changed.set(to);
00492 if(changed.anyInRange(Board_Mask_Table3x3.mask(kingSquare<BLACK>()))
00493 || pin_or_open[BLACK]!=pin_or_open_backup[BLACK])
00494 makeKing8Info<BLACK>();
00495 if(changed.anyInRange(Board_Mask_Table3x3.mask(kingSquare<WHITE>()))
00496 || pin_or_open[WHITE]!=pin_or_open_backup[WHITE])
00497 makeKing8Info<WHITE>();
00498 }
00499 }
00500
00501 template<osl::Player P>
00502 void osl::NumEffectState::
00503 epilogueDrop(Player2Type<P>, Square to, Ptype ptype, Piece oldPiece,
00504 int num, PtypeO ptypeO, int numIndex, mask_t numMask,
00505 const CArray<PieceMask,2>& pin_or_open_backup,
00506 const KingMobility& king_mobility_backup,
00507 const CArray<PieceMask,2>& effected_mask_backup,
00508 const CArray<PieceMask,2>& effected_changed_mask_backup,
00509 const CArray<uint64_t,2>& king8infos_backup,
00510 const MobilityTable& mobility_backup)
00511 {
00512 standMask(P).xorMask(numIndex,numMask);
00513 stand_count[P][ptype-PTYPE_BASIC_MIN]++;
00514 pieces_onboard[P].xorMask(numIndex,numMask);
00515 setBoard(to,Piece::EMPTY());
00516 effects.template doEffect<NumBitmapEffect::Sub,false>(*this,ptypeO,to,num);
00517 effects.template doBlockAt<NumBitmapEffect::Add,false>(*this,to,num);
00518 setPieceOf(num,oldPiece);
00519 effects.effectedNumTable[num].clear();
00520 effects.invalidateChangedEffects();
00521 pin_or_open = pin_or_open_backup;
00522 king_mobility = king_mobility_backup;
00523 effects.effected_mask = effected_mask_backup;
00524 effects.effected_changed_mask = effected_changed_mask_backup;
00525 effects.mobilityTable = mobility_backup;
00526 king8infos = king8infos_backup;
00527 }
00528
00529 template<osl::Player P>
00530 void osl::NumEffectState::
00531 prologueCapture(Player2Type<P>, Square from, Square to, Piece target,
00532 int promoteMask,
00533 Piece& oldPiece, PtypeO& oldPtypeO, PtypeO& capturePtypeO,
00534 PtypeO& new_ptypeo, int& num0, int& num1,
00535 int& num1Index, mask_t& num1Mask,
00536 CArray<PieceMask,2>& pin_or_open_backup,
00537 KingMobility& king_mobility_backup,
00538 PieceMask& promoted_backup,
00539 CArray<PieceMask,2>& effected_mask_backup,
00540 CArray<PieceMask,2>& effected_changed_mask_backup,
00541 CArray<uint64_t,2>& king8infos_backup,
00542 MobilityTable &mobility_backup)
00543 {
00544 mobility_backup = effects.mobilityTable;
00545 pin_or_open_backup = pin_or_open;
00546 king_mobility_backup = king_mobility;
00547 effected_mask_backup = effects.effected_mask;
00548 effected_changed_mask_backup = effects.effected_changed_mask;
00549 king8infos_backup = king8infos;
00550
00551 num1=target.number();
00552 num1Index=PieceMask::numToIndex(num1);
00553 num1Mask=PieceMask::numToMask(num1);
00554 pieces_onboard[alt(P)].xorMask(num1Index,num1Mask);
00555 standMask(P).xorMask(num1Index,num1Mask);
00556 oldPiece=pieceAt(from);
00557 Piece newPiece=oldPiece.promoteWithMask(promoteMask);
00558 newPiece+=(to-from);
00559 num0=oldPiece.number();
00560 setPieceOf(num0,newPiece);
00561 setPieceOf(num1,target.captured());
00562
00563 oldPtypeO=oldPiece.ptypeO();
00564 new_ptypeo=newPiece.ptypeO();
00565 capturePtypeO=target.ptypeO();
00566 stand_count[P][unpromote(getPtype(capturePtypeO))-PTYPE_BASIC_MIN]++;
00567 effects.clearChangedEffects();
00568 effects.clearEffectedChanged();
00569 effects.setChangedPieces(effectSetAt(to));
00570 effects.template doEffect<NumBitmapEffect::Sub,true>(*this,capturePtypeO,to,num1);
00571 effects.template doEffect<NumBitmapEffect::Sub,true>(*this,oldPtypeO,from,num0);
00572 setBoard(from,Piece::EMPTY());
00573 effects.template doBlockAt<NumBitmapEffect::Add,true>(*this,from,num0);
00574 effects.effectedNumTable[num0]=effects.effectedNumTable[num1];
00575 effects.effectedNumTable[num1].clear();
00576 setBoard(to,newPiece);
00577 effects.template doEffect<NumBitmapEffect::Add,true>(*this,new_ptypeo,to,num0);
00578
00579 if (oldPtypeO == newPtypeO(P,KING))
00580 makePinOpen(P);
00581 else {
00582 Direction lastD=UL;
00583 pin_or_open[P].reset(num0);
00584 pin_or_open[P].reset(num1);
00585 recalcPinOpen(from,lastD,P);
00586 recalcPinOpen(to,lastD,P);
00587 }
00588 {
00589 Direction lastD=UL;
00590 pin_or_open[alt(P)].reset(num0);
00591 pin_or_open[alt(P)].reset(num1);
00592 recalcPinOpen(from,lastD,alt(P));
00593 recalcPinOpen(to,lastD,alt(P));
00594 }
00595 promoted_backup = promoted;
00596 promoted.reset(num1);
00597 effects.effected_mask[BLACK].reset(num1);
00598 effects.effected_mask[WHITE].reset(num1);
00599 if (promoteMask)
00600 promoted.set(num0);
00601 if(hasEffectAt(BLACK,to))
00602 effects.effected_mask[BLACK].set(num0);
00603 else
00604 effects.effected_mask[BLACK].reset(num0);
00605 if(hasEffectAt(WHITE,to))
00606 effects.effected_mask[WHITE].set(num0);
00607 else
00608 effects.effected_mask[WHITE].reset(num0);
00609 effects.effected_changed_mask[BLACK].set(num0);
00610 effects.effected_changed_mask[WHITE].set(num0);
00611 {
00612 BoardMask changed=changedEffects(BLACK)|changedEffects(WHITE);
00613 changed.set(from);
00614 changed.set(to);
00615 if(changed.anyInRange(Board_Mask_Table3x3.mask(kingSquare<BLACK>()))
00616 || pin_or_open[BLACK]!=pin_or_open_backup[BLACK])
00617 makeKing8Info<BLACK>();
00618 if(changed.anyInRange(Board_Mask_Table3x3.mask(kingSquare<WHITE>()))
00619 || pin_or_open[WHITE]!=pin_or_open_backup[WHITE])
00620 makeKing8Info<WHITE>();
00621 }
00622 }
00623
00624 template<osl::Player P>
00625 void osl::NumEffectState::
00626 epilogueCapture(Player2Type<P>, Square from, Square to, Piece target,
00627 Piece oldPiece, PtypeO oldPtypeO, PtypeO capturePtypeO,
00628 PtypeO newPtypeO, int num0, int num1,
00629 int num1Index, mask_t num1Mask,
00630 const CArray<PieceMask,2>& pin_or_open_backup,
00631 const KingMobility& king_mobility_backup,
00632 const PieceMask& promoted_backup,
00633 const CArray<PieceMask,2>& effected_mask_backup,
00634 const CArray<PieceMask,2>& effected_changed_mask_backup,
00635 const CArray<uint64_t,2>& king8infos_backup,
00636 const MobilityTable &mobility_backup)
00637 {
00638 standMask(P).xorMask(num1Index,num1Mask);
00639 stand_count[P][unpromote(getPtype(capturePtypeO))-PTYPE_BASIC_MIN]--;
00640 pieces_onboard[alt(P)].xorMask(num1Index,num1Mask);
00641 effects.effectedNumTable[num1]=effects.effectedNumTable[num0];
00642 effects.effectedNumTable[num0].clear();
00643 setPieceOf(num0,oldPiece);
00644 setPieceOf(num1,target);
00645 effects.template doEffect<NumBitmapEffect::Sub,false>(*this,newPtypeO,to,num0);
00646 setBoard(from,oldPiece);
00647 setBoard(to,target);
00648 effects.template doBlockAt<NumBitmapEffect::Sub,false>(*this,from,num0);
00649 effects.template doEffect<NumBitmapEffect::Add,false>(*this,capturePtypeO,to,num1);
00650 effects.template doEffect<NumBitmapEffect::Add,false>(*this,oldPtypeO,from,num0);
00651 effects.invalidateChangedEffects();
00652 pin_or_open = pin_or_open_backup;
00653 king_mobility = king_mobility_backup;
00654 promoted = promoted_backup;
00655 effects.effected_mask = effected_mask_backup;
00656 effects.effected_changed_mask = effected_changed_mask_backup;
00657 effects.mobilityTable = mobility_backup;
00658 king8infos = king8infos_backup;
00659 }
00660
00661
00662 #ifndef MINIMAL
00663 bool osl::NumEffectState::isConsistent(bool showError) const
00664 {
00665 if (!SimpleState::isConsistent(showError))
00666 {
00667 if (showError)
00668 std::cerr << "error before effect\n";
00669 return false;
00670 }
00671 effect::NumSimpleEffectTable effects1(*this);
00672 if (!(effects1==effects))
00673 {
00674 if (showError)
00675 {
00676 std::cerr << "Effect error 1" << std::endl;
00677 std::cerr << *this;
00678 for(int y=1;y<=9;y++)
00679 for(int x=9;x>0;x--)
00680 {
00681 Square pos(x,y);
00682 if (!(effects1.effectSetAt(pos)==effects.effectSetAt(pos)))
00683 {
00684 std::cerr << pos << ",real=" << effects.effectSetAt(pos) << ",ideal=" << effects1.effectSetAt(pos) << std::endl;
00685 }
00686 }
00687 for(int num=0;num<=39;num++){
00688 for(int i=0;i<8;i++){
00689 Direction d=static_cast<Direction>(i);
00690 if(effects.effectedNumTable[num][d]!=effects1.effectedNumTable[num][d]){
00691 std::cerr << "piece=" << pieceOf(num) << ",num=" << num << ",d=" << d << ",v1=" << effects.effectedNumTable[num][d] << ",v2=" << effects1.effectedNumTable[num][d] << std::endl;
00692 }
00693 }
00694 }
00695 std::cerr << effects.effectedNumTable << std::endl;
00696 }
00697 return false;
00698 }
00699 for (int z=0; z<2; ++z) {
00700 const Player p = indexToPlayer(z);
00701 #ifdef ALLOW_KING_ABSENCE
00702 if (kingSquare(p).isPieceStand())
00703 continue;
00704 #endif
00705 #if 0
00706 const PieceMask pin2 = effect_util::Pin::make(*this, p);
00707 if (pin(p) != pin2) {
00708 if (showError)
00709 std::cerr << "pin for " << p << " differs " << pin(p) << " " << pin2 << "\n";
00710 return false;
00711 }
00712 #endif
00713 King8Info king8info2 = King8Info::make(alt(p), *this);
00714 if (King8Info(Iking8Info(p)).uint64Value() != king8info2.uint64Value()) {
00715 if (showError)
00716 std::cerr << "king8info for " << p << " differs \n" << King8Info(Iking8Info(p)) << "\n" << king8info2 << "\n";
00717 return false;
00718 }
00719 }
00720 for (int i=0; i<Piece::SIZE; ++i) {
00721 const Piece p = pieceOf(i);
00722 if (p.isOnBoard()) {
00723 if (promoted.test(i) != p.isPromoted()) {
00724 if (showError)
00725 std::cerr << "promoted differs " << p << " " << promoted << " " << promoted.test(i) << "\n";
00726 return false;
00727 }
00728 }
00729 }
00730 return true;
00731 }
00732 #endif
00733
00734 bool osl::NumEffectState::isConsistent(const NumEffectState& prev, Move moved, bool show_error) const
00735 {
00736
00737 const CArray<BoardMask,2> changed_squares
00738 = {{ changedEffects(BLACK), changedEffects(WHITE) }};
00739 const BoardMask changed_all = changed_squares[BLACK] | changed_squares[WHITE];
00740 CArray<BoardMask, Piece::SIZE> each_effect, prev_effect;
00741 for (int i=0; i<Piece::SIZE; ++i) {
00742 each_effect[i].clear();
00743 prev_effect[i].clear();
00744 }
00745 for (int x=1; x<=9; ++x) {
00746 for (int y=1; y<=9; ++y) {
00747 const Square sq(x, y);
00748 for (int i=0; i<Piece::SIZE; ++i) {
00749 if (effectSetAt(sq).test(i))
00750 each_effect[i].set(sq);
00751 if (prev.effectSetAt(sq).test(i))
00752 prev_effect[i].set(sq);
00753 }
00754 if (! changed_all.test(sq))
00755 {
00756 if (effectSetAt(sq) != prev.effectSetAt(sq)) {
00757 #ifndef MINIMAL
00758 if (show_error)
00759 std::cerr << "changedEffects unset\n" << *this << moved << sq << "\n";
00760 #endif
00761 return false;
00762 }
00763 }
00764 for (int i=0; i<2; ++i)
00765 {
00766 const Player pl = indexToPlayer(i);
00767 if (! changed_squares[pl].test(sq))
00768 {
00769 if ((effectSetAt(sq) & piecesOnBoard(pl))
00770 != (prev.effectSetAt(sq) & prev.piecesOnBoard(pl))) {
00771 #ifndef MINIMAL
00772 if (show_error)
00773 std::cerr << "changedEffects unset for " << pl << "\n" << *this << moved << sq << "\n";
00774 #endif
00775 return false;
00776 }
00777 }
00778 }
00779 }
00780 }
00781
00782 const NumBitmapEffect changed_effect_pieces = changedPieces();
00783 for (int i=0; i<Piece::SIZE; ++i) {
00784 if (each_effect[i] == prev_effect[i])
00785 continue;
00786 if (! changed_effect_pieces.test(i)) {
00787 #ifndef MINIMAL
00788 if (show_error)
00789 std::cerr << "changedPieces() unset\n" << *this << moved << i
00790 << " " << each_effect[i] << " != " << prev_effect[i] << "\n";
00791 #endif
00792 return false;
00793 }
00794 }
00795
00796 for (int i=0; i<Piece::SIZE; ++i)
00797 {
00798 for (int j=0; j<2; ++j)
00799 {
00800 const Player pl = indexToPlayer(j);
00801 if (prev.pieceOf(i).square() == moved.to())
00802 continue;
00803 if (prev.effectedMask(pl).test(i) != effectedMask(pl).test(i)) {
00804 if (! effectedChanged(pl).test(i)) {
00805 #ifndef MINIMAL
00806 if (show_error)
00807 std::cerr << "effectedChanged(" << pl << ") unset\n" << *this << moved << i
00808 << " " << prev.effectedChanged(pl) << " != " << prev.effectedChanged(WHITE) << "\n";
00809 #endif
00810 return false;
00811 }
00812 }
00813 }
00814 }
00815 return true;
00816 }
00817
00818 template <bool show_error>
00819 bool
00820 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
00821 __attribute__ ((used,noinline))
00822 #endif
00823 osl::NumEffectState::isAlmostValidMove(Move move) const{
00824 assert(move.isValid());
00825 assert(move.isNormal());
00826 assert(this->turn() == move.player());
00827 assert(isValidMoveByRule(move, true));
00828
00829 const Square from=move.from();
00830 if (from.isPieceStand())
00831 return isAlmostValidDrop<show_error>(move);
00832 const Square to=move.to();
00833 const Piece from_piece = this->pieceAt(from);
00834
00835 if (! testValidityOtherThanEffect<show_error>(move))
00836 return false;
00837 if(!hasEffectByPiece(from_piece,to)){
00838 if (show_error) {
00839 std::cerr << " No such move2 : " << move << std::endl;
00840 }
00841 return false;
00842 }
00843 return true;
00844 }
00845
00846 bool osl::NumEffectState::
00847 isAlmostValidMove(Move move,bool show_error) const{
00848 #ifdef MINIMAL
00849 show_error=false;
00850 #endif
00851 if(show_error)
00852 return isAlmostValidMove<true>(move);
00853 else
00854 return isAlmostValidMove<false>(move);
00855 }
00856
00857 #ifndef MINIMAL
00858 void osl::NumEffectState::showEffect(std::ostream& os) const
00859 {
00860 os<< static_cast<SimpleState const&>(*this);
00861 for(int y=1;y<=9;y++){
00862 os << 'P' << y;
00863 for(int x=9;x>0;x--){
00864 Square pos(x,y);
00865 os << csa::show(pieceAt(pos)) << effectSetAt(pos);
00866 }
00867 os << std::endl;
00868 }
00869
00870 for(int num=0;num<Piece::SIZE;num++){
00871 if (standMask(BLACK).test(num)){
00872 os << "P+00" << csa::show(Piece_Table.getPtypeOf(num))
00873 << std::endl;
00874 }
00875 else if (standMask(WHITE).test(num)){
00876 os << "P-00" << csa::show(Piece_Table.getPtypeOf(num))
00877 << std::endl;
00878 }
00879 }
00880 }
00881 #endif
00882
00883 osl::PieceMask osl::NumEffectState::
00884 makePinOpen(osl::Square target,osl::Player defense)
00885 {
00886 PieceMask pins;
00887 if(target.isPieceStand()) return pins;
00888 PieceMask mask=piecesOnBoard(alt(defense));
00889 makePinOpenDir<UL>(target,pins,mask,defense);
00890 makePinOpenDir<U>(target,pins,mask,defense);
00891 makePinOpenDir<UR>(target,pins,mask,defense);
00892 makePinOpenDir<L>(target,pins,mask,defense);
00893 makePinOpenDir<R>(target,pins,mask,defense);
00894 makePinOpenDir<DL>(target,pins,mask,defense);
00895 makePinOpenDir<D>(target,pins,mask,defense);
00896 makePinOpenDir<DR>(target,pins,mask,defense);
00897 return pins;
00898 }
00899
00900 void osl::NumEffectState::
00901 makePinOpen(osl::Player defense)
00902 {
00903 pin_or_open[defense]=makePinOpen(kingSquare(defense),defense);
00904 }
00905
00906 const osl::mask_t osl::NumEffectState::
00907 allEffectAt(Player attack, Ptype ptype, Square target) const
00908 {
00909 switch (ptype) {
00910 case PAWN: case PPAWN:
00911 return allEffectAt<PAWN>(attack, target);
00912 case LANCE: case PLANCE:
00913 return allEffectAt<LANCE>(attack, target);
00914 case KNIGHT: case PKNIGHT:
00915 return allEffectAt<KNIGHT>(attack, target);
00916 case SILVER: case PSILVER:
00917 return allEffectAt<SILVER>(attack, target);
00918 case GOLD:
00919 return allEffectAt<GOLD>(attack, target);
00920 case BISHOP: case PBISHOP:
00921 return allEffectAt<BISHOP>(attack, target);
00922 case ROOK: case PROOK:
00923 return allEffectAt<ROOK>(attack, target);
00924 case KING:
00925 return allEffectAt<KING>(attack, target);
00926 default:
00927 assert(0);
00928 }
00929 return mask_t();
00930 }
00931
00932 void osl::NumEffectState::copyFrom(const NumEffectState& src)
00933 {
00934 #ifndef MINIMAL
00935 (*this).used_mask=src.used_mask;
00936 #endif
00937 (*this).stand_mask=src.stand_mask;
00938 #if (defined(__i386__) || defined(__x86_64__)) && !defined(OSL_NO_SSE)
00939 {
00940 v2di b16=*((v2di*)&src.board[16]);
00941 v2di b20=*((v2di*)&src.board[20]);
00942 v2di b24=*((v2di*)&src.board[24]);
00943 v2di b32=*((v2di*)&src.board[32]);
00944 v2di b36=*((v2di*)&src.board[36]);
00945 v2di b40=*((v2di*)&src.board[40]);
00946 v2di b48=*((v2di*)&src.board[48]);
00947 v2di b52=*((v2di*)&src.board[52]);
00948 v2di b56=*((v2di*)&src.board[56]);
00949
00950 *((v2di*)&(*this).board[16])=b16;
00951 *((v2di*)&(*this).board[20])=b20;
00952 *((v2di*)&(*this).board[24])=b24;
00953 *((v2di*)&(*this).board[32])=b32;
00954 *((v2di*)&(*this).board[36])=b36;
00955 *((v2di*)&(*this).board[40])=b40;
00956 *((v2di*)&(*this).board[48])=b48;
00957 *((v2di*)&(*this).board[52])=b52;
00958 *((v2di*)&(*this).board[56])=b56;
00959
00960
00961 v2di b64=*((v2di*)&src.board[64]);
00962 v2di b68=*((v2di*)&src.board[68]);
00963 v2di b72=*((v2di*)&src.board[72]);
00964
00965 v2di b80=*((v2di*)&src.board[80]);
00966 v2di b84=*((v2di*)&src.board[84]);
00967 v2di b88=*((v2di*)&src.board[88]);
00968
00969 v2di b96=*((v2di*)&src.board[96]);
00970 v2di b100=*((v2di*)&src.board[100]);
00971 v2di b104=*((v2di*)&src.board[104]);
00972
00973
00974 *((v2di*)&(*this).board[64])=b64;
00975 *((v2di*)&(*this).board[68])=b68;
00976 *((v2di*)&(*this).board[72])=b72;
00977
00978 *((v2di*)&(*this).board[80])=b80;
00979 *((v2di*)&(*this).board[84])=b84;
00980 *((v2di*)&(*this).board[88])=b88;
00981
00982 *((v2di*)&(*this).board[96])=b96;
00983 *((v2di*)&(*this).board[100])=b100;
00984 *((v2di*)&(*this).board[104])=b104;
00985
00986 v2di b112=*((v2di*)&src.board[112]);
00987 v2di b116=*((v2di*)&src.board[116]);
00988 v2di b120=*((v2di*)&src.board[120]);
00989
00990 v2di b128=*((v2di*)&src.board[128]);
00991 v2di b132=*((v2di*)&src.board[132]);
00992 v2di b136=*((v2di*)&src.board[136]);
00993
00994 v2di b144=*((v2di*)&src.board[144]);
00995 v2di b148=*((v2di*)&src.board[148]);
00996 v2di b152=*((v2di*)&src.board[152]);
00997
00998 *((v2di*)&(*this).board[112])=b112;
00999 *((v2di*)&(*this).board[116])=b116;
01000 *((v2di*)&(*this).board[120])=b120;
01001
01002 *((v2di*)&(*this).board[128])=b128;
01003 *((v2di*)&(*this).board[132])=b132;
01004 *((v2di*)&(*this).board[136])=b136;
01005
01006 *((v2di*)&(*this).board[144])=b144;
01007 *((v2di*)&(*this).board[148])=b148;
01008 *((v2di*)&(*this).board[152])=b152;
01009
01010 v2di p0=*((v2di*)&src.pieces[0]);
01011 v2di p4=*((v2di*)&src.pieces[4]);
01012 v2di p8=*((v2di*)&src.pieces[8]);
01013 v2di p12=*((v2di*)&src.pieces[12]);
01014 v2di p16=*((v2di*)&src.pieces[16]);
01015 v2di p20=*((v2di*)&src.pieces[20]);
01016 v2di p24=*((v2di*)&src.pieces[24]);
01017 v2di p28=*((v2di*)&src.pieces[28]);
01018 v2di p32=*((v2di*)&src.pieces[32]);
01019 v2di p36=*((v2di*)&src.pieces[36]);
01020 *((v2di*)&(*this).pieces[0])=p0;
01021 *((v2di*)&(*this).pieces[4])=p4;
01022 *((v2di*)&(*this).pieces[8])=p8;
01023 *((v2di*)&(*this).pieces[12])=p12;
01024 *((v2di*)&(*this).pieces[16])=p16;
01025 *((v2di*)&(*this).pieces[20])=p20;
01026 *((v2di*)&(*this).pieces[24])=p24;
01027 *((v2di*)&(*this).pieces[28])=p28;
01028 *((v2di*)&(*this).pieces[32])=p32;
01029 *((v2di*)&(*this).pieces[36])=p36;
01030 }
01031 #else
01032 for(int x=1;x<=9;x++)
01033 for(int y=1;y<=9;y++)
01034 (*this).board[Square(x,y).index()]=src.board[Square(x,y).index()];
01035 (*this).pieces=src.pieces;
01036 #endif
01037 (*this).pawnMask=src.pawnMask;
01038 this->stand_count = src.stand_count;
01039 this->player_to_move=src.player_to_move;
01040 effects.copyFrom(src.effects);
01041 this->pieces_onboard=src.pieces_onboard;
01042 (*this).promoted=src.promoted;
01043 (*this).pin_or_open=src.pin_or_open;
01044 (*this).king_mobility=src.king_mobility;
01045 (*this).king8infos=src.king8infos;
01046 }
01047
01048 void osl::NumEffectState::copyFrom(const SimpleState& src)
01049 {
01050 copyFrom(NumEffectState(src));
01051 }
01052
01053 bool osl::NumEffectState::isSafeMove(Move move) const
01054 {
01055 using namespace move_classifier;
01056 return ConditionAdaptor<SafeMove>::isMember(*this, move);
01057 }
01058 bool osl::NumEffectState::isCheck(Move move) const
01059 {
01060 using namespace move_classifier;
01061 return PlayerMoveAdaptor<Check>::isMember(*this, move);
01062 }
01063 bool osl::NumEffectState::isPawnDropCheckmate(Move move) const
01064 {
01065 using namespace move_classifier;
01066 return PlayerMoveAdaptor<PawnDropCheckmate>::isMember(*this, move);
01067 }
01068 bool osl::NumEffectState::isDirectCheck(Move move) const
01069 {
01070 using namespace move_classifier;
01071 return PlayerMoveAdaptor<DirectCheck>::isMember(*this, move);
01072 }
01073
01074 bool osl::NumEffectState::isOpenCheck(Move move) const
01075 {
01076 using namespace move_classifier;
01077 return ConditionAdaptor<OpenCheck>::isMember(*this, move);
01078 }
01079
01080 #ifndef MINIMAL
01081 void osl::NumEffectState::generateAllUnsafe(MoveVector& out) const
01082 {
01083 move_action::Store store(out);
01084 move_generator::AllMoves<move_action::Store>::generate(turn(), *this, store);
01085 }
01086 void osl::NumEffectState::generateLegal(MoveVector& moves) const
01087 {
01088 if (inCheck()) {
01089
01090 GenerateEscapeKing::generate(*this, moves);
01091 }
01092 else {
01093
01094 MoveVector all_moves;
01095 GenerateAllMoves::generate(turn(), *this, all_moves);
01096
01097
01098 std::copy_if(all_moves.begin(), all_moves.end(), std::back_inserter(moves),
01099 [&](Move m){
01100 return this->isSafeMove(m) && ! this->isPawnDropCheckmate(m);
01101 });
01102 }
01103 }
01104
01105 void osl::NumEffectState::generateWithFullUnpromotions(MoveVector& moves) const
01106 {
01107 generateLegal(moves);
01108 if (inCheck())
01109 return;
01110 for (int i=0, iend=moves.size(); i<iend; ++i) {
01111 const Move move = moves[i];
01112 if (move.hasIgnoredUnpromote())
01113 moves.push_back(move.unpromote());
01114 }
01115 }
01116 #endif
01117
01118 void osl::NumEffectState::
01119 findEffect(Player P, Square target, PieceVector& out) const
01120 {
01121 effect_action::StorePiece store(&out);
01122 forEachEffect(P, target, store);
01123 }
01124
01125 namespace osl
01126 {
01127
01128
01129 template bool NumEffectState::
01130 hasEffectByWithRemove<BLACK>(Square, Square) const;
01131 template bool NumEffectState::
01132 hasEffectByWithRemove<WHITE>(Square, Square) const;
01133 template void NumEffectState::makeKing8Info<BLACK>();
01134 template void NumEffectState::makeKing8Info<WHITE>();
01135
01136
01137 template void NumEffectState::
01138 prologueSimple(Player2Type<BLACK>, Square, Square, int, Piece&, int&,
01139 PtypeO&, PtypeO&, CArray<PieceMask,2>&, KingMobility&,
01140 PieceMask&, CArray<PieceMask,2>&, CArray<PieceMask,2>&,
01141 CArray<uint64_t,2>&, MobilityTable&);
01142 template void NumEffectState::
01143 prologueSimple(Player2Type<WHITE>, Square, Square, int, Piece&, int&,
01144 PtypeO&, PtypeO&, CArray<PieceMask,2>&, KingMobility&,
01145 PieceMask&, CArray<PieceMask,2>&, CArray<PieceMask,2>&,
01146 CArray<uint64_t,2>&, MobilityTable&);
01147
01148 template void NumEffectState::
01149 prologueCapture(Player2Type<BLACK>, Square, Square, Piece, int, Piece&,
01150 PtypeO&, PtypeO&, PtypeO&, int&, int&, int&, mask_t&,
01151 CArray<PieceMask,2>&, KingMobility&, PieceMask&,
01152 CArray<PieceMask,2>&, CArray<PieceMask,2>&,
01153 CArray<uint64_t,2>&, MobilityTable&);
01154 template void NumEffectState::
01155 prologueCapture(Player2Type<WHITE>, Square, Square, Piece, int, Piece&,
01156 PtypeO&, PtypeO&, PtypeO&, int&, int&, int&, mask_t&,
01157 CArray<PieceMask,2>&, KingMobility&, PieceMask&,
01158 CArray<PieceMask,2>&, CArray<PieceMask,2>&,
01159 CArray<uint64_t,2>&, MobilityTable&);
01160
01161 template void NumEffectState::
01162 prologueDrop(Player2Type<BLACK>, Square, Ptype, Piece&, int&, PtypeO&,
01163 int&, mask_t&, CArray<PieceMask,2>&, KingMobility&,
01164 CArray<PieceMask,2>&, CArray<PieceMask,2>&,
01165 CArray<uint64_t,2>&, MobilityTable&);
01166 template void NumEffectState::
01167 prologueDrop(Player2Type<WHITE>, Square, Ptype, Piece&, int&, PtypeO&,
01168 int&, mask_t&, CArray<PieceMask,2>&, KingMobility&,
01169 CArray<PieceMask,2>&, CArray<PieceMask,2>&,
01170 CArray<uint64_t,2>&, MobilityTable&);
01171
01172 template void NumEffectState::
01173 epilogueCapture(Player2Type<BLACK>, Square, Square, Piece, Piece, PtypeO, PtypeO,
01174 PtypeO, int, int, int, mask_t, const CArray<PieceMask,2>&,
01175 const KingMobility&, const PieceMask&, const CArray<PieceMask,2>&,
01176 const CArray<PieceMask,2>&, const CArray<uint64_t,2>&,
01177 const MobilityTable&);
01178 template void NumEffectState::
01179 epilogueCapture(Player2Type<WHITE>, Square, Square, Piece, Piece, PtypeO, PtypeO,
01180 PtypeO, int, int, int, mask_t, const CArray<PieceMask,2>&,
01181 const KingMobility&, const PieceMask&, const CArray<PieceMask,2>&,
01182 const CArray<PieceMask,2>&, const CArray<uint64_t,2>&,
01183 const MobilityTable&);
01184 template void NumEffectState::
01185 epilogueDrop(Player2Type<BLACK>, Square, Ptype, Piece, int, PtypeO, int, mask_t,
01186 const CArray<PieceMask,2>&, const KingMobility&, const CArray<PieceMask,2>&,
01187 const CArray<PieceMask,2>&, const CArray<uint64_t,2>&, const MobilityTable&);
01188 template void NumEffectState::
01189 epilogueDrop(Player2Type<WHITE>, Square, Ptype, Piece, int, PtypeO, int, mask_t,
01190 const CArray<PieceMask,2>&, const KingMobility&, const CArray<PieceMask,2>&,
01191 const CArray<PieceMask,2>&, const CArray<uint64_t,2>&, const MobilityTable&);
01192
01193 #ifndef DFPNSTATONE
01194 template Piece
01195 NumEffectState::safeCaptureNotByKing<BLACK>(Square, Piece) const;
01196 template Piece
01197 NumEffectState::safeCaptureNotByKing<WHITE>(Square, Piece) const;
01198 #endif
01199 }
01200
01201
01202
01203
01204
01205