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       }
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       // 2. 駒に関する情報
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       // 3. あるSquareへの利き
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       // 3.1 集合を返す
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       // 3.2 bool を返す
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       // 3.3 pieceを探す
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       // 4. 指手
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       // 5. forEachXXX
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           // reset old pins
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   } // namespace state
00951   using state::NumEffectState;
00952 } // namespace osl
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 /* OSL_NUM_EFFECT_STATE_H */
01162 // ;;; Local Variables:
01163 // ;;; mode:c++
01164 // ;;; c-basic-offset:2
01165 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines