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,typename State,Player P,Ptype T>
00022 class AddMaskAction{
00023 Liberty & liberty;
00024 State const& state;
00025 const Position target;
00026 const NearMask nearMask;
00027 public:
00028 AddMaskAction(Liberty& l,State const& s,Position t,NearMask n)
00029 : liberty(l), state(s), target(t), nearMask(n)
00030 {
00031 }
00032 void operator()(Piece p){
00033 #if 1
00034 const Position from=p.position();
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.position(),
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.position(),
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 Position 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.position());
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<typename State,Ptype T>
00116 void addMaskPtype(State const& state,Position target,NearMask nearMask){
00117 typedef AddMaskAction<Liberty8<P>,State,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 State,typename U>
00124 void addMask(State const& state,Position target,NearMask nearMask,U);
00125
00126 template<typename State>
00127 void addMask(State const&, Position, NearMask, ptl::NullPtype){}
00128
00129 template<typename State,Ptype T,typename Tail>
00130 void addMask(State const& state,Position target,NearMask nearMask,ptl::PtypeList<T,Tail>){
00131 addMaskPtype<State,T>(state,target,nearMask);
00132 addMask(state,target,nearMask,Tail());
00133 }
00134
00135 public:
00136 template<typename State>
00137 Liberty8(State const& state,Position target);
00138 void andMask(NearMask m){
00139 mask&=m;
00140 }
00141 NearMask getMask() const{
00142 return mask;
00143 }
00147 int count() const{
00148 int ret=0;
00149 for (int i=0;i<8;i++)
00150 if (mask.isSet(i))
00151 ret++;
00152 return ret;
00153 }
00154 };
00155 template<Player P>
00156 std::ostream& operator<<(std::ostream& os,Liberty8<P> const& liberty);
00157 }
00158 }
00159
00160 template<osl::Player P>
00161 template<typename State>
00162 osl::effect::
00163 Liberty8<P>::Liberty8(State const& state, Position target)
00164 {
00165 BOOST_STATIC_ASSERT(! boost::is_pointer<State>::value);
00169 assert(state.getPieceAt(target).template isOnBoardByOwner<P>());
00174 NearMask nearMask=NearMask::make<State,P>(state,target);
00179 mask = NearMask::makeDirect(nearMask.uintValue() & 0xff);
00180 addMask(state,target,nearMask,ptl::PtypeListIsBasic());
00181 }
00182
00183 #endif
00184
00185
00186
00187