My Project
numEffectState.tcc
Go to the documentation of this file.
1 /* numEffectState.tcc
2  */
3 #ifndef OSL_NUM_EFFECT_STATE_TCC
4 #define OSL_NUM_EFFECT_STATE_TCC
5 
6 #include "osl/numEffectState.h"
7 #include "osl/move_classifier/kingOpenMove.h"
8 #include "osl/bits/numSimpleEffect.tcc"
9 
10 template <osl::Player P>
11 bool osl::NumEffectState::
12 hasEffectByWithRemove(Square target,Square removed) const
13 {
14  const Piece piece = pieceAt(removed);
15  if (! piece.isPiece())
16  return hasEffectAt<P>(target);
17  if (piece.owner() == P)
18  {
19  if (hasEffectNotBy(P, piece, target))
20  return true;
21  }
22  else
23  {
24  if (hasEffectAt(P, target))
25  return true;
26  }
27  if (! longEffectAt(removed, P).any())
28  return false;
29  const Direction d = Board_Table.getLongDirection<BLACK>(Offset32(target,removed));
30  if (!isLong(d))
31  return false;
32  const int num=longEffectNumTable()[piece.number()][longToShort(d)];
33  return (! Piece::isEmptyNum(num)
34  && pieceOf(num).owner()==P);
35 }
36 
37 namespace osl
38 {
39  template <osl::Player P, bool InterestEmpty, Direction Dir>
40  struct TestEffectOfMove
41  {
42  template <class State, class Function>
43  static void testShort(const State& s, int mask, Square from,
44  Function& f) {
45  static_assert(! DirectionTraits<Dir>::isLong, "Dir");
46  if (! (mask & DirectionTraits<Dir>::mask))
47  return;
48 
49  const Offset offset = DirectionPlayerTraits<Dir,P>::offset();
50  const Square target = from+offset;
51  const Piece piece = s.pieceAt(target);
52  if (piece.isEdge())
53  return;
54  if (InterestEmpty || (! piece.isEmpty()))
55  f(target);
56  }
57  template <class State, class Function>
58  static void testLong(const State& s, int mask, Square from,
59  Function& f) {
60  static_assert(DirectionTraits<Dir>::isLong, "Dir");
61  if (! (mask & DirectionTraits<Dir>::mask))
62  return;
63 
64  const Offset offset = DirectionPlayerTraits<Dir,P>::offset();
65 
66  Square target = from+offset;
67  Piece piece = s.pieceAt(target);
68  while (piece.isEmpty()) {
69  if (InterestEmpty)
70  f(target);
71  target = target+offset;
72  piece = s.pieceAt(target);
73  }
74  if (piece.isPiece()) {
75  f(target);
76  }
77  }
78  };
79  struct SafeCapture
80  {
81  public:
82  const NumEffectState& state;
83  Piece safe_one;
84  SafeCapture(const NumEffectState& s) : state(s), safe_one(Piece::EMPTY()) {
85  }
86  template <Player P>
87  void doAction(Piece effect_piece, Square target) {
88  if (move_classifier::KingOpenMove<P>::isMember
89  (state, effect_piece.ptype(), effect_piece.square(), target))
90  return;
91  safe_one = effect_piece;
92  }
93  };
94 } // namespace osl
95 
96 template <osl::Player P, class Function, bool InterestEmpty>
97 void osl::NumEffectState::
98 forEachEffectOfPtypeO(Square from, Ptype ptype, Function& f) const
99 {
100  const int mask = Ptype_Table.getMoveMask(ptype);
101  TestEffectOfMove<P,InterestEmpty,UL>::testShort(*this, mask, from, f);
102  TestEffectOfMove<P,InterestEmpty,U>::testShort(*this, mask, from, f);
103  TestEffectOfMove<P,InterestEmpty,UR>::testShort(*this, mask, from, f);
104  TestEffectOfMove<P,InterestEmpty,L>::testShort(*this, mask, from, f);
105  TestEffectOfMove<P,InterestEmpty,R>::testShort(*this, mask, from, f);
106  TestEffectOfMove<P,InterestEmpty,DL>::testShort(*this, mask, from, f);
107  TestEffectOfMove<P,InterestEmpty,D>::testShort(*this, mask, from, f);
108  TestEffectOfMove<P,InterestEmpty,DR>::testShort(*this, mask, from, f);
109  TestEffectOfMove<P,InterestEmpty,UUL>::testShort(*this, mask, from, f);
110  TestEffectOfMove<P,InterestEmpty,UUR>::testShort(*this, mask, from, f);
111  TestEffectOfMove<P,InterestEmpty,LONG_UL>::testLong(*this, mask, from, f);
112  TestEffectOfMove<P,InterestEmpty,LONG_U>::testLong(*this, mask, from, f);
113  TestEffectOfMove<P,InterestEmpty,LONG_UR>::testLong(*this, mask, from, f);
114  TestEffectOfMove<P,InterestEmpty,LONG_L>::testLong(*this, mask, from, f);
115  TestEffectOfMove<P,InterestEmpty,LONG_R>::testLong(*this, mask, from, f);
116  TestEffectOfMove<P,InterestEmpty,LONG_DL>::testLong(*this, mask, from, f);
117  TestEffectOfMove<P,InterestEmpty,LONG_D>::testLong(*this, mask, from, f);
118  TestEffectOfMove<P,InterestEmpty,LONG_DR>::testLong(*this, mask, from, f);
119 }
120 
121 template <class Function, bool InterestEmpty>
122 void osl::NumEffectState::
123 forEachEffectOfPtypeO(Square from, PtypeO ptypeo, Function& f) const
124 {
125  const Player P = getOwner(ptypeo);
126  if (P == BLACK)
127  this->template forEachEffectOfPtypeO<BLACK,Function,InterestEmpty>
128  (from, getPtype(ptypeo), f);
129  else
130  this->template forEachEffectOfPtypeO<WHITE,Function,InterestEmpty>
131  (from, getPtype(ptypeo), f);
132 }
133 
134 
135 template <osl::Player P>
136 osl::Piece
137 osl::NumEffectState::safeCaptureNotByKing(Square target, Piece king) const
138 {
139  assert(king.owner() == P);
140  assert(king.ptype() == KING);
141  PieceMask ignore = pin(P);
142  ignore.set(king.number());
143  const Piece piece = findAttackNotBy(P, target, ignore);
144  if (piece.isPiece())
145  return piece;
146  SafeCapture safe_captures(*this);
147  this->template forEachEffectNotBy<P>(target, king, safe_captures);
148 
149  return safe_captures.safe_one;
150 }
151 
152 #endif /* OSL_NUM_EFFECT_STATE_TCC */
153 // ;;; Local Variables:
154 // ;;; mode:c++
155 // ;;; c-basic-offset:2
156 // ;;; End: