All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
liberty8.h
Go to the documentation of this file.
1 /* liberty8.h
2  */
3 #ifndef _LIBERTY8_H
4 #define _LIBERTY8_H
5 
7 #include "osl/direction.h"
8 #include "osl/piece.h"
9 #include "osl/ptypeList.h"
10 #include "osl/container/nearMask.h"
11 #include <boost/type_traits.hpp>
12 #include <iosfwd>
13 namespace osl
14 {
15  namespace effect
16  {
21  template<typename Liberty,Player P,Ptype T>
23  Liberty & liberty;
24  NumEffectState const& state;
25  const Square target;
26  const NearMask nearMask;
27  public:
28  AddMaskAction(Liberty& l,NumEffectState const& s,Square t,NearMask n)
29  : liberty(l), state(s), target(t), nearMask(n)
30  {
31  }
32  void operator()(Piece p){
33 #if 1
34  const Square from=p.square();
35  const NearMask shortMask = Liberty8_Table.
36  getShortMask<PlayerTraits<P>::opponent>(p.ptype(), from, target);
37  liberty.andMask(shortMask);
39  (T!=LANCE || !p.isPromotedNotKingGold())){
40  LongEffect8 longEffect8=
42  getLongEffect<PlayerTraits<P>::opponent>(p.ptype(),
43  p.square(),
44  target);
45  Offset offset=longEffect8.getOffset();
46  if(offset.zero()) return;
47  // これが引き算で良いかどうかまだ気になる
48  if(state.isEmptyBetween(from,target-offset.blackOffset<P>())){
49  unsigned int nearMaskSpace=nearMask.spaceMask();
50  unsigned int mask0=longEffect8.getMask(0);
51  liberty.andMask(NearMask::makeDirect(~mask0));
52  if((mask0&nearMaskSpace)!=0){
53  unsigned int mask1=longEffect8.getMask(1);
54  liberty.andMask(NearMask::makeDirect(~mask1));
55  if( T!=BISHOP && (mask1&nearMaskSpace)!=0){
56  unsigned int mask2=longEffect8.getMask(2);
57  liberty.andMask(NearMask::makeDirect(~mask2));
58  }
59  }
60  }
61  }
62  if(T==ROOK){
63  LongEffect8 longEffect8=
65  getLongEffect2<PlayerTraits<P>::opponent>(p.square(),
66  target);
67  unsigned int mask0=longEffect8.getMask(0);
68  if(mask0==0) return;
69  unsigned int nearMaskSpace=nearMask.spaceMask();
70  liberty.andMask(NearMask::makeDirect(~mask0));
71  if((mask0&nearMaskSpace)==0) return;
72  unsigned int mask1=longEffect8.getMask(1);
73  liberty.andMask(NearMask::makeDirect(~mask1));
74  }
75 #else
76 
79  for(int i=0;i<8;i++){
80  Direction dir=static_cast<Direction>(i);
82  if(to.isOnBoard() &&
83  state.hasEffectTo(p,to))
84  liberty.andMask(~(1<<i));
85  }
86  if(state.hasEffectTo(p,target)){
87  Direction longDirection=
89  // 駒がある方向に長い利きをもっていて
90  // かつ逆方向に短い利きを持っていることはないので,
91  // これで良いことにする
92  if(Ptype_Table.getMoveMask(p.ptype())&dirToMask(longDirection)){
93  liberty.andMask(~(1<<longToShort(longDirection)));
94  }
95  }
96 #endif
97  }
98  };
99 
108  template<Player P>
109  class Liberty8
110  {
113  NearMask mask;
114 
115  template<Ptype T>
116  void addMaskPtype(NumEffectState const& state,Square target,NearMask nearMask){
117  typedef AddMaskAction<Liberty8<P>,P,T> action_t;
118  action_t action(*this,state,target,nearMask);
119  state.template
120  forEachOnBoard<PlayerTraits<P>::opponent,T,action_t>(action);
121  }
122 
123  template<typename U>
124  void addMask(NumEffectState const& state,Square target,NearMask nearMask,U);
125 
126  void addMask(NumEffectState const&, Square, NearMask, ptl::NullPtype){}
127 
128  template<Ptype T,typename Tail>
129  void addMask(NumEffectState const& state,Square target,NearMask nearMask,ptl::PtypeList<T,Tail>){
130  addMaskPtype<T>(state,target,nearMask);
131  addMask(state,target,nearMask,Tail());
132  }
133 
134  public:
135  Liberty8(NumEffectState const& state,Square target);
136  void andMask(NearMask m){
137  mask&=m;
138  }
139  NearMask getMask() const{
140  return mask;
141  }
145  int count() const{
146  int ret=0;
147  for (int i=0;i<8;i++)
148  if (mask.isSet(i))
149  ret++;
150  return ret;
151  }
152  };
153  template<Player P>
154  std::ostream& operator<<(std::ostream& os,Liberty8<P> const& liberty);
155  } // namespace effect
156 } // namespace osl
157 
158 template<osl::Player P>
160 Liberty8<P>::Liberty8(NumEffectState const& state, Square target)
161 {
165  assert(state.pieceAt(target).template isOnBoardByOwner<P>());
170  NearMask nearMask=NearMask::make<P>(state,target);
175  mask = NearMask::makeDirect(nearMask.uintValue() & 0xff);
176  addMask(state,target,nearMask,ptl::PtypeListIsBasic());
177 }
178 
179 #endif /* _LIBERTY8_H */
180 // ;;; Local Variables:
181 // ;;; mode:c++
182 // ;;; c-basic-offset:2
183 // ;;; End: