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/align16New.h"
00009 #include <boost/cstdint.hpp>
00010
00011 namespace osl
00012 {
00013 namespace checkmate
00014 {
00015 class King8Info;
00016 }
00017 namespace state
00018 {
00019 class NumEffectState;
00025 bool operator==(const NumEffectState& st1, const NumEffectState& st2);
00026
00032 class NumEffectState : public SimpleState
00033 #if OSL_WORDSIZE == 32
00034 , public misc::Align16New
00035 #endif
00036 {
00037 effect::NumSimpleEffectTable effects;
00038 CArray<PieceMask,2> pieces_onboard;
00040 PieceMask promoted;
00041 CArray<PieceMask,2> pin_or_open;
00042 KingMobility king_mobility;
00043 CArray<uint64_t,2> king8infos;
00044
00045 friend bool operator==(const NumEffectState& st1,const NumEffectState& st2);
00046 typedef NumEffectState state_t;
00047 public:
00048
00049
00050
00051 explicit NumEffectState(const state::SimpleState& st=SimpleState(HIRATE));
00052 ~NumEffectState();
00054 void copyFrom(const NumEffectState& src);
00055 void copyFrom(const SimpleState& src);
00056 bool isConsistent(bool showError=true) const;
00058 bool isConsistent(const NumEffectState& prev, Move moved, bool show_error=true) const;
00059 void showEffect(std::ostream& os) const;
00060
00061
00062
00063
00064
00065 const PieceMask& piecesOnBoard(Player p) const { return pieces_onboard[p]; }
00066 const PieceMask promotedPieces() const { return promoted; }
00067 const PieceMask pin(Player king) const
00068 {
00069 return pin_or_open[king]&piecesOnBoard(king);
00070 }
00071 PieceMask pinOrOpen(Player king) const
00072 {
00073 return pin_or_open[king];
00074 }
00075 uint64_t Iking8Info(Player king) const
00076 {
00077 return king8infos[king];
00078 }
00079 const checkmate::King8Info
00080 #ifdef __GNUC__
00081 __attribute__ ((pure))
00082 #endif
00083 king8Info(Player king) const;
00085 bool inCheck(Player P) const
00086 {
00087 const Square king = kingSquare(P);
00088 #ifdef ALLOW_KING_ABSENCE
00089 if (king.isPieceStand())
00090 return false;
00091 #endif
00092 return hasEffectAt(alt(P), king);
00093 }
00095 bool inCheck() const { return inCheck(turn()); }
00096 const EffectedNumTable& longEffectNumTable() const
00097 {
00098 return effects.effectedNumTable;
00099 }
00100
00102 const PieceMask effectedMask(Player pl) const
00103 {
00104 return effects.effected_mask[pl];
00105 }
00109 const PieceMask effectedChanged(Player pl) const
00110 {
00111 return effects.effected_changed_mask[pl];
00112 }
00113 bool hasChangedEffects() const {
00114 return ! effects.changedEffects(BLACK).isInvalid();
00115 }
00116 const BoardMask changedEffects(Player pl) const{
00117 assert(hasChangedEffects());
00118 return effects.changedEffects(pl);
00119 }
00120 const BoardMask changedEffects() const{
00121 BoardMask ret = changedEffects(BLACK);
00122 return ret |= changedEffects(WHITE);
00123 }
00124 const NumBitmapEffect changedPieces() const{
00125 return effects.changedPieces();
00126 }
00127 template <Ptype PTYPE> bool longEffectChanged() const
00128 {
00129 return changedPieces().template hasLong<PTYPE>();
00130 }
00131 template <Ptype PTYPE> bool anyEffectChanged() const
00132 {
00133 return changedPieces().template hasAny<PTYPE>();
00134 }
00135
00137 const Piece findThreatenedPiece(Player P) const;
00138
00139
00140
00141
00142 bool isOnBoardNum(int num) const
00143 {
00144 return piecesOnBoard(BLACK).test(num) || piecesOnBoard(WHITE).test(num);
00145 }
00146
00147 Square mobilityOf(Direction d,int num) const
00148 {
00149 return effects.mobilityTable.get(d,num);
00150 }
00151 Square mobilityOf(Direction d, Piece p) const
00152 {
00153 return mobilityOf(d, p.number());
00154 }
00155 Square kingMobilityAbs(Player p, Direction d) const
00156 {
00157 return Square::makeDirect(king_mobility[p][d]);
00158 }
00164 Square kingMobilityOfPlayer(Player p, Direction d) const
00165 {
00166 if (p == BLACK)
00167 d = inverse(d);
00168 return kingMobilityAbs(p, d);
00169 }
00174 template<Player P>
00175 Direction pinnedDir(Piece p) const
00176 {
00177 assert(p.owner() == P);
00178 assert(pinOrOpen(P).test(p.number()));
00179 Square king=kingSquare<P>();
00180 return Board_Table.getShort8<P>(p.square(),king);
00181 }
00182 Direction pinnedDir(Piece p) const
00183 {
00184 if (p.owner() == BLACK)
00185 return pinnedDir<BLACK>(p);
00186 else
00187 return pinnedDir<WHITE>(p);
00188 }
00193 template<Player P>
00194 bool pinnedCanMoveTo(Piece p,Square to) const
00195 {
00196 assert(p.owner() == P);
00197 Direction d=pinnedDir<P>(p);
00198 Square from=p.square();
00199 assert(hasEffectIf(p.ptypeO(),from,to));
00200 return primDir(d)==primDirUnsafe(Board_Table.getShort8Unsafe<P>(from,to));
00201 }
00202 bool pinnedCanMoveTo(Piece p,Square to) const
00203 {
00204 if (p.owner() == BLACK)
00205 return pinnedCanMoveTo<BLACK>(p, to);
00206 else
00207 return pinnedCanMoveTo<WHITE>(p, to);
00208 }
00209
00210
00211
00212 const NumBitmapEffect effectSetAt(Square sq) const
00213 {
00214 return effects.effectSetAt(sq);
00215 }
00220 int countEffect(Player player,Square target) const
00221 {
00222 assert(target.isOnBoard());
00223 return effectSetAt(target).countEffect(player);
00224 }
00230 int
00231 #ifdef __GNUC__
00232 __attribute__ ((pure))
00233 #endif
00234 countEffect(Player player,Square target, PieceMask pins) const
00235 {
00236 assert(target.isOnBoard());
00237 const NumBitmapEffect effect = effectSetAt(target);
00238 const int all = effect.countEffect(player);
00239 pins &= effect;
00240 return all - pins.countBit();
00241 }
00242
00243
00244
00245
00246 template <Ptype PTYPE>
00247 const mask_t allEffectAt(Player P, Square target) const
00248 {
00249 return effectSetAt(target).template selectBit<PTYPE>() & piecesOnBoard(P).template getMask<PTYPE>();
00250 }
00251 const mask_t allEffectAt(Player P, Ptype ptype, Square target) const;
00252 template <Ptype PTYPE> const mask_t longEffectAt(Square target) const
00253 {
00254 return effectSetAt(target).selectLong<PTYPE>() >> 8;
00255 }
00256 template <Ptype PTYPE> const mask_t longEffectAt(Square target, Player owner) const
00257 {
00258 return longEffectAt<PTYPE>(target) & piecesOnBoard(owner).getMask(1);
00259 }
00260 const mask_t longEffectAt(Square target) const
00261 {
00262 return effectSetAt(target).selectLong() >> 8;
00263 }
00264 const mask_t longEffectAt(Square target, Player owner) const
00265 {
00266 return longEffectAt(target) & piecesOnBoard(owner).getMask(1);
00267 }
00268
00269
00270
00271
00277 template<Player P>
00278 bool hasEffectAt(Square target) const {
00279 assert(target.isOnBoard());
00280 mask_t mask=effectSetAt(target).getMask(1);
00281 mask&=NumBitmapEffect::playerEffectMask<P>();
00282 return !mask.none();
00283 }
00289 bool hasEffectAt(Player player,Square target) const {
00290 assert(target.isOnBoard());
00291 mask_t mask=effectSetAt(target).getMask(1);
00292 mask&=NumBitmapEffect::playerEffectMask(player);
00293 return !mask.none();
00294 }
00295
00299 template <Ptype PTYPE>
00300 bool hasLongEffectAt(Player P, Square to) const {
00301 BOOST_STATIC_ASSERT( (PTYPE == LANCE || PTYPE == BISHOP || PTYPE == ROOK) );
00302 return longEffectAt<PTYPE>(to, P).any();
00303 }
00304
00308 template <Ptype PTYPE>
00309 bool hasEffectByPtype(Player attack, Square target) const
00310 {
00311 return allEffectAt<PTYPE>(attack, target).any();
00312 }
00316 template <Ptype PTYPE>
00317 bool hasEffectByPtypeStrict(Player attack, Square target) const
00318 {
00319 mask_t mask=allEffectAt<PTYPE>(attack, target);
00320 if (isPromoted(PTYPE))
00321 mask &= promoted.getMask<PTYPE>();
00322 else
00323 mask &= ~(promoted.getMask<PTYPE>());
00324 return mask.any();
00325 }
00330 template<Direction Dir,Player P>
00331 bool hasEffectInDirection(Square to) const {
00332 BOOST_STATIC_ASSERT( (DirectionTraits<Dir>::isLong) );
00333 const PieceMask& pieces_onboard=piecesOnBoard(P);
00334 mask_t mask1=pieces_onboard.getMask(1);
00335 mask1 &= ((PtypeDirectionTraits<LANCE,Dir>::canMove
00336 ? mask_t::makeDirect(PtypeFuns<LANCE>::indexMask)
00337 : mask_t::makeDirect(0))
00338 | (PtypeDirectionTraits<BISHOP,Dir>::canMove
00339 ? mask_t::makeDirect(PtypeFuns<BISHOP>::indexMask)
00340 : mask_t::makeDirect(0))
00341 | (PtypeDirectionTraits<ROOK,Dir>::canMove
00342 ? mask_t::makeDirect(PtypeFuns<ROOK>::indexMask)
00343 : mask_t::makeDirect(0)));
00344 mask1 <<= 8;
00345
00346 mask1&=effectSetAt(to).getMask(1)& NumBitmapEffect::longEffectMask();
00347 while (mask1.any())
00348 {
00349 int num=mask1.takeOneBit()+NumBitmapEffect::longToNumOffset;
00350 Square from = pieceOf(num).square();
00351 Direction dir=Board_Table.getLongDirection<BLACK>(Offset32(to,from));
00352 if (dir==DirectionPlayerTraits<Dir,P>::directionByBlack)
00353 return true;
00354 }
00355 return false;
00356 }
00363 bool hasEffectNotBy(Player player,Piece piece,Square target) const {
00364 assert(piece.owner()==player);
00365 PieceMask pieces_onboard=piecesOnBoard(player);
00366 int num=piece.number();
00367 pieces_onboard.reset(num);
00368 return (pieces_onboard&effectSetAt(target)).any();
00369 }
00373 bool hasEffectByNotPinnedAndKing(Player pl,Square target) const{
00374 assert(target.isOnBoard());
00375 PieceMask m=piecesOnBoard(pl)& ~pinOrOpen(pl) & effectSetAt(target);
00376 m.clearBit<KING>();
00377 return m.any();
00378 }
00382 bool hasEffectByNotPinned(Player pl,Square target) const{
00383 assert(target.isOnBoard());
00384 PieceMask m=piecesOnBoard(pl)& ~pinOrOpen(pl) & effectSetAt(target);
00385 return m.any();
00386 }
00393 bool hasMultipleEffectAt(Player player,Square target) const
00394 {
00395 mask_t mask=effectSetAt(target).getMask(1);
00396 mask&=NumBitmapEffect::playerEffectMask(player);
00397 return NumBitmapEffect::playerEffect(player).getMask(1) < mask;
00398 }
00399
00404 bool hasEffectByPiece(Piece attack, Square target) const
00405 {
00406 assert(attack.isPiece());
00407 assert(target.isOnBoard());
00408 return effectSetAt(target).test(attack.number());
00409 }
00410
00411
00419 bool hasEffectIf(PtypeO ptypeo,Square attacker,
00420 Square target) const
00421 #ifdef __GNUC__
00422 __attribute__ ((pure))
00423 #endif
00424 {
00425 Offset32 offset32=Offset32(target,attacker);
00426 EffectContent effect=Ptype_Table.getEffect(ptypeo,offset32);
00427 if (! effect.hasEffect())
00428 return false;
00429 if (effect.hasUnblockableEffect())
00430 return true;
00431 assert(Board_Table.getShortOffset(offset32) == effect.offset());
00432 return this->isEmptyBetween(attacker,target,effect.offset());
00433 }
00437 template<Player P>
00438 bool
00439 #ifdef __GNUC__
00440 __attribute__ ((pure))
00441 #endif
00442 hasEffectByWithRemove(Square target,Square removed) const;
00443
00444 bool hasEffectByWithRemove(Player player, Square target,Square removed) const{
00445 if (player==BLACK)
00446 return hasEffectByWithRemove<BLACK>(target,removed);
00447 else
00448 return hasEffectByWithRemove<WHITE>(target,removed);
00449 }
00450
00451
00452
00453
00454
00456 template <Ptype PTYPE>
00457 const Piece findAttackAt(Player attack, Square target) const
00458 {
00459 mask_t mask=allEffectAt<PTYPE>(attack, target);
00460 if (mask.none())
00461 return Piece::EMPTY();
00462 return pieceOf(mask.takeOneBit()+PtypeFuns<PTYPE>::indexNum*32);
00463 }
00464 template <Ptype PTYPE>
00465 const Piece findAttackAtStrict(Player attack, Square target) const
00466 {
00467 mask_t mask=allEffectAt<PTYPE>(attack, target);
00468 if (isPromoted(PTYPE))
00469 mask &= promoted.getMask<PTYPE>();
00470 else
00471 mask &= ~(promoted.getMask<PTYPE>());
00472 if (mask.none())
00473 return Piece::EMPTY();
00474 return pieceOf(mask.takeOneBit()+PtypeFuns<PTYPE>::indexNum*32);
00475 }
00480 const Piece findLongAttackAt(Player owner, int piece, Direction d) const
00481 {
00482 assert(pieceOf(piece).isOnBoardByOwner(owner));
00483 if (owner == BLACK)
00484 d = inverse(d);
00485 const int num = effects.effectedNumTable[piece][d];
00486 if (num == EMPTY_NUM)
00487 return Piece::EMPTY();
00488 return pieceOf(num);
00489 }
00490 const Piece findLongAttackAt(Player owner, Piece piece, Direction d) const
00491 {
00492 assert(piece.isPiece());
00493 assert(piece.owner() == owner);
00494 return findLongAttackAt(owner, piece.number(), d);
00495 }
00496 const Piece findLongAttackAt(Piece piece, Direction d) const
00497 {
00498 assert(piece.isPiece());
00499 return findLongAttackAt(piece.owner(), piece, d);
00500 }
00501 const Piece findLongAttackAt(Square square, Direction d) const
00502 {
00503 return findLongAttackAt(pieceOnBoard(square), d);
00504 }
00508 const Piece selectCheapPiece(PieceMask effect) const;
00514 const Piece findCheapAttack(Player P, Square square) const
00515 {
00516 return selectCheapPiece(piecesOnBoard(P) & effectSetAt(square));
00517 }
00523 const Piece findCheapAttackNotBy(Player P, Square square, const PieceMask& ignore) const
00524 {
00525 PieceMask pieces = piecesOnBoard(P);
00526 pieces &= ~ignore;
00527 return selectCheapPiece(pieces & effectSetAt(square));
00528 }
00529 const Piece findAttackNotBy(Player P, Square square, const PieceMask& ignore) const
00530 {
00531 PieceMask pieces = piecesOnBoard(P);
00532 pieces &= ~ignore;
00533 pieces &= effectSetAt(square);
00534 if (pieces.none())
00535 return Piece::EMPTY();
00536 return pieceOf(pieces.takeOneBit());
00537 }
00546 template<Player P>
00547 bool findCheckPiece(Piece& attack_piece) const
00548 {
00549 return hasEffectAt<PlayerTraits<P>::opponent>(kingSquare(P),attack_piece);
00550 }
00551 bool hasEffectAt(Player P, Square target,Piece& attackerPiece) const
00552 {
00553 if (P == BLACK)
00554 return hasEffectAt<BLACK>(target, attackerPiece);
00555 else
00556 return hasEffectAt<WHITE>(target, attackerPiece);
00557 }
00564 template<Player P>
00565 bool hasEffectAt(Square target,Piece& attackerPiece) const {
00566 attackerPiece=Piece::EMPTY();
00567 const PieceMask& pieceMask=piecesOnBoard(P)&effectSetAt(target);
00568 #if OSL_WORDSIZE == 64
00569 mask_t mask=pieceMask.getMask(0);
00570 if (mask.none()) return false;
00575 if (mask.hasMultipleBit())
00576 return true;
00577 int num=mask.bsf();
00578 attackerPiece=pieceOf(num);
00579 return true;
00580 #elif OSL_WORDSIZE == 32
00581 mask_t mask0=pieceMask.getMask(0);
00582 mask_t mask1=pieceMask.getMask(1);
00583 if (mask0.any())
00584 {
00585 if (mask1.any())
00586 return true;
00587 int num=mask0.bsf();
00588 if (mask0 == PieceMask::numToMask(num))
00589 attackerPiece=pieceOf(num);
00590 return true;
00591 }
00592 else if (mask1.any())
00593 {
00594 int num=mask1.bsf();
00595 if (mask1==PieceMask::numToMask(num))
00596 attackerPiece=pieceOf(num+32);
00597 return true;
00598 }
00599 else
00600 return false;
00601 #endif
00602 }
00603
00604
00605
00606
00617 template <bool show_error>
00618 bool isAlmostValidMove(Move move) const;
00619 bool isAlmostValidMove(Move move,bool show_error=true) const;
00620 void makeMove(Move move);
00621 void makeMovePass()
00622 {
00623 changeTurn();
00624 effects.clearChangedEffects();
00625 effects.clearEffectedChanged();
00626 }
00627
00628 template <class Function>
00629 void makeUnmakePass(Function &f)
00630 {
00631 changeTurn();
00632 f(Square::STAND());
00633 changeTurn();
00634 }
00635 template <class Function>
00636 void makeUnmakeMove(Move move, Function &f)
00637 {
00638 if (move.player() == BLACK)
00639 makeUnmakeMove(Player2Type<BLACK>(), move, f);
00640 else
00641 makeUnmakeMove(Player2Type<WHITE>(), move, f);
00642 }
00643 template <Player P, class Function>
00644 void makeUnmakeMove(Player2Type<P> player, Move move, Function &f)
00645 {
00646 if (move.isPass())
00647 return makeUnmakePass(f);
00648 assert(move.isValid());
00649 assert(isAlmostValidMove(move));
00650 assert(P == move.player());
00651 assert(P == turn());
00652 Square from=move.from();
00653 Square to=move.to();
00654 if (from.isPieceStand())
00655 {
00656 assert(pieceAt(to) == Piece::EMPTY());
00657 doUndoDropMove(player,to,move.ptype(),f);
00658 }
00659 else
00660 {
00661 assert(pieceAt(from) != Piece::EMPTY());
00662 Piece captured=pieceAt(to);
00663 if (captured != Piece::EMPTY())
00664 {
00665 doUndoCaptureMove(player,from,to,captured,move.promoteMask(),f);
00666 }
00667 else
00668 {
00669 doUndoSimpleMove(player,from,to,move.promoteMask(),f);
00670 }
00671 }
00672 }
00673 bool wasCheckEvasion(Move last_move) const;
00674
00675
00676
00679 template<Player P,Ptype T,typename F>
00680 void forEachOnBoard(F& func) const {
00681 mask_t onMask=piecesOnBoard(P).template selectBit<T>() ;
00682 while (onMask.any())
00683 {
00684 int num=onMask.takeOneBit()+((PtypeFuns<T>::indexNum)<<5);
00685 Piece p = pieceOf(num);
00686 func(p);
00687 }
00688 }
00691 template<Player P,Ptype T,typename F>
00692 void forEachOnBoardPtypeStrict(F& func) const
00693 {
00694 mask_t mask=piecesOnBoard(P).template selectBit<T>() ;
00695 if (isPromoted(T))
00696 mask &= promoted.getMask<T>();
00697 else
00698 mask &= ~(promoted.getMask<T>());
00699 while (mask.any())
00700 {
00701 int num=mask.takeOneBit()+((PtypeFuns<T>::indexNum)<<5);
00702 func(pieceOf(num));
00703 }
00704 }
00705 private:
00706 template<Player P,class Action>
00707 void forEachEffect(const PieceMask& pieces, Square sq,Action & action) const
00708 {
00709 #if OSL_WORDSIZE == 64
00710 mask_t mask=pieces.getMask(0);
00711 while (mask.any())
00712 {
00713 const int num=mask.takeOneBit();
00714 action.template doAction<P>(pieceOf(num),sq);
00715 }
00716 #elif OSL_WORDSIZE == 32
00717 mask_t mask0=pieces.getMask(0);
00718 while (mask0.any())
00719 {
00720 const int num=mask0.takeOneBit();
00721 action.template doAction<P>(pieceOf(num),sq);
00722 }
00723 mask_t mask1=pieces.getMask(1);
00724 while (mask1.any())
00725 {
00726 const int num=mask1.takeOneBit()+32;
00727 action.template doAction<P>(pieceOf(num),sq);
00728 }
00729 #endif
00730 }
00731 public:
00736 template<Player P,class Action>
00737 void forEachEffect(Square sq,Action & action) const
00738 {
00739 const PieceMask pieceMask=piecesOnBoard(P)&effectSetAt(sq);
00740 forEachEffect<P,Action>(pieceMask, sq, action);
00741 }
00747 template<Player P,class Action>
00748 void forEachEffect(Square sq,Action & action,const PieceMask& pin) const
00749 {
00750 PieceMask pieceMask=piecesOnBoard(P)&effectSetAt(sq);
00751 pieceMask &= ~pin;
00752 forEachEffect<P,Action>(pieceMask, sq, action);
00753 }
00754
00760 template<Player P,class Action>
00761 void forEachEffectNotBy(Square sq,Piece piece,Action & action) const {
00762 PieceMask pieces=piecesOnBoard(P)&effectSetAt(sq);
00763 pieces.reset(piece.number());
00764 forEachEffect<P,Action>(pieces, sq, action);
00765 }
00766
00767 private:
00768 template<Player P,Ptype Type,class Action,Direction Dir>
00769 void forEachEffectOfPieceDir(Square, Action&, Int2Type<false>) const {}
00770 template<Player P,Ptype Type,class Action,Direction Dir>
00771 void forEachEffectOfPieceDir(Square pieceSquare,Action & action,Int2Type<true>) const {
00772 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00773 action.template doAction<P>(this->pieceAt(pieceSquare),pieceSquare+offset);
00774 }
00775
00776 template<Player P,Ptype Type,class Action,Direction Dir>
00777 void forEachEffectOfPieceDir(Square pieceSquare,Action & action) const {
00778 forEachEffectOfPieceDir<P,Type,Action,Dir>(pieceSquare,action,Int2Type<(PtypeTraits<Type>::moveMask & DirectionTraits<Dir>::mask)!=0>());
00779 }
00780 template<Player P,Ptype Type,class Action,Direction Dir>
00781 void forEachEffectOfPieceLongDir(Square, Action&, Int2Type<false>) const {}
00782 template<Player P,Ptype Type,class Action,Direction Dir>
00783 void forEachEffectOfPieceLongDir(Square pieceSquare,Action & action,Int2Type<true>) const {
00784 Piece piece=this->pieceAt(pieceSquare);
00785 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00786 assert(offset.intValue() != 35);
00787 Square sq=pieceSquare+offset;
00788 for (;this->pieceAt(sq).isEmpty();sq+=offset)
00789 action.template doAction<P>(piece,sq);
00790 action.template doAction<P>(piece,sq);
00791 }
00792
00793 template<Player P,Ptype Type,class Action,Direction Dir>
00794 void forEachEffectOfPieceLongDir(Square pieceSquare,Action & action) const {
00795 forEachEffectOfPieceLongDir<P,Type,Action,Dir>(pieceSquare,action,Int2Type<(PtypeTraits<Type>::moveMask & DirectionTraits<Dir>::mask)!=0>());
00796 }
00797 public:
00805 template<Player P,Ptype Type,class Action>
00806 void forEachEffectOfPiece(Square pieceSquare,Action & action) const;
00807 template<class Action>
00808 void forEachEffectOfPiece(Piece piece,Action & action) const;
00809
00810
00811 private:
00812 void doSimpleMove(Square from, Square to, int promoteMask);
00813 void doDropMove(Square to,Ptype ptype);
00814 void doCaptureMove(Square from, Square to, Piece target,int promoteMask);
00815
00816 template <Player P, class Function>
00817 void doUndoSimpleMove(Player2Type<P> player,
00818 Square from, Square to, int promoteMask,Function& func);
00819 template <Player P>
00820 void prologueSimple(Player2Type<P>, Square from, Square to, int promoteMask,
00821 Piece& oldPiece, int& num,
00822 PtypeO& oldPtypeO, PtypeO& new_ptypeo,
00823 CArray<PieceMask,2>& pin_or_open_backup,
00824 KingMobility& king_mobility_backup,
00825 PieceMask& promoted_backup,
00826 CArray<PieceMask,2>& effected_mask_backup,
00827 CArray<PieceMask,2>& effected_changed_mask_backup,
00828 CArray<uint64_t,2>& king8infos_backup,
00829 MobilityTable &mobility_backup
00830 );
00831 void epilogueSimple(Square from, Square to, Piece oldPiece,
00832 int num, PtypeO oldPtypeO, PtypeO newPtypeO,
00833 const CArray<PieceMask,2>& pin_or_open_backup,
00834 const KingMobility& king_mobility_backup,
00835 const PieceMask& promoted_backup,
00836 const CArray<PieceMask,2>& effected_mask_backup,
00837 const CArray<PieceMask,2>& effected_changed_mask_backup,
00838 const CArray<uint64_t,2>& king8infos_backup,
00839 const MobilityTable &mobility_backup
00840 );
00841 template <Player P, class Function>
00842 void doUndoDropMove(Player2Type<P> player,
00843 Square to, Ptype ptype, Function& func);
00844 template <Player P>
00845 void prologueDrop(Player2Type<P>, Square to, Ptype ptype,
00846 Piece& oldPiece, int& num, PtypeO& ptypeO,
00847 int& numIndex, mask_t& numMask,
00848 CArray<PieceMask,2>& pin_or_open_backup,
00849 KingMobility& king_mobility_backup,
00850 CArray<PieceMask,2>& effected_mask_backup,
00851 CArray<PieceMask,2>& effected_changed_mask_backup,
00852 CArray<uint64_t,2>& king8infos_backup,
00853 MobilityTable &mobility_backup);
00854 template<Player P>
00855 void epilogueDrop(Player2Type<P>, Square to, Ptype ptype, Piece oldPiece,
00856 int num, PtypeO ptypeO, int numIndex, mask_t numMask,
00857 const CArray<PieceMask,2>& pin_or_open_backup,
00858 const KingMobility& king_mobility_backup,
00859 const CArray<PieceMask,2>& effected_mask_backup,
00860 const CArray<PieceMask,2>& effected_changed_mask_backup,
00861 const CArray<uint64_t,2>& king8infos_backup,
00862 const MobilityTable &mobility_backup);
00863 template <Player P, class Function>
00864 void doUndoCaptureMove(Player2Type<P> player, Square from,Square to,
00865 Piece target, int promoteMask,Function& func);
00866
00867 template<Player P>
00868 void prologueCapture(Player2Type<P>, Square from, Square to, Piece target,
00869 int promoteMask,
00870 Piece& oldPiece, PtypeO& oldPtypeO, PtypeO& capturePtypeO,
00871 PtypeO& new_ptypeo, int& num0, int& num1,
00872 int& num1Index, mask_t& num1Mask,
00873 CArray<PieceMask,2>& pin_or_open_backup,
00874 KingMobility& king_mobility_backup,
00875 PieceMask& promoted_backup,
00876 CArray<PieceMask,2>& effected_mask_backup,
00877 CArray<PieceMask,2>& effected_changed_mask_backup,
00878 CArray<uint64_t,2>& king8infos_backup,
00879 MobilityTable &mobility_backup);
00880
00881 template<Player P>
00882 void epilogueCapture(Player2Type<P>, Square from, Square to, Piece target,
00883 Piece oldPiece, PtypeO oldPtypeO, PtypeO capturePtypeO,
00884 PtypeO newPtypeO, int num0, int num1,
00885 int num1Index, mask_t num1Mask,
00886 const CArray<PieceMask,2>& pin_or_open_backup,
00887 const KingMobility& king_mobility_backup,
00888 const PieceMask& promoted_backup,
00889 const CArray<PieceMask,2>& effected_mask_backup,
00890 const CArray<PieceMask,2>& effected_changed_mask_backup,
00891 const CArray<uint64_t,2>& king8infos_backup,
00892 const MobilityTable &mobility_backup);
00893
00894 template<Direction DIR>
00895 void makePinOpenDir(Square target,
00896 PieceMask& pins, PieceMask const& onBoard,Player defense)
00897 {
00898 const Offset offset = DirectionTraits<DIR>::blackOffset();
00899 Square sq=target-offset;
00900 int num;
00901 while(Piece::isEmptyNum(num=pieceAt(sq).number()))
00902 sq-=offset;
00903 king_mobility[defense][DIR]=static_cast<unsigned char>(sq.uintValue());
00904 if(Piece::isEdgeNum(num)) return;
00905 int num1=longEffectNumTable()[num][DIR];
00906 if(Piece::isPieceNum(num1) && onBoard.test(num1)){
00907 pins.set(num);
00908 }
00909 }
00910 void recalcPinOpen(Square changed, Direction &lastDir, Player defense)
00911 {
00912 Square target=kingSquare(defense);
00913 #ifdef ALLOW_KING_ABSENCE
00914 if (target.isPieceStand())
00915 return;
00916 #endif
00917 const Direction longD=Board_Table.getLongDirection<BLACK>(changed,target);
00918 if(!isLong(longD) || (lastDir!=UL && longD==lastDir)) return;
00919 lastDir=longD;
00920 Direction shortD=longToShort(longD);
00921 {
00922
00923 Square oldPos=Square::makeDirect(king_mobility[defense][shortD]);
00924 int oldNum=pieceAt(oldPos).number();
00925 if(Piece::isPieceNum(oldNum))
00926 pin_or_open[defense].reset(oldNum);
00927 }
00928 const Offset offset = Board_Table.getOffsetForBlack(longD);
00929 Square sq=target-offset;
00930 int num;
00931 while(Piece::isEmptyNum(num=pieceAt(sq).number()))
00932 sq-=offset;
00933 king_mobility[defense][shortD]=static_cast<unsigned char>(sq.uintValue());
00934 if(Piece::isEdgeNum(num)) return;
00935 int num1=longEffectNumTable()[num][shortD];
00936 if(Piece::isPieceNum(num1) && piecesOnBoard(alt(defense)).test(num1)){
00937 pin_or_open[defense].set(num);
00938 }
00939 }
00940 PieceMask makePinOpen(Square target,Player defense);
00941 void makePinOpen(Player defense);
00942 template<Player P>
00943 void makeKing8Info();
00944 };
00945
00946 inline bool operator!=(const NumEffectState& s1, const NumEffectState& s2)
00947 {
00948 return !(s1==s2);
00949 }
00950 }
00951 using state::NumEffectState;
00952 }
00953
00954 template <osl::Player P, typename Function>
00955 void osl::NumEffectState::
00956 doUndoSimpleMove(Player2Type<P> player,
00957 Square from, Square to, int promoteMask, Function& func)
00958 {
00959 Piece oldPiece;
00960 int num;
00961 PtypeO oldPtypeO, newPtypeO;
00962 CArray<PieceMask,2> pin_or_open_backup;
00963 KingMobility king_mobility_backup;
00964 PieceMask promoted_backup;
00965 CArray<PieceMask,2> effected_mask_backup;
00966 CArray<PieceMask,2> effected_changed_mask_backup;
00967 CArray<uint64_t,2> king8infos_backup;
00968 MobilityTable mobility_backup;
00969 prologueSimple(player, from, to, promoteMask, oldPiece, num, oldPtypeO, newPtypeO,
00970 pin_or_open_backup,
00971 king_mobility_backup,
00972 promoted_backup,
00973 effected_mask_backup, effected_changed_mask_backup,
00974 king8infos_backup,
00975 mobility_backup);
00976 if (promoteMask!=0 && num < PtypeTraits<PAWN>::indexLimit)
00977 {
00978 clearPawn(P,from);
00979 changeTurn();
00980 func(to);
00981 changeTurn();
00982 setPawn(P,from);
00983 }
00984 else
00985 {
00986 changeTurn();
00987 func(to);
00988 changeTurn();
00989 }
00990 epilogueSimple(from, to, oldPiece, num, oldPtypeO, newPtypeO,
00991 pin_or_open_backup,
00992 king_mobility_backup,
00993 promoted_backup, effected_mask_backup, effected_changed_mask_backup,
00994 king8infos_backup,
00995 mobility_backup);
00996 }
00997
00998 template <osl::Player P, typename Function>
00999 void osl::NumEffectState::doUndoDropMove(Player2Type<P> player,
01000 Square to, Ptype ptype, Function& func)
01001 {
01002 Piece oldPiece;
01003 PtypeO ptypeO;
01004 int num, numIndex;
01005 mask_t numMask;
01006 CArray<PieceMask,2> pin_or_open_backup;
01007 KingMobility king_mobility_backup;
01008 CArray<PieceMask,2> effected_mask_backup;
01009 CArray<PieceMask,2> effected_changed_mask_backup;
01010 CArray<uint64_t,2> king8infos_backup;
01011 MobilityTable mobility_backup;
01012 prologueDrop(player, to, ptype, oldPiece, num, ptypeO, numIndex, numMask,
01013 pin_or_open_backup, king_mobility_backup,
01014 effected_mask_backup,effected_changed_mask_backup,
01015 king8infos_backup,
01016 mobility_backup);
01017 if (ptype==PAWN)
01018 {
01019 setPawn(P,to);
01020 changeTurn();
01021 func(to);
01022 changeTurn();
01023 clearPawn(P,to);
01024 }
01025 else
01026 {
01027 changeTurn();
01028 func(to);
01029 changeTurn();
01030 }
01031 epilogueDrop(player, to, ptype, oldPiece, num, ptypeO, numIndex, numMask,
01032 pin_or_open_backup, king_mobility_backup,
01033 effected_mask_backup,effected_changed_mask_backup,
01034 king8infos_backup,
01035 mobility_backup);
01036 }
01037
01038 template <osl::Player P, typename Function>
01039 void osl::NumEffectState::doUndoCaptureMove(Player2Type<P> player,
01040 Square from,Square to, Piece target,
01041 int promoteMask,Function& func)
01042 {
01043 Piece oldPiece;
01044 PtypeO oldPtypeO, capturePtypeO, newPtypeO;
01045 int num0, num1, num1Index;
01046 mask_t num1Mask;
01047 CArray<PieceMask,2> pin_or_open_backup;
01048 KingMobility king_mobility_backup;
01049 PieceMask promoted_backup;
01050 CArray<PieceMask,2> effected_mask_backup;
01051 CArray<PieceMask,2> effected_changed_mask_backup;
01052 CArray<uint64_t,2> king8infos_backup;
01053 MobilityTable mobility_backup;
01054 prologueCapture(player, from, to, target, promoteMask, oldPiece, oldPtypeO,
01055 capturePtypeO, newPtypeO, num0, num1, num1Index,num1Mask,
01056 pin_or_open_backup, king_mobility_backup,
01057 promoted_backup,
01058 effected_mask_backup, effected_changed_mask_backup,
01059 king8infos_backup,
01060 mobility_backup);
01061
01062 changeTurn();
01063 const Ptype capturePtype=target.ptype();
01064 if (capturePtype==PAWN)
01065 {
01066 clearPawn(PlayerTraits<P>::opponent,to);
01067 if (promoteMask!=0 && num0<PtypeTraits<PAWN>::indexLimit)
01068 {
01069 clearPawn(P,from);
01070 func(to);
01071 setPawn(P,from);
01072 }
01073 else
01074 {
01075 func(to);
01076 }
01077 setPawn(PlayerTraits<P>::opponent,to);
01078 }
01079 else if (promoteMask!=0 && num0<PtypeTraits<PAWN>::indexLimit)
01080 {
01081 clearPawn(P,from);
01082 func(to);
01083 setPawn(P,from);
01084 }
01085 else
01086 {
01087 func(to);
01088 }
01089 changeTurn();
01090
01091 epilogueCapture(player, from, to, target, oldPiece, oldPtypeO, capturePtypeO, newPtypeO,
01092 num0, num1, num1Index,num1Mask,
01093 pin_or_open_backup, king_mobility_backup,
01094 promoted_backup,effected_mask_backup, effected_changed_mask_backup,
01095 king8infos_backup,
01096 mobility_backup);
01097 }
01098
01099 template <class Action>
01100 void osl::NumEffectState::
01101 forEachEffectOfPiece(Piece piece,Action & action) const
01102 {
01103 Square pieceSquare = piece.square();
01104 switch ((int)piece.ptypeO()) {
01105 case NEW_PTYPEO(WHITE,PAWN): forEachEffectOfPiece<WHITE,PAWN,Action>(pieceSquare,action); break;
01106 case NEW_PTYPEO(WHITE,LANCE): forEachEffectOfPiece<WHITE,LANCE,Action>(pieceSquare,action); break;
01107 case NEW_PTYPEO(WHITE,KNIGHT): forEachEffectOfPiece<WHITE,KNIGHT,Action>(pieceSquare,action); break;
01108 case NEW_PTYPEO(WHITE,SILVER): forEachEffectOfPiece<WHITE,SILVER,Action>(pieceSquare,action); break;
01109 case NEW_PTYPEO(WHITE,PPAWN): forEachEffectOfPiece<WHITE,PPAWN,Action>(pieceSquare,action); break;
01110 case NEW_PTYPEO(WHITE,PLANCE): forEachEffectOfPiece<WHITE,PLANCE,Action>(pieceSquare,action); break;
01111 case NEW_PTYPEO(WHITE,PKNIGHT): forEachEffectOfPiece<WHITE,PKNIGHT,Action>(pieceSquare,action); break;
01112 case NEW_PTYPEO(WHITE,PSILVER): forEachEffectOfPiece<WHITE,PSILVER,Action>(pieceSquare,action); break;
01113 case NEW_PTYPEO(WHITE,GOLD): forEachEffectOfPiece<WHITE,GOLD,Action>(pieceSquare,action); break;
01114 case NEW_PTYPEO(WHITE,BISHOP): forEachEffectOfPiece<WHITE,BISHOP,Action>(pieceSquare,action); break;
01115 case NEW_PTYPEO(WHITE,PBISHOP): forEachEffectOfPiece<WHITE,PBISHOP,Action>(pieceSquare,action); break;
01116 case NEW_PTYPEO(WHITE,ROOK): forEachEffectOfPiece<WHITE,ROOK,Action>(pieceSquare,action); break;
01117 case NEW_PTYPEO(WHITE,PROOK): forEachEffectOfPiece<WHITE,PROOK,Action>(pieceSquare,action); break;
01118 case NEW_PTYPEO(WHITE,KING): forEachEffectOfPiece<WHITE,KING,Action>(pieceSquare,action); break;
01119 case NEW_PTYPEO(BLACK,PAWN): forEachEffectOfPiece<BLACK,PAWN,Action>(pieceSquare,action); break;
01120 case NEW_PTYPEO(BLACK,LANCE): forEachEffectOfPiece<BLACK,LANCE,Action>(pieceSquare,action); break;
01121 case NEW_PTYPEO(BLACK,KNIGHT): forEachEffectOfPiece<BLACK,KNIGHT,Action>(pieceSquare,action); break;
01122 case NEW_PTYPEO(BLACK,SILVER): forEachEffectOfPiece<BLACK,SILVER,Action>(pieceSquare,action); break;
01123 case NEW_PTYPEO(BLACK,PPAWN): forEachEffectOfPiece<BLACK,PPAWN,Action>(pieceSquare,action); break;
01124 case NEW_PTYPEO(BLACK,PLANCE): forEachEffectOfPiece<BLACK,PLANCE,Action>(pieceSquare,action); break;
01125 case NEW_PTYPEO(BLACK,PKNIGHT): forEachEffectOfPiece<BLACK,PKNIGHT,Action>(pieceSquare,action); break;
01126 case NEW_PTYPEO(BLACK,PSILVER): forEachEffectOfPiece<BLACK,PSILVER,Action>(pieceSquare,action); break;
01127 case NEW_PTYPEO(BLACK,GOLD): forEachEffectOfPiece<BLACK,GOLD,Action>(pieceSquare,action); break;
01128 case NEW_PTYPEO(BLACK,BISHOP): forEachEffectOfPiece<BLACK,BISHOP,Action>(pieceSquare,action); break;
01129 case NEW_PTYPEO(BLACK,PBISHOP): forEachEffectOfPiece<BLACK,PBISHOP,Action>(pieceSquare,action); break;
01130 case NEW_PTYPEO(BLACK,ROOK): forEachEffectOfPiece<BLACK,ROOK,Action>(pieceSquare,action); break;
01131 case NEW_PTYPEO(BLACK,PROOK): forEachEffectOfPiece<BLACK,PROOK,Action>(pieceSquare,action); break;
01132 case NEW_PTYPEO(BLACK,KING): forEachEffectOfPiece<BLACK,KING,Action>(pieceSquare,action); break;
01133 default: assert(0);
01134 }
01135 }
01136
01137 template <osl::Player P, osl::Ptype Type, class Action>
01138 void osl::NumEffectState::
01139 forEachEffectOfPiece(Square pieceSquare,Action & action) const
01140 {
01141 forEachEffectOfPieceDir<P,Type,Action,UL>(pieceSquare,action);
01142 forEachEffectOfPieceDir<P,Type,Action,U>(pieceSquare,action);
01143 forEachEffectOfPieceDir<P,Type,Action,UR>(pieceSquare,action);
01144 forEachEffectOfPieceDir<P,Type,Action,L>(pieceSquare,action);
01145 forEachEffectOfPieceDir<P,Type,Action,R>(pieceSquare,action);
01146 forEachEffectOfPieceDir<P,Type,Action,DL>(pieceSquare,action);
01147 forEachEffectOfPieceDir<P,Type,Action,D>(pieceSquare,action);
01148 forEachEffectOfPieceDir<P,Type,Action,DR>(pieceSquare,action);
01149 forEachEffectOfPieceDir<P,Type,Action,UUL>(pieceSquare,action);
01150 forEachEffectOfPieceDir<P,Type,Action,UUR>(pieceSquare,action);
01151 forEachEffectOfPieceLongDir<P,Type,Action,LONG_UL>(pieceSquare,action);
01152 forEachEffectOfPieceLongDir<P,Type,Action,LONG_U>(pieceSquare,action);
01153 forEachEffectOfPieceLongDir<P,Type,Action,LONG_UR>(pieceSquare,action);
01154 forEachEffectOfPieceLongDir<P,Type,Action,LONG_L>(pieceSquare,action);
01155 forEachEffectOfPieceLongDir<P,Type,Action,LONG_R>(pieceSquare,action);
01156 forEachEffectOfPieceLongDir<P,Type,Action,LONG_DL>(pieceSquare,action);
01157 forEachEffectOfPieceLongDir<P,Type,Action,LONG_D>(pieceSquare,action);
01158 forEachEffectOfPieceLongDir<P,Type,Action,LONG_DR>(pieceSquare,action);
01159 }
01160
01161 #endif
01162
01163
01164
01165