pin.h
Go to the documentation of this file.
00001 /* pin.h
00002  */
00003 #ifndef _PIN_H
00004 #define _PIN_H
00005 
00006 #include "osl/state/numEffectState.h"
00007 #include "osl/container/pieceMask.h"
00008 #include <boost/static_assert.hpp>
00009 namespace osl
00010 {
00011   namespace effect_util
00012   {
00013 
00014     class PinOrOpen
00015     {
00016     private:
00020       template <Player Defense,Direction DIR>
00021       static void findDirectionStep(const NumEffectState& state, Square target,
00022                                     PieceMask& pins, PieceMask const& onBoard)
00023       {
00024         const Offset offset = DirectionTraits<DIR>::blackOffset();
00025         Square pos=target-offset;
00026         int num;
00027         while(Piece::isEmptyNum(num=state.pieceAt(pos).number()))
00028           pos-=offset;
00029         if(Piece::isEdgeNum(num)) return;
00030         int num1=state.longEffectNumTable()[num][DIR];
00031         if(Piece::isPieceNum(num1) && onBoard.test(num1)){
00032           pins.set(num);
00033         }
00034       }
00035     public:
00036       template<Player Defense>
00037       static PieceMask makeStep(const NumEffectState& state, Square target)
00038       {
00039         PieceMask pins;
00040         PieceMask mask=state.piecesOnBoard(alt(Defense));
00041         findDirectionStep<Defense,UL>(state,target,pins,mask);
00042         findDirectionStep<Defense,U>(state,target,pins,mask);
00043         findDirectionStep<Defense,UR>(state,target,pins,mask);
00044         findDirectionStep<Defense,L>(state,target,pins,mask);
00045         findDirectionStep<Defense,R>(state,target,pins,mask);
00046         findDirectionStep<Defense,DL>(state,target,pins,mask);
00047         findDirectionStep<Defense,D>(state,target,pins,mask);
00048         findDirectionStep<Defense,DR>(state,target,pins,mask);
00049         return pins;
00050       }
00051 
00052       static PieceMask makeStep(const NumEffectState& state, Square target, 
00053                                        Player defense)
00054       {
00055         if(defense==BLACK)
00056           return makeStep<BLACK>(state,target);
00057         else
00058           return makeStep<WHITE>(state,target);
00059       }
00060       static PieceMask make(const NumEffectState& state,Player defense)
00061       {
00062         return makeStep(state,state.kingSquare<BLACK>(),defense);
00063       }
00064     };
00069     class Pin
00070     {
00071     private:
00072       template <Direction DIR>
00073       static void findDirection(const SimpleState& state, Square target,
00074                                 Player defense, PieceMask& pins)
00075       {
00076         const Offset diff = Board_Table.getOffset(defense, DIR);
00077         const Piece pin = state.nextPiece(target, diff);
00078         if(!pin.isOnBoardByOwner(defense)) return;
00079         const Piece attack_piece = state.nextPiece(pin.square(), diff);
00080         if(!attack_piece.isOnBoardByOwner(alt(defense))) return;
00081         if (Ptype_Table.getMoveMask(attack_piece.ptype())
00082             & DirectionTraits<DirectionTraits<DIR>::longDir>::mask)
00083           pins.set(pin.number());
00084       }
00090       template<Player P>
00091       static void findLance(const NumEffectState& state, Square target,
00092                             PieceMask& pins)
00093       {
00094         assert(target==state.kingSquare<P>());
00095         const Offset diff = DirectionPlayerTraits<U,P>::offset();
00096         Square pos = target+diff;
00097         Piece pin;
00098         while ((pin=state.pieceAt(pos)) == Piece::EMPTY())
00099           pos += diff;
00100         if (! pin.isOnBoardByOwner<P>() )
00101           return;
00102         NumBitmapEffect effect=state.effectSetAt(pos);
00103         mask_t mask=(effect.getMask(1)&mask_t::makeDirect(PtypeFuns<LANCE>::indexMask<<8));
00104         if(mask.any()){
00105           pins.set(pin.number());
00106         }
00107       }
00108     public:
00113       static PieceMask makeNaive(const SimpleState& state, Square target, 
00114                                  Player defense);
00115     private:
00116       static bool hasEffectWithOffset(const SimpleState& state, 
00117                                       Piece attack_piece, Piece pin, Offset diff)
00118       {
00119         const Piece attack_piece2 = state.nextPiece(pin.square(), diff);
00120         return attack_piece == attack_piece2;
00121       }
00122       static bool hasEffectWithOffset(const NumEffectState& state, 
00123                                       Piece attack_piece, Piece pin, Offset)
00124       {
00125         return state.hasEffectByPiece(attack_piece, pin.square());
00126       }
00127       static void findOffset(const NumEffectState& state, 
00128                              Piece attack_piece, Square target, 
00129                              Player defense, Offset diff, PieceMask& pins)
00130       {
00131         const Piece pin = state.nextPiece(target, diff);
00132         assert(pin.isPiece());
00133         if (pin.owner() != defense)
00134           return;
00135         if (! hasEffectWithOffset(state, attack_piece, pin, diff))
00136           return;
00137         pins.set(pin.number());
00138       }
00139       template <Ptype PTYPE>
00140       static void findPtype(const NumEffectState& state, Square target, 
00141                             Player attack, Player defense, PieceMask& result)
00142       {
00143         BOOST_STATIC_ASSERT((PTYPE == ROOK) || (PTYPE == BISHOP));
00144         const PtypeO attack_ptypeo = newPtypeO(attack, PTYPE);
00145         for (int i=PtypeTraits<PTYPE>::indexMin; 
00146              i < PtypeTraits<PTYPE>::indexLimit; ++i)
00147         {
00148           const Piece attack_piece = state.pieceOf(i);
00149           if (attack_piece.isOnBoardByOwner(attack))
00150           {
00151             const Square attack_position = attack_piece.square();
00152             const Offset32 diff(attack_position, target);
00153             const EffectContent effect 
00154               = Ptype_Table.getEffect(attack_ptypeo, diff);
00155             if (!effect.hasBlockableEffect()) // 利きはあるか
00156               continue;
00157             const Offset offset = effect.offset();
00158 #if 0
00159             if (offset.zero())  // 隣にいる場合: pin はない
00160               continue;
00161 #endif
00162             findOffset(state, attack_piece, target, defense, 
00163                             offset, result);
00164           }
00165         }
00166       }
00167     public:
00172       static PieceMask makeByPiece(const NumEffectState& state, Square target, 
00173                                    Player defense);
00174 
00179       static PieceMask makeByPieceKing(const NumEffectState& state, Square target, 
00180                                        Player defense);
00181 
00185       template <Player Defense,Direction DIR>
00186       static void findDirectionStep(const NumEffectState& state, Square target,
00187                                     PieceMask& pins)
00188       {
00189         const Offset offset = DirectionTraits<DIR>::blackOffset();
00190         Square pos=target-offset;
00191         int num;
00192         while(Piece::isEmptyNum(num=state.pieceAt(pos).number()))
00193           pos-=offset;
00194         if(Piece::isEdgeNum(num)) return;
00195         if(Defense==BLACK){
00196           if(!state.pieceAt(pos).pieceIsBlack()) return;
00197         }
00198         else{
00199           if(state.pieceAt(pos).pieceIsBlack()) return;
00200         }
00201         int num1=state.longEffectNumTable()[num][DIR];
00202         if(!Piece::isPieceNum(num1)) return;
00203         if(Defense==BLACK){
00204           if(!state.pieceOf(num1).pieceIsBlack())
00205             pins.set(num);
00206         }
00207         else{
00208           if(state.pieceOf(num1).pieceIsBlack())
00209             pins.set(num);
00210         }
00211       }
00212       template<Player Defense>
00213       static PieceMask makeStep(const NumEffectState& state, Square target)
00214       {
00215         PieceMask pins;
00216         findDirectionStep<Defense,UL>(state,target,pins);
00217         findDirectionStep<Defense,U>(state,target,pins);
00218         findDirectionStep<Defense,UR>(state,target,pins);
00219         findDirectionStep<Defense,L>(state,target,pins);
00220         findDirectionStep<Defense,R>(state,target,pins);
00221         findDirectionStep<Defense,DL>(state,target,pins);
00222         findDirectionStep<Defense,D>(state,target,pins);
00223         findDirectionStep<Defense,DR>(state,target,pins);
00224         return pins;
00225       }
00226 
00227       static PieceMask makeStep(const NumEffectState& state, Square target, 
00228                                        Player defense)
00229       {
00230         if(defense==BLACK)
00231           return makeStep<BLACK>(state,target);
00232         else
00233           return makeStep<WHITE>(state,target);
00234       }
00235       template<Player Defense>
00236       static PieceMask makeStep1(const NumEffectState& state, Square target)
00237       {
00238         PieceMask pins=PinOrOpen::makeStep<Defense>(state,target);;
00239         pins &= state.piecesOnBoard(Defense);
00240         return pins;
00241       }
00242 
00243       static PieceMask makeStep1(const NumEffectState& state, Square target, 
00244                                        Player defense)
00245       {
00246         if(defense==BLACK)
00247           return makeStep1<BLACK>(state,target);
00248         else
00249           return makeStep1<WHITE>(state,target);
00250       }
00257       static PieceMask make(const NumEffectState& state, Square target, 
00258                             Player defense)
00259       {
00260         return makeByPiece(state, target, defense);
00261       }
00265       static PieceMask make(const NumEffectState& state, Player defense)
00266       {
00267         return makeByPiece(state, defense);
00268       }
00269       static PieceMask makeNaive(const SimpleState& state, Player defense)
00270       {
00271         return makeNaive(state, state.kingSquare(defense), defense);
00272       }
00273       static PieceMask makeByPiece(const NumEffectState& state, Player defense)
00274       {
00275         return makeByPieceKing(state, state.kingSquare(defense), defense);
00276       }
00280       static int count(const NumEffectState& state, Player defense)
00281       {
00282         const PieceMask pins = make(state, defense);
00283         return pins.countBit();
00284       }
00285       static int count(const NumEffectState& state, Square target, 
00286                        Player defense)
00287       {
00288         const PieceMask pins = make(state, target, defense);
00289         return pins.countBit();
00290       }
00291     };
00292     
00293     
00294   } // namespace effect_util
00295 } // namespace osl
00296 
00297 #endif /* _PIN_H */
00298 // ;;; Local Variables:
00299 // ;;; mode:c++
00300 // ;;; c-basic-offset:2
00301 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines