00001
00002
00003 #ifndef OSL_NUM_EFFECT_STATE_H
00004 #define OSL_NUM_EFFECT_STATE_H
00005
00006 #include "osl/effect/numSimpleEffect.h"
00007 #include "osl/mobility/kingMobility.h"
00008 #include "osl/misc/fastCopier.h"
00009 #include "osl/misc/align16New.h"
00010 #include <boost/cstdint.hpp>
00011
00012 namespace osl
00013 {
00014 namespace checkmate
00015 {
00016 class King8Info;
00017 }
00018 namespace state
00019 {
00020 class NumEffectState;
00026 bool operator==(const NumEffectState& st1, const NumEffectState& st2);
00027
00033 class NumEffectState : public SimpleState
00034 #if OSL_WORDSIZE == 32
00035 , public misc::Align16New
00036 #endif
00037 {
00038 effect::NumSimpleEffectTable effects;
00039 CArray<PieceMask,2> onBoardMask;
00041 PieceMask promoted;
00042 CArray<PieceMask,2> pin_or_open;
00043 KingMobility king_mobility;
00044 CArray<uint64_t,2> king8infos;
00045
00046 friend bool operator==(const NumEffectState& st1,const NumEffectState& st2);
00047 typedef NumEffectState state_t;
00048 friend class apply_move::ApplyDoUndoSimpleMove<BLACK,NumEffectState>;
00049 friend class apply_move::ApplyDoUndoCaptureMove<BLACK,NumEffectState>;
00050 friend class apply_move::ApplyDoUndoDropMove<BLACK,NumEffectState>;
00051 friend class apply_move::ApplyDoUndoSimpleMove<WHITE,NumEffectState>;
00052 friend class apply_move::ApplyDoUndoCaptureMove<WHITE,NumEffectState>;
00053 friend class apply_move::ApplyDoUndoDropMove<WHITE,NumEffectState>;
00054 friend class osl::misc::FastCopier;
00055 PieceMask& mutableOnBoardMask(Player p) {
00056 return onBoardMask[p];
00057 }
00058 public:
00059 const PieceMask& getOnBoardMask(Player p) const {
00060 return onBoardMask[p];
00061 }
00062 bool isOnBoardNum(int num) const
00063 {
00064 return getOnBoardMask(BLACK).test(num) ||
00065 getOnBoardMask(WHITE).test(num);
00066 }
00067
00070 template<Player P,Ptype T,typename F>
00071 void forEachOnBoard(F& func) const {
00072 mask_t onMask=getOnBoardMask(P).template selectBit<T>() ;
00073 while (onMask.any())
00074 {
00075 int num=onMask.takeOneBit()+((PtypeFuns<T>::indexNum)<<5);
00076 Piece p = getPieceOf(num);
00077 func(p);
00078 }
00079 }
00082 template<Player P,Ptype T,typename F>
00083 void forEachOnBoardPtypeStrict(F& func) const
00084 {
00085 mask_t mask=getOnBoardMask(P).template selectBit<T>() ;
00086 if (isPromoted(T))
00087 mask &= promoted.getMask<T>();
00088 else
00089 mask &= ~(promoted.getMask<T>());
00090 while (mask.any())
00091 {
00092 int num=mask.takeOneBit()+((PtypeFuns<T>::indexNum)<<5);
00093 func(getPieceOf(num));
00094 }
00095 }
00096
00097 explicit NumEffectState(const state::SimpleState& st=SimpleState(HIRATE));
00098 ~NumEffectState();
00099
00100 NumBitmapEffect getEffect(Position pos) const
00101 {
00102 return effects.getEffect(pos);
00103 }
00104 Position getMobility(Direction d,int num) const
00105 {
00106 return effects.mobilityTable.get(d,num);
00107 }
00108 void setMobility(Direction d,int num,Position pos)
00109 {
00110 effects.mobilityTable.set(d,num,pos);
00111 }
00112 Position kingMobilityAbs(Player p, Direction d) const
00113 {
00114 return Position::makeDirect(king_mobility[p][d]);
00115 }
00121 Position kingMobilityOfPlayer(Player p, Direction d) const
00122 {
00123 if (p == BLACK)
00124 d = inverse(d);
00125 return kingMobilityAbs(p, d);
00126 }
00127 const EffectedNumTable& longEffectNumTable() const
00128 {
00129 return effects.effectedNumTable;
00130 }
00135 const Piece longEffectOfDirection(Player owner, int piece, Direction d) const
00136 {
00137 assert(getPieceOf(piece).isOnBoardByOwner(owner));
00138 if (owner == BLACK)
00139 d = inverse(d);
00140 const int num = effects.effectedNumTable[piece][d];
00141 if (num == EMPTY_NUM)
00142 return Piece::EMPTY();
00143 return getPieceOf(num);
00144 }
00145 const Piece longEffectOfDirection(Player owner, Piece piece, Direction d) const
00146 {
00147 assert(piece.isPiece());
00148 assert(piece.owner() == owner);
00149 return longEffectOfDirection(owner, piece.number(), d);
00150 }
00151 const Piece longEffectOfDirection(Piece piece, Direction d) const
00152 {
00153 assert(piece.isPiece());
00154 return longEffectOfDirection(piece.owner(), piece, d);
00155 }
00156 const Piece longEffectOfDirection(Position square, Direction d) const
00157 {
00158 return longEffectOfDirection(getPieceOnBoard(square), d);
00159 }
00160 template <Ptype PTYPE>
00161 const mask_t effectBit(Player P, Position target) const
00162 {
00163 return getEffect(target).template selectBit<PTYPE>() & getOnBoardMask(P).template getMask<PTYPE>();
00164 }
00165 const mask_t effectBit(Player P, Ptype ptype, Position target) const;
00166 template <Ptype PTYPE> const mask_t selectLong(Position target) const
00167 {
00168 return getEffect(target).selectLong<PTYPE>() >> 8;
00169 }
00170 template <Ptype PTYPE> const mask_t selectLong(Position target, Player owner) const
00171 {
00172 return selectLong<PTYPE>(target) & getOnBoardMask(owner).getMask(1);
00173 }
00174 const mask_t selectLong(Position target, Player owner) const
00175 {
00176 return (getEffect(target).selectLong() >> 8)
00177 & getOnBoardMask(owner).getMask(1);
00178 }
00179
00180 const BoardMask changedEffects(Player pl) const{
00181 assert(! effects.changedEffects(pl).isInvalid());
00182 return effects.changedEffects(pl);
00183 }
00184 const BoardMask changedEffects() const{
00185 BoardMask ret = changedEffects(BLACK);
00186 return ret |= changedEffects(WHITE);
00187 }
00188 const NumBitmapEffect changedPieces() const{
00189 return effects.changedPieces();
00190 }
00191 template <Ptype PTYPE> bool longEffectChanged() const
00192 {
00193 return changedPieces().template hasLong<PTYPE>();
00194 }
00195 template <Ptype PTYPE> bool anyEffectChanged() const
00196 {
00197 return changedPieces().template hasAny<PTYPE>();
00198 }
00199 PieceMask pin(Player king) const
00200 {
00201 return pin_or_open[king]&getOnBoardMask(king);
00202 }
00203 PieceMask pinOrOpen(Player king) const
00204 {
00205 return pin_or_open[king];
00206 }
00207 uint64_t Iking8Info(Player king) const
00208 {
00209 return king8infos[king];
00210 }
00211 const checkmate::King8Info king8Info(Player king) const;
00212 const PieceMask promotedPieces() const { return promoted; }
00213 private:
00214 template<Direction DIR>
00215 void makePinOpenDir(Position target,
00216 PieceMask& pins, PieceMask const& onBoard,Player defense)
00217 {
00218 const Offset offset = DirectionTraits<DIR>::blackOffset();
00219 Position pos=target-offset;
00220 int num;
00221 while(Piece::isEmptyNum(num=getPieceAt(pos).number()))
00222 pos-=offset;
00223 king_mobility[defense][DIR]=static_cast<unsigned char>(pos.uintValue());
00224 if(Piece::isEdgeNum(num)) return;
00225 int num1=longEffectNumTable()[num][DIR];
00226 if(Piece::isPieceNum(num1) && onBoard.test(num1)){
00227 pins.set(num);
00228 }
00229 }
00230 void recalcPinOpen(Position changed, Direction &lastDir, Player defense)
00231 {
00232 Position target=getKingPosition(defense);
00233 #ifdef ALLOW_KING_ABSENCE
00234 if (target.isPieceStand())
00235 return;
00236 #endif
00237 const Direction longD=Board_Table.getLongDirection<BLACK>(changed,target);
00238 if(!isLong(longD) || (lastDir!=UL && longD==lastDir)) return;
00239 lastDir=longD;
00240 Direction shortD=longToShort(longD);
00241 {
00242
00243 Position oldPos=Position::makeDirect(king_mobility[defense][shortD]);
00244 int oldNum=getPieceAt(oldPos).number();
00245 if(Piece::isPieceNum(oldNum))
00246 pin_or_open[defense].reset(oldNum);
00247 }
00248 const Offset offset = Board_Table.getOffsetForBlack(longD);
00249 Position pos=target-offset;
00250 int num;
00251 while(Piece::isEmptyNum(num=getPieceAt(pos).number()))
00252 pos-=offset;
00253 king_mobility[defense][shortD]=static_cast<unsigned char>(pos.uintValue());
00254 if(Piece::isEdgeNum(num)) return;
00255 int num1=longEffectNumTable()[num][shortD];
00256 if(Piece::isPieceNum(num1) && getOnBoardMask(alt(defense)).test(num1)){
00257 pin_or_open[defense].set(num);
00258 }
00259 }
00260 PieceMask makePinOpen(Position target,Player defense);
00261 public:
00262 void makePinOpen(Player defense);
00263 template<Player P>
00264 void makeKing8Info();
00265 public:
00266 bool isConsistent(bool showError=true) const;
00268 bool isConsistent(const NumEffectState& prev, Move moved, bool show_error=true) const;
00269
00270 void doSimpleMove(Position from, Position to, int promoteMask);
00271 void doDropMove(Position to,Ptype ptype);
00272 void doCaptureMove(Position from, Position to, Piece target,int promoteMask);
00277 template<Direction Dir,Player P>
00278 bool hasEffectDir(Position to) const {
00279 BOOST_STATIC_ASSERT( (DirectionTraits<Dir>::isLong) );
00280 const PieceMask& onBoardMask=getOnBoardMask(P);
00281 mask_t mask1=onBoardMask.getMask(1);
00282 mask1 &= ((PtypeDirectionTraits<LANCE,Dir>::canMove
00283 ? mask_t::makeDirect(PtypeFuns<LANCE>::indexMask)
00284 : mask_t::makeDirect(0))
00285 | (PtypeDirectionTraits<BISHOP,Dir>::canMove
00286 ? mask_t::makeDirect(PtypeFuns<BISHOP>::indexMask)
00287 : mask_t::makeDirect(0))
00288 | (PtypeDirectionTraits<ROOK,Dir>::canMove
00289 ? mask_t::makeDirect(PtypeFuns<ROOK>::indexMask)
00290 : mask_t::makeDirect(0)));
00291 mask1 <<= 8;
00292
00293 mask1&=getEffect(to).getMask(1)& NumBitmapEffect::longEffectMask();
00294 while (mask1.any())
00295 {
00296 int num=mask1.takeOneBit()+NumBitmapEffect::longToNumOffset;
00297 Position from = getPieceOf(num).position();
00298 Direction dir=Board_Table.getLongDirection<BLACK>(Offset32(to,from));
00299 if (dir==DirectionPlayerTraits<Dir,P>::directionByBlack)
00300 return true;
00301 }
00302 return false;
00303 }
00307 template <Ptype PTYPE>
00308 bool hasEffectLong(Player P, Position to) const {
00309 BOOST_STATIC_ASSERT( (PTYPE == LANCE || PTYPE == BISHOP || PTYPE == ROOK) );
00310 const PieceMask& onBoardMask=getOnBoardMask(P);
00311 mask_t mask1=onBoardMask.getMask(1);
00312 mask1 &= mask_t::makeDirect(PtypeFuns<PTYPE>::indexMask);
00313 mask1 <<= 8;
00314
00315 mask1&=getEffect(to).getMask(1)& NumBitmapEffect::longEffectMask();
00316 return mask1.any();
00317 }
00323 bool hasEffectBy(Player player,Position target) const {
00324 assert(target.isOnBoard());
00325 mask_t mask=getEffect(target).getMask(1);
00326 mask&=NumBitmapEffect::playerEffectMask(player);
00327 return !mask.none();
00328 }
00332 template<Player P>
00333 bool hasEffectByNotPinned(Position target) const{
00334 assert(target.isOnBoard());
00335 PieceMask m=getOnBoardMask(P)& ~pinOrOpen(alt(P)) & getEffect(target);
00336 return m.any();
00337 }
00345 bool hasEffectNotBy(Player player,Piece piece,Position target) const {
00346 assert(piece.owner()==player);
00347 PieceMask onBoardMask=getOnBoardMask(player);
00348 int num=piece.number();
00349 onBoardMask.reset(num);
00350 return (onBoardMask&getEffect(target)).any();
00351 }
00359 bool hasEffectNotMask(Player player,Position target,PieceMask const& notMask) const {
00360 PieceMask onBoardMask=getOnBoardMask(player);
00361 return (onBoardMask&getEffect(target)¬Mask).any();
00362 }
00369 bool hasMultipleEffectBy(Player player,Position target) const
00370 {
00371 mask_t mask=getEffect(target).getMask(1);
00372 mask&=NumBitmapEffect::playerEffectMask(player);
00373 return NumBitmapEffect::playerEffect(player).getMask(1) < mask;
00374 }
00375
00380 bool hasEffectByPiece(Piece attack, Position target) const
00381 {
00382 assert(attack.isPiece());
00383 assert(target.isOnBoard());
00384 return getEffect(target).test(attack.number());
00385 }
00386
00390 template <Ptype PTYPE>
00391 bool hasEffectByPtype(Player attack, Position target) const
00392 {
00393 return effectBit<PTYPE>(attack, target).any();
00394 }
00398 template <Ptype PTYPE>
00399 bool hasEffectByPtypeStrict(Player attack, Position target) const
00400 {
00401 mask_t mask=effectBit<PTYPE>(attack, target);
00402 if (isPromoted(PTYPE))
00403 mask &= promoted.getMask<PTYPE>();
00404 else
00405 mask &= ~(promoted.getMask<PTYPE>());
00406 return mask.any();
00407 }
00409 template <Ptype PTYPE>
00410 const Piece effectPtype(Player attack, Position target) const
00411 {
00412 mask_t mask=effectBit<PTYPE>(attack, target);
00413 if (mask.none())
00414 return Piece::EMPTY();
00415 return getPieceOf(mask.takeOneBit()+PtypeFuns<PTYPE>::indexNum*32);
00416 }
00417 template <Ptype PTYPE>
00418 const Piece effectPtypeStrict(Player attack, Position target) const
00419 {
00420 mask_t mask=effectBit<PTYPE>(attack, target);
00421 if (isPromoted(PTYPE))
00422 mask &= promoted.getMask<PTYPE>();
00423 else
00424 mask &= ~(promoted.getMask<PTYPE>());
00425 if (mask.none())
00426 return Piece::EMPTY();
00427 return getPieceOf(mask.takeOneBit()+PtypeFuns<PTYPE>::indexNum*32);
00428 }
00429
00434 int countEffect(Player player,Position target) const
00435 {
00436 assert(target.isOnBoard());
00437 return getEffect(target).countEffect(player);
00438 }
00444 int countEffect(Player player,Position target, PieceMask pins) const
00445 {
00446 assert(target.isOnBoard());
00447 const NumBitmapEffect effect = getEffect(target);
00448 const int all = effect.countEffect(player);
00449 pins &= effect;
00450 return all - pins.countBit();
00451 }
00456 template<Player P,Ptype Type,class Action>
00457 void forEachEffectPtype(Position pos,Action & action) const {
00458 mask_t mask=effectBit<Type>(P, pos);
00459 while (mask.any())
00460 {
00461 int num=mask.takeOneBit()+(PtypeFuns<Type>::indexNum<<5);
00462 action.template doActionPtype<P,Type>(getPieceOf(num),pos);
00463 }
00464 }
00465
00466 private:
00467 template<Player P,class Action>
00468 void forEachEffect(const PieceMask& pieces, Position pos,Action & action) const
00469 {
00470 #if OSL_WORDSIZE == 64
00471 mask_t mask=pieces.getMask(0);
00472 while (mask.any())
00473 {
00474 const int num=mask.takeOneBit();
00475 action.template doAction<P>(getPieceOf(num),pos);
00476 }
00477 #elif OSL_WORDSIZE == 32
00478 mask_t mask0=pieces.getMask(0);
00479 while (mask0.any())
00480 {
00481 const int num=mask0.takeOneBit();
00482 action.template doAction<P>(getPieceOf(num),pos);
00483 }
00484 mask_t mask1=pieces.getMask(1);
00485 while (mask1.any())
00486 {
00487 const int num=mask1.takeOneBit()+32;
00488 action.template doAction<P>(getPieceOf(num),pos);
00489 }
00490 #endif
00491 }
00492 public:
00497 template<Player P,class Action>
00498 void forEachEffect(Position pos,Action & action) const
00499 {
00500 const PieceMask pieceMask=getOnBoardMask(P)&getEffect(pos);
00501 forEachEffect<P,Action>(pieceMask, pos, action);
00502 }
00508 template<Player P,class Action>
00509 void forEachEffect(Position pos,Action & action,const PieceMask& pin) const
00510 {
00511 PieceMask pieceMask=getOnBoardMask(P)&getEffect(pos);
00512 pieceMask &= ~pin;
00513 forEachEffect<P,Action>(pieceMask, pos, action);
00514 }
00515
00521 template<Player P,class Action>
00522 void forEachEffectNotBy(Position pos,Piece piece,Action & action) const {
00523 PieceMask pieces=getOnBoardMask(P)&getEffect(pos);
00524 pieces.reset(piece.number());
00525 forEachEffect<P,Action>(pieces, pos, action);
00526 }
00527
00533 template<Player P>
00534 bool hasEffectBy(Position target) const {
00535 assert(target.isOnBoard());
00536 mask_t mask=getEffect(target).getMask(1);
00537 mask&=NumBitmapEffect::playerEffectMask<P>();
00538 return !mask.none();
00539 }
00540
00541 bool hasEffectBy(Player P, Position target,Piece& attackerPiece) const
00542 {
00543 if (P == BLACK)
00544 return hasEffectBy<BLACK>(target, attackerPiece);
00545 else
00546 return hasEffectBy<WHITE>(target, attackerPiece);
00547 }
00554 template<Player P>
00555 bool hasEffectBy(Position target,Piece& attackerPiece) const {
00556 attackerPiece=Piece::EMPTY();
00557 const PieceMask& pieceMask=getOnBoardMask(P)&getEffect(target);
00558 #if OSL_WORDSIZE == 64
00559 mask_t mask=pieceMask.getMask(0);
00560 if (mask.none()) return false;
00565 if (mask.hasMultipleBit())
00566 return true;
00567 int num=mask.bsf();
00568 attackerPiece=getPieceOf(num);
00569 return true;
00570 #elif OSL_WORDSIZE == 32
00571 mask_t mask0=pieceMask.getMask(0);
00572 mask_t mask1=pieceMask.getMask(1);
00573 if (mask0.any())
00574 {
00575 if (mask1.any())
00576 return true;
00577 int num=mask0.bsf();
00578 if (mask0 == PieceMask::numToMask(num))
00579 attackerPiece=getPieceOf(num);
00580 return true;
00581 }
00582 else if (mask1.any())
00583 {
00584 int num=mask1.bsf();
00585 if (mask1==PieceMask::numToMask(num))
00586 attackerPiece=getPieceOf(num+32);
00587 return true;
00588 }
00589 else
00590 return false;
00591 #endif
00592 }
00596 const Piece selectCheapPiece(PieceMask effect) const;
00602 const Piece findCheapThreat(Player P, Position square) const
00603 {
00604 return selectCheapPiece(getOnBoardMask(P) & getEffect(square));
00605 }
00611 const Piece findCheapThreatNotBy(Player P, Position square, const PieceMask& ignore) const
00612 {
00613 PieceMask pieces = getOnBoardMask(P);
00614 pieces &= ~ignore;
00615 return selectCheapPiece(pieces & getEffect(square));
00616 }
00617 const Piece findThreatNotBy(Player P, Position square, const PieceMask& ignore) const
00618 {
00619 PieceMask pieces = getOnBoardMask(P);
00620 pieces &= ~ignore;
00621 pieces &= getEffect(square);
00622 if (pieces.none())
00623 return Piece::EMPTY();
00624 return getPieceOf(pieces.takeOneBit());
00625 }
00626
00628 const Piece findThreatenedPiece(Player P) const;
00629
00631 bool inCheck(Player P) const
00632 {
00633 const Position king = getKingPosition(P);
00634 #ifdef ALLOW_KING_ABSENCE
00635 if (king.isPieceStand())
00636 return false;
00637 #endif
00638 return hasEffectBy(alt(P), king);
00639 }
00641 bool inCheck() const { return inCheck(getTurn()); }
00650 template<Player P>
00651 bool findCheckPiece(Piece& attack_piece) const
00652 {
00653 return hasEffectBy<PlayerTraits<P>::opponent>(getKingPosition(P),attack_piece);
00654 }
00665 template <bool show_error>
00666 bool isAlmostValidMove(Move move) const;
00667 bool isAlmostValidMove(Move move,bool show_error=true) const;
00668
00669 private:
00670 template<Player P,Ptype Type,class Action,Direction Dir>
00671 void forEachEffectOfPieceDir(Position, Action&, Int2Type<false>) const {}
00672 template<Player P,Ptype Type,class Action,Direction Dir>
00673 void forEachEffectOfPieceDir(Position piecePosition,Action & action,Int2Type<true>) const {
00674 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00675 action.template doAction<P>(this->getPieceAt(piecePosition),piecePosition+offset);
00676 }
00677
00678 template<Player P,Ptype Type,class Action,Direction Dir>
00679 void forEachEffectOfPieceDir(Position piecePosition,Action & action) const {
00680 forEachEffectOfPieceDir<P,Type,Action,Dir>(piecePosition,action,Int2Type<(PtypeTraits<Type>::moveMask & DirectionTraits<Dir>::mask)!=0>());
00681 }
00682 template<Player P,Ptype Type,class Action,Direction Dir>
00683 void forEachEffectOfPieceLongDir(Position, Action&, Int2Type<false>) const {}
00684 template<Player P,Ptype Type,class Action,Direction Dir>
00685 void forEachEffectOfPieceLongDir(Position piecePosition,Action & action,Int2Type<true>) const {
00686 Piece piece=this->getPieceAt(piecePosition);
00687 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00688 assert(offset.intValue() != 35);
00689 Position pos=piecePosition+offset;
00690 for (;this->getPieceAt(pos).isEmpty();pos+=offset)
00691 action.template doAction<P>(piece,pos);
00692 action.template doAction<P>(piece,pos);
00693 }
00694
00695 template<Player P,Ptype Type,class Action,Direction Dir>
00696 void forEachEffectOfPieceLongDir(Position piecePosition,Action & action) const {
00697 forEachEffectOfPieceLongDir<P,Type,Action,Dir>(piecePosition,action,Int2Type<(PtypeTraits<Type>::moveMask & DirectionTraits<Dir>::mask)!=0>());
00698 }
00699 public:
00707 template<Player P,Ptype Type,class Action>
00708 void forEachEffectOfPiece(Position piecePosition,Action & action) const;
00709 template<class Action>
00710 void forEachEffectOfPiece(Piece piece,Action & action) const;
00711
00719 bool hasEffectFromTo(PtypeO ptypeo,Position attacker,
00720 Position target) const
00721 {
00722 Offset32 offset32=Offset32(target,attacker);
00723 EffectContent effect=Ptype_Table.getEffect(ptypeo,offset32);
00724 if (! effect.hasEffect())
00725 return false;
00726 if (effect.hasUnblockableEffect())
00727 return true;
00728 assert(Board_Table.getShortOffset(offset32) == effect.offset());
00729 return this->isEmptyBetween(attacker,target,effect.offset());
00730 }
00734 template<Player P>
00735 bool hasEffectByWithRemove(Position target,Position removed) const;
00736
00737 bool hasEffectByWithRemove(Player player, Position target,Position removed) const{
00738 if (player==BLACK)
00739 return hasEffectByWithRemove<BLACK>(target,removed);
00740 else
00741 return hasEffectByWithRemove<WHITE>(target,removed);
00742 }
00743
00744 void showEffect(std::ostream& os) const;
00745
00747 const PieceMask effectedMask(Player pl) const
00748 {
00749 return effects.effected_mask[pl];
00750 }
00754 const PieceMask effectedChanged(Player pl) const
00755 {
00756 return effects.effected_changed_mask[pl];
00757 }
00758 void makeMovePass()
00759 {
00760 changeTurn();
00761 effects.clearChangedEffects();
00762 effects.clearEffectedChanged();
00763 }
00768 template<Player P>
00769 Direction pinnedDir(Piece p) const
00770 {
00771 assert(pinOrOpen(P).test(p.number()));
00772 Position king=getKingPosition<P>();
00773 return Board_Table.getShort8<P>(p.position(),king);
00774 }
00779 template<Player P>
00780 bool pinnedCanMoveTo(Piece p,Position to) const
00781 {
00782 Direction d=pinnedDir<P>(p);
00783 Position from=p.position();
00784 assert(hasEffectFromTo(p.ptypeO(),from,to));
00785 return primDir(d)==primDirUnsafe(Board_Table.getShort8Unsafe<P>(from,to));
00786 }
00787 };
00788
00789 inline bool operator!=(const NumEffectState& s1,
00790 const NumEffectState& s2)
00791 {
00792 return !(s1==s2);
00793 }
00794 }
00795 using state::NumEffectState;
00796
00797 namespace apply_move
00798 {
00799 template<Player P>
00800 struct ApplyDoUndoSimpleMove<P,NumEffectState>
00801 {
00802 typedef NumEffectState state_t;
00803 template <typename F>
00804 static void doUndoSimpleMove(state_t& s,
00805 Position from, Position to, int promoteMask,F& func);
00806
00807 static
00808 void prologue(state_t& s, Position from, Position to, int promoteMask,
00809 Piece& oldPiece, int& num,
00810 PtypeO& oldPtypeO, PtypeO& new_ptypeo,
00811 CArray<PieceMask,2>& pin_or_open_backup,
00812 KingMobility& king_mobility_backup,
00813 PieceMask& promoted_backup,
00814 CArray<PieceMask,2>& effected_mask_backup,
00815 CArray<PieceMask,2>& effected_changed_mask_backup,
00816 CArray<uint64_t,2>& king8infos_backup,
00817 MobilityTable &mobility_backup
00818 );
00819 static
00820 void epilogue(state_t& s, Position from, Position to, Piece oldPiece,
00821 int num, PtypeO oldPtypeO, PtypeO newPtypeO,
00822 const CArray<PieceMask,2>& pin_or_open_backup,
00823 const KingMobility& king_mobility_backup,
00824 const PieceMask& promoted_backup,
00825 const CArray<PieceMask,2>& effected_mask_backup,
00826 const CArray<PieceMask,2>& effected_changed_mask_backup,
00827 const CArray<uint64_t,2>& king8infos_backup,
00828 const MobilityTable &mobility_backup
00829 );
00830 };
00831
00832
00833 template<Player P>
00834 template <typename F>
00835 void ApplyDoUndoSimpleMove<P,NumEffectState>::
00836 doUndoSimpleMove(state_t& s,
00837 Position from, Position to, int promoteMask,F& func)
00838 {
00839 Piece oldPiece;
00840 int num;
00841 PtypeO oldPtypeO, newPtypeO;
00842 CArray<PieceMask,2> pin_or_open_backup;
00843 KingMobility king_mobility_backup;
00844 PieceMask promoted_backup;
00845 CArray<PieceMask,2> effected_mask_backup;
00846 CArray<PieceMask,2> effected_changed_mask_backup;
00847 CArray<uint64_t,2> king8infos_backup;
00848 MobilityTable mobility_backup;
00849 prologue(s, from, to, promoteMask, oldPiece, num, oldPtypeO, newPtypeO,
00850 pin_or_open_backup,
00851 king_mobility_backup,
00852 promoted_backup,
00853 effected_mask_backup, effected_changed_mask_backup,
00854 king8infos_backup,
00855 mobility_backup);
00856
00857 if (promoteMask!=0 && num < PtypeTraits<PAWN>::indexLimit)
00858 {
00859 s.clearPawn(P,from);
00860 s.changeTurn();
00861 func(to);
00862 s.changeTurn();
00863 s.setPawn(P,from);
00864 }
00865 else
00866 {
00867 s.changeTurn();
00868 func(to);
00869 s.changeTurn();
00870 }
00871
00872 epilogue(s, from, to, oldPiece, num, oldPtypeO, newPtypeO,
00873 pin_or_open_backup,
00874 king_mobility_backup,
00875 promoted_backup, effected_mask_backup, effected_changed_mask_backup,
00876 king8infos_backup,
00877 mobility_backup);
00878 }
00879
00880 template<Player P>
00881 struct ApplyDoUndoDropMove<P,NumEffectState>
00882 {
00883 typedef NumEffectState state_t;
00884 template <typename F>
00885 static void doUndoDropMove(state_t& s,
00886 Position to, Ptype ptype,F& func);
00887 static
00888 void prologue(state_t& s, Position to, Ptype ptype,
00889 Piece& oldPiece, int& num, PtypeO& ptypeO,
00890 int& numIndex, mask_t& numMask,
00891 CArray<PieceMask,2>& pin_or_open_backup,
00892 KingMobility& king_mobility_backup,
00893 CArray<PieceMask,2>& effected_mask_backup,
00894 CArray<PieceMask,2>& effected_changed_mask_backup,
00895 CArray<uint64_t,2>& king8infos_backup,
00896 MobilityTable &mobility_backup
00897 );
00898 static
00899 void epilogue(state_t& s, Position to, Ptype ptype, Piece oldPiece,
00900 int num, PtypeO ptypeO, int numIndex, mask_t numMask,
00901 const CArray<PieceMask,2>& pin_or_open_backup,
00902 const KingMobility& king_mobility_backup,
00903 const CArray<PieceMask,2>& effected_mask_backup,
00904 const CArray<PieceMask,2>& effected_changed_mask_backup,
00905 const CArray<uint64_t,2>& king8infos_backup,
00906 const MobilityTable &mobility_backup
00907 );
00908 };
00909
00910 template<Player P>
00911 template <typename F>
00912 void ApplyDoUndoDropMove<P,NumEffectState>::
00913 doUndoDropMove(state_t& s,
00914 Position to, Ptype ptype,F& func)
00915 {
00916 Piece oldPiece;
00917 PtypeO ptypeO;
00918 int num, numIndex;
00919 mask_t numMask;
00920 CArray<PieceMask,2> pin_or_open_backup;
00921 KingMobility king_mobility_backup;
00922 CArray<PieceMask,2> effected_mask_backup;
00923 CArray<PieceMask,2> effected_changed_mask_backup;
00924 CArray<uint64_t,2> king8infos_backup;
00925 MobilityTable mobility_backup;
00926 prologue(s, to, ptype, oldPiece, num, ptypeO, numIndex, numMask,
00927 pin_or_open_backup, king_mobility_backup,
00928 effected_mask_backup,effected_changed_mask_backup,
00929 king8infos_backup,
00930 mobility_backup);
00931
00932 if (ptype==PAWN)
00933 {
00934 s.setPawn(P,to);
00935 s.changeTurn();
00936 func(to);
00937 s.changeTurn();
00938 s.clearPawn(P,to);
00939 }
00940 else
00941 {
00942 s.changeTurn();
00943 func(to);
00944 s.changeTurn();
00945 }
00946 epilogue(s, to, ptype, oldPiece, num, ptypeO, numIndex, numMask,
00947 pin_or_open_backup, king_mobility_backup,
00948 effected_mask_backup,effected_changed_mask_backup,
00949 king8infos_backup,
00950 mobility_backup);
00951 }
00952
00953 template<Player P>
00954 struct ApplyDoUndoCaptureMove<P,NumEffectState>
00955 {
00956 typedef NumEffectState state_t;
00957 template <typename F>
00958 static void doUndoCaptureMove(state_t& s, Position from,Position to,
00959 Piece target, int promoteMask,F& func);
00960 static
00961 void prologue(state_t& s, Position from, Position to, Piece target,
00962 int promoteMask,
00963 Piece& oldPiece, PtypeO& oldPtypeO, PtypeO& capturePtypeO,
00964 PtypeO& new_ptypeo, int& num0, int& num1,
00965 int& num1Index, mask_t& num1Mask,
00966 CArray<PieceMask,2>& pin_or_open_backup,
00967 KingMobility& king_mobility_backup,
00968 PieceMask& promoted_backup,
00969 CArray<PieceMask,2>& effected_mask_backup,
00970 CArray<PieceMask,2>& effected_changed_mask_backup,
00971 CArray<uint64_t,2>& king8infos_backup,
00972 MobilityTable &mobility_backup
00973 );
00974 static
00975 void epilogue(state_t& s, Position from, Position to, Piece target,
00976 Piece oldPiece, PtypeO oldPtypeO, PtypeO capturePtypeO,
00977 PtypeO newPtypeO, int num0, int num1,
00978 int num1Index, mask_t num1Mask,
00979 const CArray<PieceMask,2>& pin_or_open_backup,
00980 const KingMobility& king_mobility_backup,
00981 const PieceMask& promoted_backup,
00982 const CArray<PieceMask,2>& effected_mask_backup,
00983 const CArray<PieceMask,2>& effected_changed_mask_backup,
00984 const CArray<uint64_t,2>& king8infos_backup,
00985 const MobilityTable &mobility_backup
00986 );
00987 };
00988
00989 template<Player P>
00990 template <typename F>
00991 void ApplyDoUndoCaptureMove<P,NumEffectState>::
00992 doUndoCaptureMove(state_t& s, Position from,Position to, Piece target,
00993 int promoteMask,F& func)
00994 {
00995 Piece oldPiece;
00996 PtypeO oldPtypeO, capturePtypeO, newPtypeO;
00997 int num0, num1, num1Index;
00998 mask_t num1Mask;
00999 CArray<PieceMask,2> pin_or_open_backup;
01000 KingMobility king_mobility_backup;
01001 PieceMask promoted_backup;
01002 CArray<PieceMask,2> effected_mask_backup;
01003 CArray<PieceMask,2> effected_changed_mask_backup;
01004 CArray<uint64_t,2> king8infos_backup;
01005 MobilityTable mobility_backup;
01006 prologue(s, from, to, target, promoteMask, oldPiece, oldPtypeO,
01007 capturePtypeO, newPtypeO, num0, num1, num1Index,num1Mask,
01008 pin_or_open_backup, king_mobility_backup,
01009 promoted_backup,
01010 effected_mask_backup, effected_changed_mask_backup,
01011 king8infos_backup,
01012 mobility_backup);
01013
01014 s.changeTurn();
01015 const Ptype capturePtype=target.ptype();
01016 if (capturePtype==PAWN)
01017 {
01018 s.clearPawn(PlayerTraits<P>::opponent,to);
01019 if (promoteMask!=0 && num0<PtypeTraits<PAWN>::indexLimit)
01020 {
01021 s.clearPawn(P,from);
01022 func(to);
01023 s.setPawn(P,from);
01024 }
01025 else
01026 {
01027 func(to);
01028 }
01029 s.setPawn(PlayerTraits<P>::opponent,to);
01030 }
01031 else if (promoteMask!=0 && num0<PtypeTraits<PAWN>::indexLimit)
01032 {
01033 s.clearPawn(P,from);
01034 func(to);
01035 s.setPawn(P,from);
01036 }
01037 else
01038 {
01039 func(to);
01040 }
01041 s.changeTurn();
01042
01043 epilogue(s, from, to, target, oldPiece, oldPtypeO, capturePtypeO, newPtypeO,
01044 num0, num1, num1Index,num1Mask,
01045 pin_or_open_backup, king_mobility_backup,
01046 promoted_backup,effected_mask_backup, effected_changed_mask_backup,
01047 king8infos_backup,
01048 mobility_backup);
01049 }
01050 }
01051 using state::NumEffectState;
01052 }
01053
01054 template <class Action>
01055 void osl::NumEffectState::
01056 forEachEffectOfPiece(Piece piece,Action & action) const
01057 {
01058 Position piecePosition = piece.position();
01059 switch (piece.ptypeO()) {
01060 case NEW_PTYPEO(WHITE,PAWN): forEachEffectOfPiece<WHITE,PAWN,Action>(piecePosition,action); break;
01061 case NEW_PTYPEO(WHITE,LANCE): forEachEffectOfPiece<WHITE,LANCE,Action>(piecePosition,action); break;
01062 case NEW_PTYPEO(WHITE,KNIGHT): forEachEffectOfPiece<WHITE,KNIGHT,Action>(piecePosition,action); break;
01063 case NEW_PTYPEO(WHITE,SILVER): forEachEffectOfPiece<WHITE,SILVER,Action>(piecePosition,action); break;
01064 case NEW_PTYPEO(WHITE,PPAWN): forEachEffectOfPiece<WHITE,PPAWN,Action>(piecePosition,action); break;
01065 case NEW_PTYPEO(WHITE,PLANCE): forEachEffectOfPiece<WHITE,PLANCE,Action>(piecePosition,action); break;
01066 case NEW_PTYPEO(WHITE,PKNIGHT): forEachEffectOfPiece<WHITE,PKNIGHT,Action>(piecePosition,action); break;
01067 case NEW_PTYPEO(WHITE,PSILVER): forEachEffectOfPiece<WHITE,PSILVER,Action>(piecePosition,action); break;
01068 case NEW_PTYPEO(WHITE,GOLD): forEachEffectOfPiece<WHITE,GOLD,Action>(piecePosition,action); break;
01069 case NEW_PTYPEO(WHITE,BISHOP): forEachEffectOfPiece<WHITE,BISHOP,Action>(piecePosition,action); break;
01070 case NEW_PTYPEO(WHITE,PBISHOP): forEachEffectOfPiece<WHITE,PBISHOP,Action>(piecePosition,action); break;
01071 case NEW_PTYPEO(WHITE,ROOK): forEachEffectOfPiece<WHITE,ROOK,Action>(piecePosition,action); break;
01072 case NEW_PTYPEO(WHITE,PROOK): forEachEffectOfPiece<WHITE,PROOK,Action>(piecePosition,action); break;
01073 case NEW_PTYPEO(WHITE,KING): forEachEffectOfPiece<WHITE,KING,Action>(piecePosition,action); break;
01074 case NEW_PTYPEO(BLACK,PAWN): forEachEffectOfPiece<BLACK,PAWN,Action>(piecePosition,action); break;
01075 case NEW_PTYPEO(BLACK,LANCE): forEachEffectOfPiece<BLACK,LANCE,Action>(piecePosition,action); break;
01076 case NEW_PTYPEO(BLACK,KNIGHT): forEachEffectOfPiece<BLACK,KNIGHT,Action>(piecePosition,action); break;
01077 case NEW_PTYPEO(BLACK,SILVER): forEachEffectOfPiece<BLACK,SILVER,Action>(piecePosition,action); break;
01078 case NEW_PTYPEO(BLACK,PPAWN): forEachEffectOfPiece<BLACK,PPAWN,Action>(piecePosition,action); break;
01079 case NEW_PTYPEO(BLACK,PLANCE): forEachEffectOfPiece<BLACK,PLANCE,Action>(piecePosition,action); break;
01080 case NEW_PTYPEO(BLACK,PKNIGHT): forEachEffectOfPiece<BLACK,PKNIGHT,Action>(piecePosition,action); break;
01081 case NEW_PTYPEO(BLACK,PSILVER): forEachEffectOfPiece<BLACK,PSILVER,Action>(piecePosition,action); break;
01082 case NEW_PTYPEO(BLACK,GOLD): forEachEffectOfPiece<BLACK,GOLD,Action>(piecePosition,action); break;
01083 case NEW_PTYPEO(BLACK,BISHOP): forEachEffectOfPiece<BLACK,BISHOP,Action>(piecePosition,action); break;
01084 case NEW_PTYPEO(BLACK,PBISHOP): forEachEffectOfPiece<BLACK,PBISHOP,Action>(piecePosition,action); break;
01085 case NEW_PTYPEO(BLACK,ROOK): forEachEffectOfPiece<BLACK,ROOK,Action>(piecePosition,action); break;
01086 case NEW_PTYPEO(BLACK,PROOK): forEachEffectOfPiece<BLACK,PROOK,Action>(piecePosition,action); break;
01087 case NEW_PTYPEO(BLACK,KING): forEachEffectOfPiece<BLACK,KING,Action>(piecePosition,action); break;
01088 default: assert(0);
01089 }
01090 }
01091
01092 template <osl::Player P, osl::Ptype Type, class Action>
01093 void osl::NumEffectState::
01094 forEachEffectOfPiece(Position piecePosition,Action & action) const
01095 {
01096 forEachEffectOfPieceDir<P,Type,Action,UL>(piecePosition,action);
01097 forEachEffectOfPieceDir<P,Type,Action,U>(piecePosition,action);
01098 forEachEffectOfPieceDir<P,Type,Action,UR>(piecePosition,action);
01099 forEachEffectOfPieceDir<P,Type,Action,L>(piecePosition,action);
01100 forEachEffectOfPieceDir<P,Type,Action,R>(piecePosition,action);
01101 forEachEffectOfPieceDir<P,Type,Action,DL>(piecePosition,action);
01102 forEachEffectOfPieceDir<P,Type,Action,D>(piecePosition,action);
01103 forEachEffectOfPieceDir<P,Type,Action,DR>(piecePosition,action);
01104 forEachEffectOfPieceDir<P,Type,Action,UUL>(piecePosition,action);
01105 forEachEffectOfPieceDir<P,Type,Action,UUR>(piecePosition,action);
01106 forEachEffectOfPieceLongDir<P,Type,Action,LONG_UL>(piecePosition,action);
01107 forEachEffectOfPieceLongDir<P,Type,Action,LONG_U>(piecePosition,action);
01108 forEachEffectOfPieceLongDir<P,Type,Action,LONG_UR>(piecePosition,action);
01109 forEachEffectOfPieceLongDir<P,Type,Action,LONG_L>(piecePosition,action);
01110 forEachEffectOfPieceLongDir<P,Type,Action,LONG_R>(piecePosition,action);
01111 forEachEffectOfPieceLongDir<P,Type,Action,LONG_DL>(piecePosition,action);
01112 forEachEffectOfPieceLongDir<P,Type,Action,LONG_D>(piecePosition,action);
01113 forEachEffectOfPieceLongDir<P,Type,Action,LONG_DR>(piecePosition,action);
01114 }
01115
01116 template<osl::Player P>
01117 void osl::apply_move::ApplyDoUndoSimpleMove<P,osl::state::NumEffectState>::
01118 prologue(state_t& s, Position from, Position to, int promoteMask,
01119 Piece& oldPiece, int& num,
01120 PtypeO& oldPtypeO, PtypeO& new_ptypeo,
01121 CArray<PieceMask,2>& pin_or_open_backup,
01122 KingMobility& king_mobility_backup,
01123 PieceMask& promoted_backup,
01124 CArray<PieceMask,2>& effected_mask_backup,
01125 CArray<PieceMask,2>& effected_changed_mask_backup,
01126 CArray<uint64_t,2>& king8infos_backup,
01127 MobilityTable &mobility_backup)
01128 {
01129 mobility_backup = s.effects.mobilityTable;
01130 pin_or_open_backup = s.pin_or_open;
01131 king_mobility_backup = s.king_mobility;
01132 effected_mask_backup = s.effects.effected_mask;
01133 effected_changed_mask_backup = s.effects.effected_changed_mask;
01134 king8infos_backup=s.king8infos;
01135
01136 oldPiece=s.getPieceAt(from);
01137 Piece newPiece=oldPiece.promoteWithMask(promoteMask);
01138 newPiece+=(to-from);
01139 num=oldPiece.number();
01140
01141 oldPtypeO=oldPiece.ptypeO();
01142 new_ptypeo=newPiece.ptypeO();
01143
01144 s.setPieceOf(num,newPiece);
01145 s.effects.clearChangedEffects();
01146 s.effects.clearEffectedChanged();
01147 s.effects.template doEffect<NumBitmapEffect::Sub,true>(s,oldPtypeO,from,num);
01148
01149
01150 s.effects.effectedNumTable[num].clear();
01151 s.setBoard(to,newPiece);
01152 s.effects.template doBlockAt<NumBitmapEffect::Sub,true>(s,to,num);
01153 s.setBoard(from,Piece::EMPTY());
01154 s.effects.template doBlockAt<NumBitmapEffect::Add,true>(s,from,num);
01155 s.effects.template doEffect<NumBitmapEffect::Add,true>(s,new_ptypeo,to,num);
01156
01157 if (oldPtypeO == newPtypeO(P,KING))
01158 s.makePinOpen(P);
01159 else {
01160 Direction lastD=UL;
01161 s.pin_or_open[P].reset(num);
01162 s.recalcPinOpen(from,lastD,P);
01163 s.recalcPinOpen(to,lastD,P);
01164 }
01165 {
01166 Direction lastD=UL;
01167 s.pin_or_open[alt(P)].reset(num);
01168 s.recalcPinOpen(from,lastD,alt(P));
01169 s.recalcPinOpen(to,lastD,alt(P));
01170 }
01171 promoted_backup = s.promoted;
01172 if (promoteMask)
01173 s.promoted.set(num);
01174 if(s.hasEffectBy(BLACK,to))
01175 s.effects.effected_mask[BLACK].set(num);
01176 else
01177 s.effects.effected_mask[BLACK].reset(num);
01178 if(s.hasEffectBy(WHITE,to))
01179 s.effects.effected_mask[WHITE].set(num);
01180 else
01181 s.effects.effected_mask[WHITE].reset(num);
01182 s.effects.effected_changed_mask[BLACK].set(num);
01183 s.effects.effected_changed_mask[WHITE].set(num);
01184 {
01185 BoardMask changed=s.changedEffects(BLACK)|s.changedEffects(WHITE);
01186 changed.set(from);
01187 changed.set(to);
01188 if(changed.anyInRange(Board_Mask_Table3x3.mask(s.getKingPosition<BLACK>()))
01189 || s.pin_or_open[BLACK]!=pin_or_open_backup[BLACK])
01190 s.makeKing8Info<BLACK>();
01191 if(changed.anyInRange(Board_Mask_Table3x3.mask(s.getKingPosition<WHITE>()))
01192 || s.pin_or_open[WHITE]!=pin_or_open_backup[WHITE])
01193 s.makeKing8Info<WHITE>();
01194 }
01195 }
01196
01197 template<osl::Player P>
01198 void osl::apply_move::ApplyDoUndoSimpleMove<P,osl::state::NumEffectState>::
01199 epilogue(state_t& s, Position from, Position to, Piece oldPiece,
01200 int num, PtypeO oldPtypeO, PtypeO newPtypeO,
01201 const CArray<PieceMask,2>& pin_or_open_backup,
01202 const KingMobility& king_mobility_backup,
01203 const PieceMask& promoted_backup,
01204 const CArray<PieceMask,2>& effected_mask_backup,
01205 const CArray<PieceMask,2>& effected_changed_mask_backup,
01206 const CArray<uint64_t,2>& king8infos_backup,
01207 const MobilityTable & mobility_backup
01208 )
01209 {
01210 s.setPieceOf(num,oldPiece);
01211 s.effects.template doEffect<NumBitmapEffect::Sub,false>(s,newPtypeO,to,num);
01212 s.setBoard(from,oldPiece);
01213 s.effects.effectedNumTable[num].clear();
01214 s.effects.template doBlockAt<NumBitmapEffect::Sub,false>(s,from,num);
01215 s.setBoard(to,Piece::EMPTY());
01216 s.effects.template doBlockAt<NumBitmapEffect::Add,false>(s,to,num);
01217 s.effects.template doEffect<NumBitmapEffect::Add,false>(s,oldPtypeO,from,num);
01218 s.effects.invalidateChangedEffects();
01219 s.pin_or_open = pin_or_open_backup;
01220 s.king_mobility = king_mobility_backup;
01221 s.promoted = promoted_backup;
01222 s.effects.effected_mask = effected_mask_backup;
01223 s.effects.effected_changed_mask = effected_changed_mask_backup;
01224 s.effects.mobilityTable = mobility_backup;
01225 s.king8infos = king8infos_backup;
01226 }
01227
01228 template<osl::Player P>
01229 void osl::apply_move::ApplyDoUndoDropMove<P,osl::state::NumEffectState>::
01230 prologue(state_t& s, Position to, Ptype ptype,
01231 Piece& oldPiece, int& num, PtypeO& ptypeO,
01232 int& numIndex, mask_t& numMask,
01233 CArray<PieceMask,2>& pin_or_open_backup,
01234 KingMobility& king_mobility_backup,
01235 CArray<PieceMask,2>& effected_mask_backup,
01236 CArray<PieceMask,2>& effected_changed_mask_backup,
01237 CArray<uint64_t,2>& king8infos_backup,
01238 MobilityTable &mobility_backup)
01239 {
01240 king8infos_backup = s.king8infos;
01241 mobility_backup = s.effects.mobilityTable;
01242 pin_or_open_backup = s.pin_or_open;
01243 king_mobility_backup = s.king_mobility;
01244 effected_mask_backup = s.effects.effected_mask;
01245 effected_changed_mask_backup = s.effects.effected_changed_mask;
01246 #if OSL_WORDSIZE == 64
01247 numIndex=0;
01248 #elif OSL_WORDSIZE == 32
01249 numIndex=Ptype_Table.getIndex(ptype);
01250 #endif
01251 const mask_t ownMochigoma=
01252 s.standMask(P).getMask(numIndex) & Ptype_Table.getMaskLow(ptype);
01253 assert(ownMochigoma.any());
01254 numMask=ownMochigoma.lowestBit();
01255 int numLow = ownMochigoma.bsf();
01256 num = numLow|(numIndex<<5);
01257 oldPiece=s.getPieceOf(num);
01258 Piece newPiece=oldPiece;
01259 newPiece+=to-Position::STAND();
01260 ptypeO=newPiece.ptypeO();
01261 s.setPieceOf(num,newPiece);
01262 s.effects.clearChangedEffects();
01263 s.effects.clearEffectedChanged();
01264 s.effects.template doBlockAt<NumBitmapEffect::Sub,true>(s,to,num);
01265 s.effects.template doEffect<NumBitmapEffect::Add,true>(s,ptypeO,to,num);
01266 s.setBoard(to,newPiece);
01267 s.standMask(P).xorMask(numIndex,numMask);
01268 s.stand_count[P][ptype-PTYPE_BASIC_MIN]--;
01269 s.mutableOnBoardMask(P).xorMask(numIndex,numMask);
01270 {
01271 Direction lastD=UL;
01272 s.recalcPinOpen(to,lastD,P);
01273 }
01274 {
01275 Direction lastD=UL;
01276 s.recalcPinOpen(to,lastD,alt(P));
01277 }
01278 if(s.hasEffectBy(BLACK,to))
01279 s.effects.effected_mask[BLACK].set(num);
01280 else
01281 s.effects.effected_mask[BLACK].reset(num);
01282 if(s.hasEffectBy(WHITE,to))
01283 s.effects.effected_mask[WHITE].set(num);
01284 else
01285 s.effects.effected_mask[WHITE].reset(num);
01286 s.effects.effected_changed_mask[BLACK].set(num);
01287 s.effects.effected_changed_mask[WHITE].set(num);
01288 {
01289 BoardMask changed=s.changedEffects(BLACK)|s.changedEffects(WHITE);
01290 changed.set(to);
01291 if(changed.anyInRange(Board_Mask_Table3x3.mask(s.getKingPosition<BLACK>()))
01292 || s.pin_or_open[BLACK]!=pin_or_open_backup[BLACK])
01293 s.makeKing8Info<BLACK>();
01294 if(changed.anyInRange(Board_Mask_Table3x3.mask(s.getKingPosition<WHITE>()))
01295 || s.pin_or_open[WHITE]!=pin_or_open_backup[WHITE])
01296 s.makeKing8Info<WHITE>();
01297 }
01298 }
01299
01300 template<osl::Player P>
01301 void osl::apply_move::ApplyDoUndoDropMove<P,osl::state::NumEffectState>::
01302 epilogue(state_t& s, Position to, Ptype ptype, Piece oldPiece,
01303 int num, PtypeO ptypeO, int numIndex, mask_t numMask,
01304 const CArray<PieceMask,2>& pin_or_open_backup,
01305 const KingMobility& king_mobility_backup,
01306 const CArray<PieceMask,2>& effected_mask_backup,
01307 const CArray<PieceMask,2>& effected_changed_mask_backup,
01308 const CArray<uint64_t,2>& king8infos_backup,
01309 const MobilityTable& mobility_backup
01310 )
01311 {
01312 s.standMask(P).xorMask(numIndex,numMask);
01313 s.stand_count[P][ptype-PTYPE_BASIC_MIN]++;
01314 s.mutableOnBoardMask(P).xorMask(numIndex,numMask);
01315 s.setBoard(to,Piece::EMPTY());
01316 s.effects.template doEffect<NumBitmapEffect::Sub,false>(s,ptypeO,to,num);
01317 s.effects.template doBlockAt<NumBitmapEffect::Add,false>(s,to,num);
01318 s.setPieceOf(num,oldPiece);
01319 s.effects.effectedNumTable[num].clear();
01320 s.effects.invalidateChangedEffects();
01321 s.pin_or_open = pin_or_open_backup;
01322 s.king_mobility = king_mobility_backup;
01323 s.effects.effected_mask = effected_mask_backup;
01324 s.effects.effected_changed_mask = effected_changed_mask_backup;
01325 s.effects.mobilityTable = mobility_backup;
01326 s.king8infos = king8infos_backup;
01327 }
01328
01329 template<osl::Player P>
01330 void osl::apply_move::ApplyDoUndoCaptureMove<P,osl::state::NumEffectState>::
01331 prologue(state_t& s, Position from, Position to, Piece target,
01332 int promoteMask,
01333 Piece& oldPiece, PtypeO& oldPtypeO, PtypeO& capturePtypeO,
01334 PtypeO& new_ptypeo, int& num0, int& num1,
01335 int& num1Index, mask_t& num1Mask,
01336 CArray<PieceMask,2>& pin_or_open_backup,
01337 KingMobility& king_mobility_backup,
01338 PieceMask& promoted_backup,
01339 CArray<PieceMask,2>& effected_mask_backup,
01340 CArray<PieceMask,2>& effected_changed_mask_backup,
01341 CArray<uint64_t,2>& king8infos_backup,
01342 MobilityTable &mobility_backup)
01343 {
01344 mobility_backup = s.effects.mobilityTable;
01345 pin_or_open_backup = s.pin_or_open;
01346 king_mobility_backup = s.king_mobility;
01347 effected_mask_backup = s.effects.effected_mask;
01348 effected_changed_mask_backup = s.effects.effected_changed_mask;
01349 king8infos_backup = s.king8infos;
01350
01351 num1=target.number();
01352 num1Index=PieceMask::numToIndex(num1);
01353 num1Mask=PieceMask::numToMask(num1);
01354 s.mutableOnBoardMask(PlayerTraits<P>::opponent).xorMask(num1Index,num1Mask);
01355 s.standMask(P).xorMask(num1Index,num1Mask);
01356 oldPiece=s.getPieceAt(from);
01357 Piece newPiece=oldPiece.promoteWithMask(promoteMask);
01358 newPiece+=(to-from);
01359 num0=oldPiece.number();
01360 s.setPieceOf(num0,newPiece);
01361 s.setPieceOf(num1,target.captured());
01362
01363 oldPtypeO=oldPiece.ptypeO();
01364 new_ptypeo=newPiece.ptypeO();
01365 capturePtypeO=target.ptypeO();
01366 s.stand_count[P][unpromote(getPtype(capturePtypeO))-PTYPE_BASIC_MIN]++;
01367 s.effects.clearChangedEffects();
01368 s.effects.clearEffectedChanged();
01369 s.effects.setChangedPieces(s.getEffect(to));
01370 s.effects.template doEffect<NumBitmapEffect::Sub,true>(s,capturePtypeO,to,num1);
01371 s.effects.template doEffect<NumBitmapEffect::Sub,true>(s,oldPtypeO,from,num0);
01372 s.setBoard(from,Piece::EMPTY());
01373 s.effects.template doBlockAt<NumBitmapEffect::Add,true>(s,from,num0);
01374 s.effects.effectedNumTable[num0]=s.effects.effectedNumTable[num1];
01375 s.effects.effectedNumTable[num1].clear();
01376 s.setBoard(to,newPiece);
01377 s.effects.template doEffect<NumBitmapEffect::Add,true>(s,new_ptypeo,to,num0);
01378
01379 if (oldPtypeO == newPtypeO(P,KING))
01380 s.makePinOpen(P);
01381 else {
01382 Direction lastD=UL;
01383 s.pin_or_open[P].reset(num0);
01384 s.pin_or_open[P].reset(num1);
01385 s.recalcPinOpen(from,lastD,P);
01386 s.recalcPinOpen(to,lastD,P);
01387 }
01388 {
01389 Direction lastD=UL;
01390 s.pin_or_open[alt(P)].reset(num0);
01391 s.pin_or_open[alt(P)].reset(num1);
01392 s.recalcPinOpen(from,lastD,alt(P));
01393 s.recalcPinOpen(to,lastD,alt(P));
01394 }
01395 promoted_backup = s.promoted;
01396 s.promoted.reset(num1);
01397 s.effects.effected_mask[BLACK].reset(num1);
01398 s.effects.effected_mask[WHITE].reset(num1);
01399 if (promoteMask)
01400 s.promoted.set(num0);
01401 if(s.hasEffectBy(BLACK,to))
01402 s.effects.effected_mask[BLACK].set(num0);
01403 else
01404 s.effects.effected_mask[BLACK].reset(num0);
01405 if(s.hasEffectBy(WHITE,to))
01406 s.effects.effected_mask[WHITE].set(num0);
01407 else
01408 s.effects.effected_mask[WHITE].reset(num0);
01409 s.effects.effected_changed_mask[BLACK].set(num0);
01410 s.effects.effected_changed_mask[WHITE].set(num0);
01411 {
01412 BoardMask changed=s.changedEffects(BLACK)|s.changedEffects(WHITE);
01413 changed.set(from);
01414 changed.set(to);
01415 if(changed.anyInRange(Board_Mask_Table3x3.mask(s.getKingPosition<BLACK>()))
01416 || s.pin_or_open[BLACK]!=pin_or_open_backup[BLACK])
01417 s.makeKing8Info<BLACK>();
01418 if(changed.anyInRange(Board_Mask_Table3x3.mask(s.getKingPosition<WHITE>()))
01419 || s.pin_or_open[WHITE]!=pin_or_open_backup[WHITE])
01420 s.makeKing8Info<WHITE>();
01421 }
01422 }
01423
01424 template<osl::Player P>
01425 void osl::apply_move::ApplyDoUndoCaptureMove<P,osl::state::NumEffectState>::
01426 epilogue(state_t& s, Position from, Position to, Piece target,
01427 Piece oldPiece, PtypeO oldPtypeO, PtypeO capturePtypeO,
01428 PtypeO newPtypeO, int num0, int num1,
01429 int num1Index, mask_t num1Mask,
01430 const CArray<PieceMask,2>& pin_or_open_backup,
01431 const KingMobility& king_mobility_backup,
01432 const PieceMask& promoted_backup,
01433 const CArray<PieceMask,2>& effected_mask_backup,
01434 const CArray<PieceMask,2>& effected_changed_mask_backup,
01435 const CArray<uint64_t,2>& king8infos_backup,
01436 const MobilityTable &mobility_backup
01437 )
01438 {
01439 s.standMask(P).xorMask(num1Index,num1Mask);
01440 s.stand_count[P][unpromote(getPtype(capturePtypeO))-PTYPE_BASIC_MIN]--;
01441 s.mutableOnBoardMask(PlayerTraits<P>::opponent).xorMask(num1Index,num1Mask);
01442 s.effects.effectedNumTable[num1]=s.effects.effectedNumTable[num0];
01443 s.effects.effectedNumTable[num0].clear();
01444 s.setPieceOf(num0,oldPiece);
01445 s.setPieceOf(num1,target);
01446 s.effects.template doEffect<NumBitmapEffect::Sub,false>(s,newPtypeO,to,num0);
01447 s.setBoard(from,oldPiece);
01448 s.setBoard(to,target);
01449 s.effects.template doBlockAt<NumBitmapEffect::Sub,false>(s,from,num0);
01450 s.effects.template doEffect<NumBitmapEffect::Add,false>(s,capturePtypeO,to,num1);
01451 s.effects.template doEffect<NumBitmapEffect::Add,false>(s,oldPtypeO,from,num0);
01452 s.effects.invalidateChangedEffects();
01453 s.pin_or_open = pin_or_open_backup;
01454 s.king_mobility = king_mobility_backup;
01455 s.promoted = promoted_backup;
01456 s.effects.effected_mask = effected_mask_backup;
01457 s.effects.effected_changed_mask = effected_changed_mask_backup;
01458 s.effects.mobilityTable = mobility_backup;
01459 s.king8infos = king8infos_backup;
01460 }
01461
01462 #endif
01463
01464
01465
01466