All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
effect_util/pin.h
Go to the documentation of this file.
1 /* pin.h
2  */
3 #ifndef _PIN_H
4 #define _PIN_H
5 
8 #include <boost/static_assert.hpp>
9 namespace osl
10 {
11  namespace effect_util
12  {
13 
14  class PinOrOpen
15  {
16  private:
20  template <Player Defense,Direction DIR>
21  static void findDirectionStep(const NumEffectState& state, Square target,
22  PieceMask& pins, PieceMask const& onBoard)
23  {
25  Square pos=target-offset;
26  int num;
27  while(Piece::isEmptyNum(num=state.pieceAt(pos).number()))
28  pos-=offset;
29  if(Piece::isEdgeNum(num)) return;
30  int num1=state.longEffectNumTable()[num][DIR];
31  if(Piece::isPieceNum(num1) && onBoard.test(num1)){
32  pins.set(num);
33  }
34  }
35  public:
36  template<Player Defense>
37  static PieceMask makeStep(const NumEffectState& state, Square target)
38  {
39  PieceMask pins;
40  PieceMask mask=state.piecesOnBoard(alt(Defense));
41  findDirectionStep<Defense,UL>(state,target,pins,mask);
42  findDirectionStep<Defense,U>(state,target,pins,mask);
43  findDirectionStep<Defense,UR>(state,target,pins,mask);
44  findDirectionStep<Defense,L>(state,target,pins,mask);
45  findDirectionStep<Defense,R>(state,target,pins,mask);
46  findDirectionStep<Defense,DL>(state,target,pins,mask);
47  findDirectionStep<Defense,D>(state,target,pins,mask);
48  findDirectionStep<Defense,DR>(state,target,pins,mask);
49  return pins;
50  }
51 
52  static PieceMask makeStep(const NumEffectState& state, Square target,
53  Player defense)
54  {
55  if(defense==BLACK)
56  return makeStep<BLACK>(state,target);
57  else
58  return makeStep<WHITE>(state,target);
59  }
60  static PieceMask make(const NumEffectState& state,Player defense)
61  {
62  return makeStep(state,state.kingSquare<BLACK>(),defense);
63  }
64  };
69  class Pin
70  {
71  private:
72  template <Direction DIR>
73  static void findDirection(const SimpleState& state, Square target,
74  Player defense, PieceMask& pins)
75  {
76  const Offset diff = Board_Table.getOffset(defense, DIR);
77  const Piece pin = state.nextPiece(target, diff);
78  if(!pin.isOnBoardByOwner(defense)) return;
79  const Piece attack_piece = state.nextPiece(pin.square(), diff);
80  if(!attack_piece.isOnBoardByOwner(alt(defense))) return;
81  if (Ptype_Table.getMoveMask(attack_piece.ptype())
83  pins.set(pin.number());
84  }
90  template<Player P>
91  static void findLance(const NumEffectState& state, Square target,
92  PieceMask& pins)
93  {
94  assert(target==state.kingSquare<P>());
96  Square pos = target+diff;
97  Piece pin;
98  while ((pin=state.pieceAt(pos)) == Piece::EMPTY())
99  pos += diff;
100  if (! pin.isOnBoardByOwner<P>() )
101  return;
102  NumBitmapEffect effect=state.effectSetAt(pos);
103  mask_t mask=(effect.getMask(1)&mask_t::makeDirect(PtypeFuns<LANCE>::indexMask<<8));
104  if(mask.any()){
105  pins.set(pin.number());
106  }
107  }
108  public:
113  static PieceMask makeNaive(const SimpleState& state, Square target,
114  Player defense);
115  private:
116  static bool hasEffectWithOffset(const SimpleState& state,
117  Piece attack_piece, Piece pin, Offset diff)
118  {
119  const Piece attack_piece2 = state.nextPiece(pin.square(), diff);
120  return attack_piece == attack_piece2;
121  }
122  static bool hasEffectWithOffset(const NumEffectState& state,
123  Piece attack_piece, Piece pin, Offset)
124  {
125  return state.hasEffectByPiece(attack_piece, pin.square());
126  }
127  static void findOffset(const NumEffectState& state,
128  Piece attack_piece, Square target,
129  Player defense, Offset diff, PieceMask& pins)
130  {
131  const Piece pin = state.nextPiece(target, diff);
132  assert(pin.isPiece());
133  if (pin.owner() != defense)
134  return;
135  if (! hasEffectWithOffset(state, attack_piece, pin, diff))
136  return;
137  pins.set(pin.number());
138  }
139  template <Ptype PTYPE>
140  static void findPtype(const NumEffectState& state, Square target,
141  Player attack, Player defense, PieceMask& result)
142  {
143  BOOST_STATIC_ASSERT((PTYPE == ROOK) || (PTYPE == BISHOP));
144  const PtypeO attack_ptypeo = newPtypeO(attack, PTYPE);
145  for (int i=PtypeTraits<PTYPE>::indexMin;
146  i < PtypeTraits<PTYPE>::indexLimit; ++i)
147  {
148  const Piece attack_piece = state.pieceOf(i);
149  if (attack_piece.isOnBoardByOwner(attack))
150  {
151  const Square attack_position = attack_piece.square();
152  const Offset32 diff(attack_position, target);
153  const EffectContent effect
154  = Ptype_Table.getEffect(attack_ptypeo, diff);
155  if (!effect.hasBlockableEffect()) // 利きはあるか
156  continue;
157  const Offset offset = effect.offset();
158 #if 0
159  if (offset.zero()) // 隣にいる場合: pin はない
160  continue;
161 #endif
162  findOffset(state, attack_piece, target, defense,
163  offset, result);
164  }
165  }
166  }
167  public:
172  static PieceMask makeByPiece(const NumEffectState& state, Square target,
173  Player defense);
174 
179  static PieceMask makeByPieceKing(const NumEffectState& state, Square target,
180  Player defense);
181 
185  template <Player Defense,Direction DIR>
186  static void findDirectionStep(const NumEffectState& state, Square target,
187  PieceMask& pins)
188  {
189  const Offset offset = DirectionTraits<DIR>::blackOffset();
190  Square pos=target-offset;
191  int num;
192  while(Piece::isEmptyNum(num=state.pieceAt(pos).number()))
193  pos-=offset;
194  if(Piece::isEdgeNum(num)) return;
195  if(Defense==BLACK){
196  if(!state.pieceAt(pos).pieceIsBlack()) return;
197  }
198  else{
199  if(state.pieceAt(pos).pieceIsBlack()) return;
200  }
201  int num1=state.longEffectNumTable()[num][DIR];
202  if(!Piece::isPieceNum(num1)) return;
203  if(Defense==BLACK){
204  if(!state.pieceOf(num1).pieceIsBlack())
205  pins.set(num);
206  }
207  else{
208  if(state.pieceOf(num1).pieceIsBlack())
209  pins.set(num);
210  }
211  }
212  template<Player Defense>
213  static PieceMask makeStep(const NumEffectState& state, Square target)
214  {
215  PieceMask pins;
216  findDirectionStep<Defense,UL>(state,target,pins);
217  findDirectionStep<Defense,U>(state,target,pins);
218  findDirectionStep<Defense,UR>(state,target,pins);
219  findDirectionStep<Defense,L>(state,target,pins);
220  findDirectionStep<Defense,R>(state,target,pins);
221  findDirectionStep<Defense,DL>(state,target,pins);
222  findDirectionStep<Defense,D>(state,target,pins);
223  findDirectionStep<Defense,DR>(state,target,pins);
224  return pins;
225  }
226 
227  static PieceMask makeStep(const NumEffectState& state, Square target,
228  Player defense)
229  {
230  if(defense==BLACK)
231  return makeStep<BLACK>(state,target);
232  else
233  return makeStep<WHITE>(state,target);
234  }
235  template<Player Defense>
236  static PieceMask makeStep1(const NumEffectState& state, Square target)
237  {
238  PieceMask pins=PinOrOpen::makeStep<Defense>(state,target);;
239  pins &= state.piecesOnBoard(Defense);
240  return pins;
241  }
242 
243  static PieceMask makeStep1(const NumEffectState& state, Square target,
244  Player defense)
245  {
246  if(defense==BLACK)
247  return makeStep1<BLACK>(state,target);
248  else
249  return makeStep1<WHITE>(state,target);
250  }
257  static PieceMask make(const NumEffectState& state, Square target,
258  Player defense)
259  {
260  return makeByPiece(state, target, defense);
261  }
265  static PieceMask make(const NumEffectState& state, Player defense)
266  {
267  return makeByPiece(state, defense);
268  }
269  static PieceMask makeNaive(const SimpleState& state, Player defense)
270  {
271  return makeNaive(state, state.kingSquare(defense), defense);
272  }
273  static PieceMask makeByPiece(const NumEffectState& state, Player defense)
274  {
275  return makeByPieceKing(state, state.kingSquare(defense), defense);
276  }
280  static int count(const NumEffectState& state, Player defense)
281  {
282  const PieceMask pins = make(state, defense);
283  return pins.countBit();
284  }
285  static int count(const NumEffectState& state, Square target,
286  Player defense)
287  {
288  const PieceMask pins = make(state, target, defense);
289  return pins.countBit();
290  }
291  };
292 
293 
294  } // namespace effect_util
295 } // namespace osl
296 
297 #endif /* _PIN_H */
298 // ;;; Local Variables:
299 // ;;; mode:c++
300 // ;;; c-basic-offset:2
301 // ;;; End: