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 }
00072 const PieceMask checkShadow(Player attack) const
00073 {
00074 return pin_or_open[alt(attack)]&piecesOnBoard(attack);
00075 }
00076 PieceMask pinOrOpen(Player king) const
00077 {
00078 return pin_or_open[king];
00079 }
00080 uint64_t Iking8Info(Player king) const
00081 {
00082 return king8infos[king];
00083 }
00084 const checkmate::King8Info
00085 #ifdef __GNUC__
00086 __attribute__ ((pure))
00087 #endif
00088 king8Info(Player king) const;
00090 bool inCheck(Player P) const
00091 {
00092 const Square king = kingSquare(P);
00093 #ifdef ALLOW_KING_ABSENCE
00094 if (king.isPieceStand())
00095 return false;
00096 #endif
00097 return hasEffectAt(alt(P), king);
00098 }
00100 bool inCheck() const { return inCheck(turn()); }
00101 const EffectedNumTable& longEffectNumTable() const
00102 {
00103 return effects.effectedNumTable;
00104 }
00105
00107 const PieceMask effectedMask(Player pl) const
00108 {
00109 return effects.effected_mask[pl];
00110 }
00114 const PieceMask effectedChanged(Player pl) const
00115 {
00116 return effects.effected_changed_mask[pl];
00117 }
00118 bool hasChangedEffects() const {
00119 return ! effects.changedEffects(BLACK).isInvalid();
00120 }
00121 const BoardMask changedEffects(Player pl) const{
00122 assert(hasChangedEffects());
00123 return effects.changedEffects(pl);
00124 }
00125 const BoardMask changedEffects() const{
00126 BoardMask ret = changedEffects(BLACK);
00127 return ret |= changedEffects(WHITE);
00128 }
00129 const NumBitmapEffect changedPieces() const{
00130 return effects.changedPieces();
00131 }
00132 template <Ptype PTYPE> bool longEffectChanged() const
00133 {
00134 return changedPieces().template hasLong<PTYPE>();
00135 }
00136 template <Ptype PTYPE> bool anyEffectChanged() const
00137 {
00138 return changedPieces().template hasAny<PTYPE>();
00139 }
00140
00142 const Piece findThreatenedPiece(Player P) const;
00143
00144
00145
00146
00147 bool isOnBoardNum(int num) const
00148 {
00149 return piecesOnBoard(BLACK).test(num) || piecesOnBoard(WHITE).test(num);
00150 }
00151
00152 Square mobilityOf(Direction d,int num) const
00153 {
00154 return effects.mobilityTable.get(d,num);
00155 }
00156 Square mobilityOf(Direction d, Piece p) const
00157 {
00158 return mobilityOf(d, p.number());
00159 }
00160 Square kingMobilityAbs(Player p, Direction d) const
00161 {
00162 return Square::makeDirect(king_mobility[p][d]);
00163 }
00169 Square kingMobilityOfPlayer(Player p, Direction d) const
00170 {
00171 if (p == BLACK)
00172 d = inverse(d);
00173 return kingMobilityAbs(p, d);
00174 }
00179 template<Player P>
00180 Direction pinnedDir(Piece p) const
00181 {
00182 assert(p.owner() == P);
00183 assert(pinOrOpen(P).test(p.number()));
00184 Square king=kingSquare<P>();
00185 return Board_Table.getShort8<P>(p.square(),king);
00186 }
00187 Direction pinnedDir(Piece p) const
00188 {
00189 if (p.owner() == BLACK)
00190 return pinnedDir<BLACK>(p);
00191 else
00192 return pinnedDir<WHITE>(p);
00193 }
00198 template<Player P>
00199 bool pinnedCanMoveTo(Piece p,Square to) const
00200 {
00201 assert(p.owner() == P);
00202 Direction d=pinnedDir<P>(p);
00203 Square from=p.square();
00204 assert(hasEffectIf(p.ptypeO(),from,to));
00205 return primDir(d)==primDirUnsafe(Board_Table.getShort8Unsafe<P>(from,to));
00206 }
00207 bool pinnedCanMoveTo(Piece p,Square to) const
00208 {
00209 if (p.owner() == BLACK)
00210 return pinnedCanMoveTo<BLACK>(p, to);
00211 else
00212 return pinnedCanMoveTo<WHITE>(p, to);
00213 }
00214
00215
00216
00217 const NumBitmapEffect effectSetAt(Square sq) const
00218 {
00219 return effects.effectSetAt(sq);
00220 }
00225 int countEffect(Player player,Square target) const
00226 {
00227 assert(target.isOnBoard());
00228 return effectSetAt(target).countEffect(player);
00229 }
00235 int
00236 #ifdef __GNUC__
00237 __attribute__ ((pure))
00238 #endif
00239 countEffect(Player player,Square target, PieceMask pins) const
00240 {
00241 assert(target.isOnBoard());
00242 const NumBitmapEffect effect = effectSetAt(target);
00243 const int all = effect.countEffect(player);
00244 pins &= effect;
00245 return all - pins.countBit();
00246 }
00247
00248
00249
00250
00251 template <Ptype PTYPE>
00252 const mask_t allEffectAt(Player P, Square target) const
00253 {
00254 return effectSetAt(target).template selectBit<PTYPE>() & piecesOnBoard(P).template getMask<PTYPE>();
00255 }
00256 const mask_t allEffectAt(Player P, Ptype ptype, Square target) const;
00257 template <Ptype PTYPE> const mask_t longEffectAt(Square target) const
00258 {
00259 return effectSetAt(target).selectLong<PTYPE>() >> 8;
00260 }
00261 template <Ptype PTYPE> const mask_t longEffectAt(Square target, Player owner) const
00262 {
00263 return longEffectAt<PTYPE>(target) & piecesOnBoard(owner).getMask(1);
00264 }
00265 const mask_t longEffectAt(Square target) const
00266 {
00267 return effectSetAt(target).selectLong() >> 8;
00268 }
00269 const mask_t longEffectAt(Square target, Player owner) const
00270 {
00271 return longEffectAt(target) & piecesOnBoard(owner).getMask(1);
00272 }
00273
00274
00275
00276
00282 template<Player P>
00283 bool hasEffectAt(Square target) const {
00284 assert(target.isOnBoard());
00285 mask_t mask=effectSetAt(target).getMask(1);
00286 mask&=NumBitmapEffect::playerEffectMask<P>();
00287 return !mask.none();
00288 }
00294 bool hasEffectAt(Player player,Square target) const {
00295 assert(target.isOnBoard());
00296 mask_t mask=effectSetAt(target).getMask(1);
00297 mask&=NumBitmapEffect::playerEffectMask(player);
00298 return !mask.none();
00299 }
00300
00304 template <Ptype PTYPE>
00305 bool hasLongEffectAt(Player P, Square to) const {
00306 BOOST_STATIC_ASSERT( (PTYPE == LANCE || PTYPE == BISHOP || PTYPE == ROOK) );
00307 return longEffectAt<PTYPE>(to, P).any();
00308 }
00309
00313 template <Ptype PTYPE>
00314 bool hasEffectByPtype(Player attack, Square target) const
00315 {
00316 return allEffectAt<PTYPE>(attack, target).any();
00317 }
00321 template <Ptype PTYPE>
00322 bool hasEffectByPtypeStrict(Player attack, Square target) const
00323 {
00324 mask_t mask=allEffectAt<PTYPE>(attack, target);
00325 if (isPromoted(PTYPE))
00326 mask &= promoted.getMask<PTYPE>();
00327 else
00328 mask &= ~(promoted.getMask<PTYPE>());
00329 return mask.any();
00330 }
00335 template<Direction Dir,Player P>
00336 bool hasEffectInDirection(Square to) const {
00337 BOOST_STATIC_ASSERT( (DirectionTraits<Dir>::isLong) );
00338 const PieceMask& pieces_onboard=piecesOnBoard(P);
00339 mask_t mask1=pieces_onboard.getMask(1);
00340 mask1 &= ((PtypeDirectionTraits<LANCE,Dir>::canMove
00341 ? mask_t::makeDirect(PtypeFuns<LANCE>::indexMask)
00342 : mask_t::makeDirect(0))
00343 | (PtypeDirectionTraits<BISHOP,Dir>::canMove
00344 ? mask_t::makeDirect(PtypeFuns<BISHOP>::indexMask)
00345 : mask_t::makeDirect(0))
00346 | (PtypeDirectionTraits<ROOK,Dir>::canMove
00347 ? mask_t::makeDirect(PtypeFuns<ROOK>::indexMask)
00348 : mask_t::makeDirect(0)));
00349 mask1 <<= 8;
00350
00351 mask1&=effectSetAt(to).getMask(1)& NumBitmapEffect::longEffectMask();
00352 while (mask1.any())
00353 {
00354 int num=mask1.takeOneBit()+NumBitmapEffect::longToNumOffset;
00355 Square from = pieceOf(num).square();
00356 Direction dir=Board_Table.getLongDirection<BLACK>(Offset32(to,from));
00357 if (dir==DirectionPlayerTraits<Dir,P>::directionByBlack)
00358 return true;
00359 }
00360 return false;
00361 }
00368 bool hasEffectNotBy(Player player,Piece piece,Square target) const {
00369 assert(piece.owner()==player);
00370 PieceMask pieces_onboard=piecesOnBoard(player);
00371 int num=piece.number();
00372 pieces_onboard.reset(num);
00373 return (pieces_onboard&effectSetAt(target)).any();
00374 }
00378 bool hasEffectByNotPinnedAndKing(Player pl,Square target) const{
00379 assert(target.isOnBoard());
00380 PieceMask m=piecesOnBoard(pl)& ~pinOrOpen(pl) & effectSetAt(target);
00381 m.clearBit<KING>();
00382 return m.any();
00383 }
00387 bool hasEffectByNotPinned(Player pl,Square target) const{
00388 assert(target.isOnBoard());
00389 PieceMask m=piecesOnBoard(pl)& ~pinOrOpen(pl) & effectSetAt(target);
00390 return m.any();
00391 }
00398 bool hasMultipleEffectAt(Player player,Square target) const
00399 {
00400 mask_t mask=effectSetAt(target).getMask(1);
00401 mask&=NumBitmapEffect::playerEffectMask(player);
00402 return NumBitmapEffect::playerEffect(player).getMask(1) < mask;
00403 }
00404
00409 bool hasEffectByPiece(Piece attack, Square target) const
00410 {
00411 assert(attack.isPiece());
00412 assert(target.isOnBoard());
00413 return effectSetAt(target).test(attack.number());
00414 }
00415
00416
00424 bool hasEffectIf(PtypeO ptypeo,Square attacker,
00425 Square target) const
00426 #ifdef __GNUC__
00427 __attribute__ ((pure))
00428 #endif
00429 {
00430 Offset32 offset32=Offset32(target,attacker);
00431 EffectContent effect=Ptype_Table.getEffect(ptypeo,offset32);
00432 if (! effect.hasEffect())
00433 return false;
00434 if (effect.hasUnblockableEffect())
00435 return true;
00436 assert(Board_Table.getShortOffset(offset32) == effect.offset());
00437 return this->isEmptyBetween(attacker,target,effect.offset());
00438 }
00442 template<Player P>
00443 bool
00444 #ifdef __GNUC__
00445 __attribute__ ((pure))
00446 #endif
00447 hasEffectByWithRemove(Square target,Square removed) const;
00448
00449 bool hasEffectByWithRemove(Player player, Square target,Square removed) const{
00450 if (player==BLACK)
00451 return hasEffectByWithRemove<BLACK>(target,removed);
00452 else
00453 return hasEffectByWithRemove<WHITE>(target,removed);
00454 }
00455
00456
00457
00458
00459
00461 template <Ptype PTYPE>
00462 const Piece findAttackAt(Player attack, Square target) const
00463 {
00464 mask_t mask=allEffectAt<PTYPE>(attack, target);
00465 if (mask.none())
00466 return Piece::EMPTY();
00467 return pieceOf(mask.takeOneBit()+PtypeFuns<PTYPE>::indexNum*32);
00468 }
00469 template <Ptype PTYPE>
00470 const Piece findAttackAtStrict(Player attack, Square target) const
00471 {
00472 mask_t mask=allEffectAt<PTYPE>(attack, target);
00473 if (isPromoted(PTYPE))
00474 mask &= promoted.getMask<PTYPE>();
00475 else
00476 mask &= ~(promoted.getMask<PTYPE>());
00477 if (mask.none())
00478 return Piece::EMPTY();
00479 return pieceOf(mask.takeOneBit()+PtypeFuns<PTYPE>::indexNum*32);
00480 }
00485 const Piece findLongAttackAt(Player owner, int piece, Direction d) const
00486 {
00487 assert(pieceOf(piece).isOnBoardByOwner(owner));
00488 if (owner == BLACK)
00489 d = inverse(d);
00490 const int num = effects.effectedNumTable[piece][d];
00491 if (num == EMPTY_NUM)
00492 return Piece::EMPTY();
00493 return pieceOf(num);
00494 }
00495 const Piece findLongAttackAt(Player owner, Piece piece, Direction d) const
00496 {
00497 assert(piece.isPiece());
00498 assert(piece.owner() == owner);
00499 return findLongAttackAt(owner, piece.number(), d);
00500 }
00501 const Piece findLongAttackAt(Piece piece, Direction d) const
00502 {
00503 assert(piece.isPiece());
00504 return findLongAttackAt(piece.owner(), piece, d);
00505 }
00506 const Piece findLongAttackAt(Square square, Direction d) const
00507 {
00508 return findLongAttackAt(pieceOnBoard(square), d);
00509 }
00513 const Piece selectCheapPiece(PieceMask effect) const;
00519 const Piece findCheapAttack(Player P, Square square) const
00520 {
00521 return selectCheapPiece(piecesOnBoard(P) & effectSetAt(square));
00522 }
00528 const Piece findCheapAttackNotBy(Player P, Square square, const PieceMask& ignore) const
00529 {
00530 PieceMask pieces = piecesOnBoard(P);
00531 pieces &= ~ignore;
00532 return selectCheapPiece(pieces & effectSetAt(square));
00533 }
00534 const Piece findAttackNotBy(Player P, Square square, const PieceMask& ignore) const
00535 {
00536 PieceMask pieces = piecesOnBoard(P);
00537 pieces &= ~ignore;
00538 pieces &= effectSetAt(square);
00539 if (pieces.none())
00540 return Piece::EMPTY();
00541 return pieceOf(pieces.takeOneBit());
00542 }
00551 template<Player P>
00552 bool findCheckPiece(Piece& attack_piece) const
00553 {
00554 return hasEffectAt<PlayerTraits<P>::opponent>(kingSquare(P),attack_piece);
00555 }
00556 bool hasEffectAt(Player P, Square target,Piece& attackerPiece) const
00557 {
00558 if (P == BLACK)
00559 return hasEffectAt<BLACK>(target, attackerPiece);
00560 else
00561 return hasEffectAt<WHITE>(target, attackerPiece);
00562 }
00569 template<Player P>
00570 bool hasEffectAt(Square target,Piece& attackerPiece) const {
00571 attackerPiece=Piece::EMPTY();
00572 const PieceMask& pieceMask=piecesOnBoard(P)&effectSetAt(target);
00573 #if OSL_WORDSIZE == 64
00574 mask_t mask=pieceMask.getMask(0);
00575 if (mask.none()) return false;
00580 if (mask.hasMultipleBit())
00581 return true;
00582 int num=mask.bsf();
00583 attackerPiece=pieceOf(num);
00584 return true;
00585 #elif OSL_WORDSIZE == 32
00586 mask_t mask0=pieceMask.getMask(0);
00587 mask_t mask1=pieceMask.getMask(1);
00588 if (mask0.any())
00589 {
00590 if (mask1.any())
00591 return true;
00592 int num=mask0.bsf();
00593 if (mask0 == PieceMask::numToMask(num))
00594 attackerPiece=pieceOf(num);
00595 return true;
00596 }
00597 else if (mask1.any())
00598 {
00599 int num=mask1.bsf();
00600 if (mask1==PieceMask::numToMask(num))
00601 attackerPiece=pieceOf(num+32);
00602 return true;
00603 }
00604 else
00605 return false;
00606 #endif
00607 }
00608
00609
00610
00611
00622 template <bool show_error>
00623 bool isAlmostValidMove(Move move) const;
00624 bool isAlmostValidMove(Move move,bool show_error=true) const;
00625 void makeMove(Move move);
00626 void makeMovePass()
00627 {
00628 changeTurn();
00629 effects.clearChangedEffects();
00630 effects.clearEffectedChanged();
00631 }
00632
00633 template <class Function>
00634 void makeUnmakePass(Function &f)
00635 {
00636 changeTurn();
00637 f(Square::STAND());
00638 changeTurn();
00639 }
00640 template <class Function>
00641 void makeUnmakeMove(Move move, Function &f)
00642 {
00643 if (move.player() == BLACK)
00644 makeUnmakeMove(Player2Type<BLACK>(), move, f);
00645 else
00646 makeUnmakeMove(Player2Type<WHITE>(), move, f);
00647 }
00648 template <Player P, class Function>
00649 void makeUnmakeMove(Player2Type<P> player, Move move, Function &f)
00650 {
00651 if (move.isPass())
00652 return makeUnmakePass(f);
00653 assert(move.isValid());
00654 assert(isAlmostValidMove(move));
00655 assert(P == move.player());
00656 assert(P == turn());
00657 Square from=move.from();
00658 Square to=move.to();
00659 if (from.isPieceStand())
00660 {
00661 assert(pieceAt(to) == Piece::EMPTY());
00662 doUndoDropMove(player,to,move.ptype(),f);
00663 }
00664 else
00665 {
00666 assert(pieceAt(from) != Piece::EMPTY());
00667 Piece captured=pieceAt(to);
00668 if (captured != Piece::EMPTY())
00669 {
00670 doUndoCaptureMove(player,from,to,captured,move.promoteMask(),f);
00671 }
00672 else
00673 {
00674 doUndoSimpleMove(player,from,to,move.promoteMask(),f);
00675 }
00676 }
00677 }
00678 bool wasCheckEvasion(Move last_move) const;
00679
00680
00681
00684 template<Player P,Ptype T,typename F>
00685 void forEachOnBoard(F& func) const {
00686 mask_t onMask=piecesOnBoard(P).template selectBit<T>() ;
00687 while (onMask.any())
00688 {
00689 int num=onMask.takeOneBit()+((PtypeFuns<T>::indexNum)<<5);
00690 Piece p = pieceOf(num);
00691 func(p);
00692 }
00693 }
00696 template<Player P,Ptype T,typename F>
00697 void forEachOnBoardPtypeStrict(F& func) const
00698 {
00699 mask_t mask=piecesOnBoard(P).template selectBit<T>() ;
00700 if (isPromoted(T))
00701 mask &= promoted.getMask<T>();
00702 else
00703 mask &= ~(promoted.getMask<T>());
00704 while (mask.any())
00705 {
00706 int num=mask.takeOneBit()+((PtypeFuns<T>::indexNum)<<5);
00707 func(pieceOf(num));
00708 }
00709 }
00710 private:
00711 template<Player P,class Action>
00712 void forEachEffect(const PieceMask& pieces, Square sq,Action & action) const
00713 {
00714 #if OSL_WORDSIZE == 64
00715 mask_t mask=pieces.getMask(0);
00716 while (mask.any())
00717 {
00718 const int num=mask.takeOneBit();
00719 action.template doAction<P>(pieceOf(num),sq);
00720 }
00721 #elif OSL_WORDSIZE == 32
00722 mask_t mask0=pieces.getMask(0);
00723 while (mask0.any())
00724 {
00725 const int num=mask0.takeOneBit();
00726 action.template doAction<P>(pieceOf(num),sq);
00727 }
00728 mask_t mask1=pieces.getMask(1);
00729 while (mask1.any())
00730 {
00731 const int num=mask1.takeOneBit()+32;
00732 action.template doAction<P>(pieceOf(num),sq);
00733 }
00734 #endif
00735 }
00736 public:
00741 template<Player P,class Action>
00742 void forEachEffect(Square sq,Action & action) const
00743 {
00744 const PieceMask pieceMask=piecesOnBoard(P)&effectSetAt(sq);
00745 forEachEffect<P,Action>(pieceMask, sq, action);
00746 }
00752 template<Player P,class Action>
00753 void forEachEffect(Square sq,Action & action,const PieceMask& pin) const
00754 {
00755 PieceMask pieceMask=piecesOnBoard(P)&effectSetAt(sq);
00756 pieceMask &= ~pin;
00757 forEachEffect<P,Action>(pieceMask, sq, action);
00758 }
00759
00765 template<Player P,class Action>
00766 void forEachEffectNotBy(Square sq,Piece piece,Action & action) const {
00767 PieceMask pieces=piecesOnBoard(P)&effectSetAt(sq);
00768 pieces.reset(piece.number());
00769 forEachEffect<P,Action>(pieces, sq, action);
00770 }
00771
00772 private:
00773 template<Player P,Ptype Type,class Action,Direction Dir>
00774 void forEachEffectOfPieceDir(Square, Action&, Int2Type<false>) const {}
00775 template<Player P,Ptype Type,class Action,Direction Dir>
00776 void forEachEffectOfPieceDir(Square pieceSquare,Action & action,Int2Type<true>) const {
00777 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00778 action.template doAction<P>(this->pieceAt(pieceSquare),pieceSquare+offset);
00779 }
00780
00781 template<Player P,Ptype Type,class Action,Direction Dir>
00782 void forEachEffectOfPieceDir(Square pieceSquare,Action & action) const {
00783 forEachEffectOfPieceDir<P,Type,Action,Dir>(pieceSquare,action,Int2Type<(PtypeTraits<Type>::moveMask & DirectionTraits<Dir>::mask)!=0>());
00784 }
00785 template<Player P,Ptype Type,class Action,Direction Dir>
00786 void forEachEffectOfPieceLongDir(Square, Action&, Int2Type<false>) const {}
00787 template<Player P,Ptype Type,class Action,Direction Dir>
00788 void forEachEffectOfPieceLongDir(Square pieceSquare,Action & action,Int2Type<true>) const {
00789 Piece piece=this->pieceAt(pieceSquare);
00790 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00791 assert(offset.intValue() != 35);
00792 Square sq=pieceSquare+offset;
00793 for (;this->pieceAt(sq).isEmpty();sq+=offset)
00794 action.template doAction<P>(piece,sq);
00795 action.template doAction<P>(piece,sq);
00796 }
00797
00798 template<Player P,Ptype Type,class Action,Direction Dir>
00799 void forEachEffectOfPieceLongDir(Square pieceSquare,Action & action) const {
00800 forEachEffectOfPieceLongDir<P,Type,Action,Dir>(pieceSquare,action,Int2Type<(PtypeTraits<Type>::moveMask & DirectionTraits<Dir>::mask)!=0>());
00801 }
00802 public:
00810 template<Player P,Ptype Type,class Action>
00811 void forEachEffectOfPiece(Square pieceSquare,Action & action) const;
00812 template<class Action>
00813 void forEachEffectOfPiece(Piece piece,Action & action) const;
00814
00815
00816 private:
00817 void doSimpleMove(Square from, Square to, int promoteMask);
00818 void doDropMove(Square to,Ptype ptype);
00819 void doCaptureMove(Square from, Square to, Piece target,int promoteMask);
00820
00821 template <Player P, class Function>
00822 void doUndoSimpleMove(Player2Type<P> player,
00823 Square from, Square to, int promoteMask,Function& func);
00824 template <Player P>
00825 void prologueSimple(Player2Type<P>, Square from, Square to, int promoteMask,
00826 Piece& oldPiece, int& num,
00827 PtypeO& oldPtypeO, PtypeO& new_ptypeo,
00828 CArray<PieceMask,2>& pin_or_open_backup,
00829 KingMobility& king_mobility_backup,
00830 PieceMask& promoted_backup,
00831 CArray<PieceMask,2>& effected_mask_backup,
00832 CArray<PieceMask,2>& effected_changed_mask_backup,
00833 CArray<uint64_t,2>& king8infos_backup,
00834 MobilityTable &mobility_backup
00835 );
00836 void epilogueSimple(Square from, Square to, Piece oldPiece,
00837 int num, PtypeO oldPtypeO, PtypeO newPtypeO,
00838 const CArray<PieceMask,2>& pin_or_open_backup,
00839 const KingMobility& king_mobility_backup,
00840 const PieceMask& promoted_backup,
00841 const CArray<PieceMask,2>& effected_mask_backup,
00842 const CArray<PieceMask,2>& effected_changed_mask_backup,
00843 const CArray<uint64_t,2>& king8infos_backup,
00844 const MobilityTable &mobility_backup
00845 );
00846 template <Player P, class Function>
00847 void doUndoDropMove(Player2Type<P> player,
00848 Square to, Ptype ptype, Function& func);
00849 template <Player P>
00850 void prologueDrop(Player2Type<P>, Square to, Ptype ptype,
00851 Piece& oldPiece, int& num, PtypeO& ptypeO,
00852 int& numIndex, mask_t& numMask,
00853 CArray<PieceMask,2>& pin_or_open_backup,
00854 KingMobility& king_mobility_backup,
00855 CArray<PieceMask,2>& effected_mask_backup,
00856 CArray<PieceMask,2>& effected_changed_mask_backup,
00857 CArray<uint64_t,2>& king8infos_backup,
00858 MobilityTable &mobility_backup);
00859 template<Player P>
00860 void epilogueDrop(Player2Type<P>, Square to, Ptype ptype, Piece oldPiece,
00861 int num, PtypeO ptypeO, int numIndex, mask_t numMask,
00862 const CArray<PieceMask,2>& pin_or_open_backup,
00863 const KingMobility& king_mobility_backup,
00864 const CArray<PieceMask,2>& effected_mask_backup,
00865 const CArray<PieceMask,2>& effected_changed_mask_backup,
00866 const CArray<uint64_t,2>& king8infos_backup,
00867 const MobilityTable &mobility_backup);
00868 template <Player P, class Function>
00869 void doUndoCaptureMove(Player2Type<P> player, Square from,Square to,
00870 Piece target, int promoteMask,Function& func);
00871
00872 template<Player P>
00873 void prologueCapture(Player2Type<P>, Square from, Square to, Piece target,
00874 int promoteMask,
00875 Piece& oldPiece, PtypeO& oldPtypeO, PtypeO& capturePtypeO,
00876 PtypeO& new_ptypeo, int& num0, int& num1,
00877 int& num1Index, mask_t& num1Mask,
00878 CArray<PieceMask,2>& pin_or_open_backup,
00879 KingMobility& king_mobility_backup,
00880 PieceMask& promoted_backup,
00881 CArray<PieceMask,2>& effected_mask_backup,
00882 CArray<PieceMask,2>& effected_changed_mask_backup,
00883 CArray<uint64_t,2>& king8infos_backup,
00884 MobilityTable &mobility_backup);
00885
00886 template<Player P>
00887 void epilogueCapture(Player2Type<P>, Square from, Square to, Piece target,
00888 Piece oldPiece, PtypeO oldPtypeO, PtypeO capturePtypeO,
00889 PtypeO newPtypeO, int num0, int num1,
00890 int num1Index, mask_t num1Mask,
00891 const CArray<PieceMask,2>& pin_or_open_backup,
00892 const KingMobility& king_mobility_backup,
00893 const PieceMask& promoted_backup,
00894 const CArray<PieceMask,2>& effected_mask_backup,
00895 const CArray<PieceMask,2>& effected_changed_mask_backup,
00896 const CArray<uint64_t,2>& king8infos_backup,
00897 const MobilityTable &mobility_backup);
00898
00899 template<Direction DIR>
00900 void makePinOpenDir(Square target,
00901 PieceMask& pins, PieceMask const& onBoard,Player defense)
00902 {
00903 const Offset offset = DirectionTraits<DIR>::blackOffset();
00904 Square sq=target-offset;
00905 int num;
00906 while(Piece::isEmptyNum(num=pieceAt(sq).number()))
00907 sq-=offset;
00908 king_mobility[defense][DIR]=static_cast<unsigned char>(sq.uintValue());
00909 if(Piece::isEdgeNum(num)) return;
00910 int num1=longEffectNumTable()[num][DIR];
00911 if(Piece::isPieceNum(num1) && onBoard.test(num1)){
00912 pins.set(num);
00913 }
00914 }
00915 void recalcPinOpen(Square changed, Direction &lastDir, Player defense)
00916 {
00917 Square target=kingSquare(defense);
00918 #ifdef ALLOW_KING_ABSENCE
00919 if (target.isPieceStand())
00920 return;
00921 #endif
00922 const Direction longD=Board_Table.getLongDirection<BLACK>(changed,target);
00923 if(!isLong(longD) || (lastDir!=UL && longD==lastDir)) return;
00924 lastDir=longD;
00925 Direction shortD=longToShort(longD);
00926 {
00927
00928 Square oldPos=Square::makeDirect(king_mobility[defense][shortD]);
00929 int oldNum=pieceAt(oldPos).number();
00930 if(Piece::isPieceNum(oldNum))
00931 pin_or_open[defense].reset(oldNum);
00932 }
00933 const Offset offset = Board_Table.getOffsetForBlack(longD);
00934 Square sq=target-offset;
00935 int num;
00936 while(Piece::isEmptyNum(num=pieceAt(sq).number()))
00937 sq-=offset;
00938 king_mobility[defense][shortD]=static_cast<unsigned char>(sq.uintValue());
00939 if(Piece::isEdgeNum(num)) return;
00940 int num1=longEffectNumTable()[num][shortD];
00941 if(Piece::isPieceNum(num1) && piecesOnBoard(alt(defense)).test(num1)){
00942 pin_or_open[defense].set(num);
00943 }
00944 }
00945 PieceMask makePinOpen(Square target,Player defense);
00946 void makePinOpen(Player defense);
00947 template<Player P>
00948 void makeKing8Info();
00949 };
00950
00951 inline bool operator!=(const NumEffectState& s1, const NumEffectState& s2)
00952 {
00953 return !(s1==s2);
00954 }
00955 }
00956 using state::NumEffectState;
00957 }
00958
00959 template <osl::Player P, typename Function>
00960 void osl::NumEffectState::
00961 doUndoSimpleMove(Player2Type<P> player,
00962 Square from, Square to, int promoteMask, Function& func)
00963 {
00964 Piece oldPiece;
00965 int num;
00966 PtypeO oldPtypeO, newPtypeO;
00967 CArray<PieceMask,2> pin_or_open_backup;
00968 KingMobility king_mobility_backup;
00969 PieceMask promoted_backup;
00970 CArray<PieceMask,2> effected_mask_backup;
00971 CArray<PieceMask,2> effected_changed_mask_backup;
00972 CArray<uint64_t,2> king8infos_backup;
00973 MobilityTable mobility_backup;
00974 prologueSimple(player, from, to, promoteMask, oldPiece, num, oldPtypeO, newPtypeO,
00975 pin_or_open_backup,
00976 king_mobility_backup,
00977 promoted_backup,
00978 effected_mask_backup, effected_changed_mask_backup,
00979 king8infos_backup,
00980 mobility_backup);
00981 if (promoteMask!=0 && num < PtypeTraits<PAWN>::indexLimit)
00982 {
00983 clearPawn(P,from);
00984 changeTurn();
00985 func(to);
00986 changeTurn();
00987 setPawn(P,from);
00988 }
00989 else
00990 {
00991 changeTurn();
00992 func(to);
00993 changeTurn();
00994 }
00995 epilogueSimple(from, to, oldPiece, num, oldPtypeO, newPtypeO,
00996 pin_or_open_backup,
00997 king_mobility_backup,
00998 promoted_backup, effected_mask_backup, effected_changed_mask_backup,
00999 king8infos_backup,
01000 mobility_backup);
01001 }
01002
01003 template <osl::Player P, typename Function>
01004 void osl::NumEffectState::doUndoDropMove(Player2Type<P> player,
01005 Square to, Ptype ptype, Function& func)
01006 {
01007 Piece oldPiece;
01008 PtypeO ptypeO;
01009 int num, numIndex;
01010 mask_t numMask;
01011 CArray<PieceMask,2> pin_or_open_backup;
01012 KingMobility king_mobility_backup;
01013 CArray<PieceMask,2> effected_mask_backup;
01014 CArray<PieceMask,2> effected_changed_mask_backup;
01015 CArray<uint64_t,2> king8infos_backup;
01016 MobilityTable mobility_backup;
01017 prologueDrop(player, to, ptype, oldPiece, num, ptypeO, numIndex, numMask,
01018 pin_or_open_backup, king_mobility_backup,
01019 effected_mask_backup,effected_changed_mask_backup,
01020 king8infos_backup,
01021 mobility_backup);
01022 if (ptype==PAWN)
01023 {
01024 setPawn(P,to);
01025 changeTurn();
01026 func(to);
01027 changeTurn();
01028 clearPawn(P,to);
01029 }
01030 else
01031 {
01032 changeTurn();
01033 func(to);
01034 changeTurn();
01035 }
01036 epilogueDrop(player, to, ptype, oldPiece, num, ptypeO, numIndex, numMask,
01037 pin_or_open_backup, king_mobility_backup,
01038 effected_mask_backup,effected_changed_mask_backup,
01039 king8infos_backup,
01040 mobility_backup);
01041 }
01042
01043 template <osl::Player P, typename Function>
01044 void osl::NumEffectState::doUndoCaptureMove(Player2Type<P> player,
01045 Square from,Square to, Piece target,
01046 int promoteMask,Function& func)
01047 {
01048 Piece oldPiece;
01049 PtypeO oldPtypeO, capturePtypeO, newPtypeO;
01050 int num0, num1, num1Index;
01051 mask_t num1Mask;
01052 CArray<PieceMask,2> pin_or_open_backup;
01053 KingMobility king_mobility_backup;
01054 PieceMask promoted_backup;
01055 CArray<PieceMask,2> effected_mask_backup;
01056 CArray<PieceMask,2> effected_changed_mask_backup;
01057 CArray<uint64_t,2> king8infos_backup;
01058 MobilityTable mobility_backup;
01059 prologueCapture(player, from, to, target, promoteMask, oldPiece, oldPtypeO,
01060 capturePtypeO, newPtypeO, num0, num1, num1Index,num1Mask,
01061 pin_or_open_backup, king_mobility_backup,
01062 promoted_backup,
01063 effected_mask_backup, effected_changed_mask_backup,
01064 king8infos_backup,
01065 mobility_backup);
01066
01067 changeTurn();
01068 const Ptype capturePtype=target.ptype();
01069 if (capturePtype==PAWN)
01070 {
01071 clearPawn(PlayerTraits<P>::opponent,to);
01072 if (promoteMask!=0 && num0<PtypeTraits<PAWN>::indexLimit)
01073 {
01074 clearPawn(P,from);
01075 func(to);
01076 setPawn(P,from);
01077 }
01078 else
01079 {
01080 func(to);
01081 }
01082 setPawn(PlayerTraits<P>::opponent,to);
01083 }
01084 else if (promoteMask!=0 && num0<PtypeTraits<PAWN>::indexLimit)
01085 {
01086 clearPawn(P,from);
01087 func(to);
01088 setPawn(P,from);
01089 }
01090 else
01091 {
01092 func(to);
01093 }
01094 changeTurn();
01095
01096 epilogueCapture(player, from, to, target, oldPiece, oldPtypeO, capturePtypeO, newPtypeO,
01097 num0, num1, num1Index,num1Mask,
01098 pin_or_open_backup, king_mobility_backup,
01099 promoted_backup,effected_mask_backup, effected_changed_mask_backup,
01100 king8infos_backup,
01101 mobility_backup);
01102 }
01103
01104 template <class Action>
01105 void osl::NumEffectState::
01106 forEachEffectOfPiece(Piece piece,Action & action) const
01107 {
01108 Square pieceSquare = piece.square();
01109 switch ((int)piece.ptypeO()) {
01110 case NEW_PTYPEO(WHITE,PAWN): forEachEffectOfPiece<WHITE,PAWN,Action>(pieceSquare,action); break;
01111 case NEW_PTYPEO(WHITE,LANCE): forEachEffectOfPiece<WHITE,LANCE,Action>(pieceSquare,action); break;
01112 case NEW_PTYPEO(WHITE,KNIGHT): forEachEffectOfPiece<WHITE,KNIGHT,Action>(pieceSquare,action); break;
01113 case NEW_PTYPEO(WHITE,SILVER): forEachEffectOfPiece<WHITE,SILVER,Action>(pieceSquare,action); break;
01114 case NEW_PTYPEO(WHITE,PPAWN): forEachEffectOfPiece<WHITE,PPAWN,Action>(pieceSquare,action); break;
01115 case NEW_PTYPEO(WHITE,PLANCE): forEachEffectOfPiece<WHITE,PLANCE,Action>(pieceSquare,action); break;
01116 case NEW_PTYPEO(WHITE,PKNIGHT): forEachEffectOfPiece<WHITE,PKNIGHT,Action>(pieceSquare,action); break;
01117 case NEW_PTYPEO(WHITE,PSILVER): forEachEffectOfPiece<WHITE,PSILVER,Action>(pieceSquare,action); break;
01118 case NEW_PTYPEO(WHITE,GOLD): forEachEffectOfPiece<WHITE,GOLD,Action>(pieceSquare,action); break;
01119 case NEW_PTYPEO(WHITE,BISHOP): forEachEffectOfPiece<WHITE,BISHOP,Action>(pieceSquare,action); break;
01120 case NEW_PTYPEO(WHITE,PBISHOP): forEachEffectOfPiece<WHITE,PBISHOP,Action>(pieceSquare,action); break;
01121 case NEW_PTYPEO(WHITE,ROOK): forEachEffectOfPiece<WHITE,ROOK,Action>(pieceSquare,action); break;
01122 case NEW_PTYPEO(WHITE,PROOK): forEachEffectOfPiece<WHITE,PROOK,Action>(pieceSquare,action); break;
01123 case NEW_PTYPEO(WHITE,KING): forEachEffectOfPiece<WHITE,KING,Action>(pieceSquare,action); break;
01124 case NEW_PTYPEO(BLACK,PAWN): forEachEffectOfPiece<BLACK,PAWN,Action>(pieceSquare,action); break;
01125 case NEW_PTYPEO(BLACK,LANCE): forEachEffectOfPiece<BLACK,LANCE,Action>(pieceSquare,action); break;
01126 case NEW_PTYPEO(BLACK,KNIGHT): forEachEffectOfPiece<BLACK,KNIGHT,Action>(pieceSquare,action); break;
01127 case NEW_PTYPEO(BLACK,SILVER): forEachEffectOfPiece<BLACK,SILVER,Action>(pieceSquare,action); break;
01128 case NEW_PTYPEO(BLACK,PPAWN): forEachEffectOfPiece<BLACK,PPAWN,Action>(pieceSquare,action); break;
01129 case NEW_PTYPEO(BLACK,PLANCE): forEachEffectOfPiece<BLACK,PLANCE,Action>(pieceSquare,action); break;
01130 case NEW_PTYPEO(BLACK,PKNIGHT): forEachEffectOfPiece<BLACK,PKNIGHT,Action>(pieceSquare,action); break;
01131 case NEW_PTYPEO(BLACK,PSILVER): forEachEffectOfPiece<BLACK,PSILVER,Action>(pieceSquare,action); break;
01132 case NEW_PTYPEO(BLACK,GOLD): forEachEffectOfPiece<BLACK,GOLD,Action>(pieceSquare,action); break;
01133 case NEW_PTYPEO(BLACK,BISHOP): forEachEffectOfPiece<BLACK,BISHOP,Action>(pieceSquare,action); break;
01134 case NEW_PTYPEO(BLACK,PBISHOP): forEachEffectOfPiece<BLACK,PBISHOP,Action>(pieceSquare,action); break;
01135 case NEW_PTYPEO(BLACK,ROOK): forEachEffectOfPiece<BLACK,ROOK,Action>(pieceSquare,action); break;
01136 case NEW_PTYPEO(BLACK,PROOK): forEachEffectOfPiece<BLACK,PROOK,Action>(pieceSquare,action); break;
01137 case NEW_PTYPEO(BLACK,KING): forEachEffectOfPiece<BLACK,KING,Action>(pieceSquare,action); break;
01138 default: assert(0);
01139 }
01140 }
01141
01142 template <osl::Player P, osl::Ptype Type, class Action>
01143 void osl::NumEffectState::
01144 forEachEffectOfPiece(Square pieceSquare,Action & action) const
01145 {
01146 forEachEffectOfPieceDir<P,Type,Action,UL>(pieceSquare,action);
01147 forEachEffectOfPieceDir<P,Type,Action,U>(pieceSquare,action);
01148 forEachEffectOfPieceDir<P,Type,Action,UR>(pieceSquare,action);
01149 forEachEffectOfPieceDir<P,Type,Action,L>(pieceSquare,action);
01150 forEachEffectOfPieceDir<P,Type,Action,R>(pieceSquare,action);
01151 forEachEffectOfPieceDir<P,Type,Action,DL>(pieceSquare,action);
01152 forEachEffectOfPieceDir<P,Type,Action,D>(pieceSquare,action);
01153 forEachEffectOfPieceDir<P,Type,Action,DR>(pieceSquare,action);
01154 forEachEffectOfPieceDir<P,Type,Action,UUL>(pieceSquare,action);
01155 forEachEffectOfPieceDir<P,Type,Action,UUR>(pieceSquare,action);
01156 forEachEffectOfPieceLongDir<P,Type,Action,LONG_UL>(pieceSquare,action);
01157 forEachEffectOfPieceLongDir<P,Type,Action,LONG_U>(pieceSquare,action);
01158 forEachEffectOfPieceLongDir<P,Type,Action,LONG_UR>(pieceSquare,action);
01159 forEachEffectOfPieceLongDir<P,Type,Action,LONG_L>(pieceSquare,action);
01160 forEachEffectOfPieceLongDir<P,Type,Action,LONG_R>(pieceSquare,action);
01161 forEachEffectOfPieceLongDir<P,Type,Action,LONG_DL>(pieceSquare,action);
01162 forEachEffectOfPieceLongDir<P,Type,Action,LONG_D>(pieceSquare,action);
01163 forEachEffectOfPieceLongDir<P,Type,Action,LONG_DR>(pieceSquare,action);
01164 }
01165
01166 #endif
01167
01168
01169
01170