liberty8.h
Go to the documentation of this file.
00001 /* liberty8.h
00002  */
00003 #ifndef _LIBERTY8_H
00004 #define _LIBERTY8_H
00005 
00006 #include "osl/effect/liberty8Table.h"
00007 #include "osl/direction.h"
00008 #include "osl/piece.h"
00009 #include "osl/ptypeList.h"
00010 #include "osl/container/nearMask.h"
00011 #include <boost/type_traits.hpp>
00012 #include <iosfwd>
00013 namespace osl
00014 {
00015   namespace effect
00016   {
00021     template<typename Liberty,Player P,Ptype T>
00022     class AddMaskAction{
00023       Liberty & liberty;
00024       NumEffectState const& state;
00025       const Square target;
00026       const NearMask nearMask;
00027     public:
00028       AddMaskAction(Liberty& l,NumEffectState const& s,Square t,NearMask n) 
00029         : liberty(l), state(s), target(t), nearMask(n)
00030       {
00031       }
00032       void operator()(Piece p){
00033 #if 1
00034         const Square from=p.square();
00035         const NearMask shortMask = Liberty8_Table.
00036           getShortMask<PlayerTraits<P>::opponent>(p.ptype(), from, target);
00037         liberty.andMask(shortMask);
00038         if(PtypeFuns<T>::hasLongMove &&
00039            (T!=LANCE || !p.isPromotedNotKingGold())){
00040           LongEffect8 longEffect8=
00041             Liberty8_Table.
00042             getLongEffect<PlayerTraits<P>::opponent>(p.ptype(),
00043                                                      p.square(),
00044                                                      target);
00045           Offset offset=longEffect8.getOffset();
00046           if(offset.zero()) return;
00047           // これが引き算で良いかどうかまだ気になる
00048           if(state.isEmptyBetween(from,target-offset.blackOffset<P>())){
00049             unsigned int nearMaskSpace=nearMask.spaceMask();
00050             unsigned int mask0=longEffect8.getMask(0);
00051             liberty.andMask(NearMask::makeDirect(~mask0));
00052             if((mask0&nearMaskSpace)!=0){
00053               unsigned int mask1=longEffect8.getMask(1);
00054               liberty.andMask(NearMask::makeDirect(~mask1));
00055               if( T!=BISHOP && (mask1&nearMaskSpace)!=0){
00056                 unsigned int mask2=longEffect8.getMask(2);
00057                 liberty.andMask(NearMask::makeDirect(~mask2));
00058               }
00059             }
00060           }
00061         }
00062         if(T==ROOK){
00063           LongEffect8 longEffect8=
00064             Liberty8_Table.
00065             getLongEffect2<PlayerTraits<P>::opponent>(p.square(),
00066                                                       target);
00067           unsigned int mask0=longEffect8.getMask(0);
00068           if(mask0==0) return;
00069           unsigned int nearMaskSpace=nearMask.spaceMask();
00070           liberty.andMask(NearMask::makeDirect(~mask0));
00071           if((mask0&nearMaskSpace)==0) return;
00072           unsigned int mask1=longEffect8.getMask(1);
00073           liberty.andMask(NearMask::makeDirect(~mask1));
00074         }
00075 #else
00076 
00079         for(int i=0;i<8;i++){
00080           Direction dir=static_cast<Direction>(i);
00081           Square to=target-Board_Table.getOffset<P>(dir);
00082           if(to.isOnBoard() && 
00083              state.hasEffectTo(p,to))
00084             liberty.andMask(~(1<<i));
00085         }
00086         if(state.hasEffectTo(p,target)){
00087           Direction longDirection=
00088             Board_Table.getLongDirection<P>(target,p.square());
00089           // 駒がある方向に長い利きをもっていて
00090           // かつ逆方向に短い利きを持っていることはないので,
00091           // これで良いことにする
00092           if(Ptype_Table.getMoveMask(p.ptype())&dirToMask(longDirection)){
00093             liberty.andMask(~(1<<longToShort(longDirection)));
00094           }
00095         }
00096 #endif      
00097       }
00098     };
00099 
00108     template<Player P>
00109     class Liberty8
00110     {
00113       NearMask mask;
00114     
00115       template<Ptype T>
00116       void addMaskPtype(NumEffectState const& state,Square target,NearMask nearMask){
00117         typedef AddMaskAction<Liberty8<P>,P,T> action_t;
00118         action_t action(*this,state,target,nearMask);
00119         state.template
00120           forEachOnBoard<PlayerTraits<P>::opponent,T,action_t>(action);
00121       }
00122 
00123       template<typename U>
00124       void addMask(NumEffectState const& state,Square target,NearMask nearMask,U);
00125 
00126       void addMask(NumEffectState const&, Square, NearMask, ptl::NullPtype){}
00127 
00128       template<Ptype T,typename Tail>
00129       void addMask(NumEffectState const& state,Square target,NearMask nearMask,ptl::PtypeList<T,Tail>){
00130         addMaskPtype<T>(state,target,nearMask);
00131         addMask(state,target,nearMask,Tail());
00132       }
00133 
00134     public:
00135       Liberty8(NumEffectState const& state,Square target);
00136       void andMask(NearMask m){
00137         mask&=m;
00138       }
00139       NearMask getMask() const{
00140         return mask;
00141       }
00145       int count() const{
00146         int ret=0;
00147         for (int i=0;i<8;i++)
00148           if (mask.isSet(i))
00149             ret++;
00150         return ret;
00151       }
00152     };
00153     template<Player P>
00154     std::ostream& operator<<(std::ostream& os,Liberty8<P> const& liberty);
00155   } // namespace effect
00156 } // namespace osl
00157 
00158 template<osl::Player P>
00159 osl::effect::
00160 Liberty8<P>::Liberty8(NumEffectState const& state, Square target)
00161 {
00165   assert(state.pieceAt(target).template isOnBoardByOwner<P>());
00170   NearMask nearMask=NearMask::make<P>(state,target);
00175   mask = NearMask::makeDirect(nearMask.uintValue() & 0xff);
00176   addMask(state,target,nearMask,ptl::PtypeListIsBasic());
00177 }
00178 
00179 #endif /* _LIBERTY8_H */
00180 // ;;; Local Variables:
00181 // ;;; mode:c++
00182 // ;;; c-basic-offset:2
00183 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines