00001
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 }
00156 }
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
00180
00181
00182
00183