numEffectState.h
Go to the documentation of this file.
00001 /* numEffectState.h
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       // 0. 将棋以外の操作
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       // 1. 盤面全体の情報
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       // 2. 駒に関する情報
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       // 3. あるSquareへの利き
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       // 3.1 集合を返す
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       // 3.2 bool を返す
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       // 3.3 pieceを探す
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       // 4. 指手
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       // 5. forEachXXX
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           // reset old pins
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   } // namespace state
00956   using state::NumEffectState;
00957 } // namespace osl
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 /* OSL_NUM_EFFECT_STATE_H */
01167 // ;;; Local Variables:
01168 // ;;; mode:c++
01169 // ;;; c-basic-offset:2
01170 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines