All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ntesukiMoveGeneratorAttack.cc
Go to the documentation of this file.
1 /* ntesukiMoveGenerator.cc
2  */
10 #include "osl/move_classifier/check.h"
11 #include "osl/move_generator/escape.h"
13 #include "osl/move_generator/addEffect.h"
14 #include "osl/move_generator/addEffect.tcc"
20 #include "osl/move_generator/capture.h"
21 #include "osl/move_generator/capture.tcc"
22 #include "osl/move_generator/captureEffectToAroundKing8.h"
23 #include "osl/move_action/store.h"
24 #include "osl/move_action/safeFilter.h"
25 #include <iostream>
26 
27 /*
28  * n 手すき探索で用いる move generator.
29  */
30 
31 namespace osl
32 {
33  namespace ntesuki
34  {
35  /* ----------------------------------------------------------------------
36  * Utility
37  * ----------------------------------------------------------------------
38  */
39  static
40  bool
41  hasEffectByBigPieces (const NumEffectState& state,
42  const Player player,
43  const Square pos)
44  {
45 #if OSL_WORDSIZE == 64
46  const PieceMask bigPieceMask (container::PieceMaskBase(
47  PieceMask::numToMask (PtypeTraits<ROOK>::indexMin)
48  | PieceMask::numToMask (PtypeTraits<ROOK>::indexMin + 1)
49  | PieceMask::numToMask (PtypeTraits<BISHOP>::indexMin)
50  | PieceMask::numToMask (PtypeTraits<BISHOP>::indexMin + 1)));
51 
52  const PieceMask pieceMask = (state.piecesOnBoard (player)
53  & state.effectAt (pos)
54  & bigPieceMask);
55  return pieceMask.any();
56 #elif OSL_WORDSIZE == 32
57  // TODO: 多分このコードで64bit 環境と共通にできると思うんだけど
58  // 締切まではそのままに
59  PieceMask bigPieceMask;
60  bigPieceMask.set(PtypeTraits<ROOK>::indexMin);
61  bigPieceMask.set(PtypeTraits<ROOK>::indexMin + 1);
62  bigPieceMask.set(PtypeTraits<BISHOP>::indexMin);
63  bigPieceMask.set(PtypeTraits<BISHOP>::indexMin + 1);
64  const PieceMask pieceMask = (state.piecesOnBoard (player)
65  & state.effectAt (pos)
66  & bigPieceMask);
67  return pieceMask.any();
68 #endif
69  }
70 
71  template <Player P>
72  static
73  void
74  getCheckMoves (const NumEffectState& state, MoveVector& moves)
75  {
76  using namespace move_classifier;
77 
78  const Square targetKing
79  = state.kingSquare<PlayerTraits<P>::opponent>();
80 
82  move_action::SafeFilter<P, state::NumEffectState, move_action::Store> store_safe(state, store);
83  move_generator::AddEffect<P, true>::generate(state, targetKing, store_safe);
84  }
85 
86  template <Player P>
87  struct CaptureHelper
88  {
89  CaptureHelper(const NumEffectState& state,
91  : state(state), action(action)
92  {
93  }
94 
95  void operator()(Piece p)
96  {
98  }
99  private:
100  const NumEffectState& state;
102  };
103 
104  template <Player P, Ptype T>
105  static
106  void
107  capture(const NumEffectState& state, move_action::Store action)
108  {
109  CaptureHelper<P> captureHelper(state, action);
110  state.forEachOnBoard<PlayerTraits<P>::opponent, T, CaptureHelper<P> >(captureHelper);
111  }
112 
113  /* ----------------------------------------------------------------------
114  * ATTACK
115  * ----------------------------------------------------------------------
116  */
117  /* GetAllAttackMoves
118  */
119  GetAllAttackMoves::GetAllAttackMoves(bool verbose)
120  : NtesukiAttackMoveGenerator(verbose) {}
121  GetAllAttackMoves::~GetAllAttackMoves() {}
122  template <Player P>
124  generate(const NumEffectState& state,
125  NtesukiMoveList& moves)
126  {
127  MoveVector move_candidates;
128  LegalMoves::generate(state, move_candidates);
129  moves = NtesukiMoveList(state, move_candidates);
130  }
131  template void GetAllAttackMoves::generate<BLACK>(const NumEffectState& state,
132  NtesukiMoveList& moves);
133  template void GetAllAttackMoves::generate<WHITE>(const NumEffectState& state,
134  NtesukiMoveList& moves);
135 
136  /* GetAttackMoves
137  */
138  GetAttackMoves::GetAttackMoves(bool verbose)
139  : NtesukiAttackMoveGenerator(verbose) {}
140  GetAttackMoves::~GetAttackMoves() {}
141  template <Player P>
142  void GetAttackMoves::
143  generate(const NumEffectState& state,
144  NtesukiMoveList& moves)
145  {
146 #if 0
147  const Square pos = state.template kingSquare<P>();
148  const bool check = state.hasEffectAt(PlayerTraits<P>::opponent, pos);
149 
150  if (check)
151  {
152  MoveVector move_candidates;
153  GenerateEscapeKing::generate(state, move_candidates);
154  moves = NtesukiMoveList(state, move_candidates);
155  return;
156  }
157 
158  MoveVector check_candidates;
159  getCheckMoves<P>(state, check_candidates);
160 
161  MoveVector move_candidates;
162  move_action::Store store(move_candidates);
163 
165  capture<P, ROOK>(state, store);
166  capture<P, BISHOP>(state, store);
167  capture<P, GOLD>(state, store);
168  capture<P, SILVER>(state, store);
169  capture<P, KNIGHT>(state, store);
170  capture<P, LANCE>(state, store);
171  //shold we generate pawn?
172 
173  size_t deleted = 0;
174  for (size_t i = 0; i < move_candidates.size(); ++i)
175  {
176  const Move m = move_candidates[i];
177  if (check_candidates.isMember(move_candidates[i])
178  || (m.from() != Square::STAND() &&
180  m.ptype(),
181  m.from(),
182  m.to())))
183  {
184  ++deleted;
185  move_candidates[i] = Move::INVALID();
186  }
187  }
188 
189  for (size_t i = 0; i < move_candidates.size(); ++i)
190  {
191  if (move_candidates[i] == Move::INVALID()) continue;
192 
193  {
194  ntesuki_assert(!move_classifier::
195  PlayerMoveAdaptor<move_classifier::Check>::
196  isMember(state, move_candidates[i])
197  || (std::cerr << std::endl
198  << state
199  << check_candidates << std::endl
200  << move_candidates << std::endl,
201  0));
202  }
203 
204  moves.push_front(NtesukiMove(move_candidates[i], NtesukiMove::NONE));
205  }
206  for (size_t i = 0; i < check_candidates.size(); ++i)
207  {
208  moves.push_front(NtesukiMove(check_candidates[i], NtesukiMove::CHECK_FLAG));
209  }
210 
211 #else
212  MoveVector all_moves;
213  MoveVector move_candidates;
214  LegalMoves::generate(state, all_moves);
215 
216  const Square opKingSquare =
217  state.kingSquare (alt(state.turn ()));
218 
219  for (unsigned int i=0; i<all_moves.size(); ++i)
220  {
221  const Move m = all_moves[i];
222 
223  /*
224  * 次の手を生成する
225  * - 王に迫る可能性のある手(25近傍に利きをつける手)
226  * - 角道・飛車道を空ける手 (CHECK)
227  * - 取る手
228  */
229  const Square from = m.from();
230 
231  if (Neighboring25Direct::hasEffect(state, m.ptypeO(), m.to(),
232  opKingSquare))
233  {
234  move_candidates.push_back(m);
235  }
236  else if (hasEffectByBigPieces (state, state.turn (), from))
237  {
238  move_candidates.push_back(m);
239  }
240  else
241  {
242  const Square to = m.to();
243  const Piece atTo = state.pieceOnBoard (to);
244 
245  if ((atTo.isPiece())
246  && (atTo.owner() == alt (state.turn ())))
247  {
248  move_candidates.push_back(m);
249  }
250  }
251  }//for each move in all_moves
252  moves = NtesukiMoveList(state, move_candidates);
253 #endif
254  }//generate
255  template void GetAttackMoves::generate<BLACK>(const NumEffectState& state,
256  NtesukiMoveList& moves);
257  template void GetAttackMoves::generate<WHITE>(const NumEffectState& state,
258  NtesukiMoveList& moves);
259 
260  /* GetMultipleAttackMoves
261  */
262  GetMultipleAttackMoves::GetMultipleAttackMoves(bool verbose)
263  : NtesukiAttackMoveGenerator(verbose) {}
264  GetMultipleAttackMoves::~GetMultipleAttackMoves() {}
265  template <Player P>
267  generate(const NumEffectState& state,
268  NtesukiMoveList& moves)
269  {
270  assert (state.turn() == P);
271  MoveVector all_moves;
272  MoveVector move_candidates;
273  LegalMoves::generate(state, all_moves);
274 
275  const Square opKingSquare =
276  state.kingSquare (alt(state.turn ()));
277 
278  for (unsigned int i=0; i<all_moves.size(); ++i)
279  {
280  const Move m = all_moves[i];
281  const Square from = m.from();
282 
284  m.ptype(),
285  m.to(),
286  opKingSquare))
287  {
288  move_candidates.push_back(m);
289  }
290  else if (hasEffectByBigPieces (state, state.turn (), from))
291  {
292  move_candidates.push_back(m);
293  }
294  else
295  {
296  const Square to = m.to();
297  const Piece atTo = state.pieceOnBoard (to);
298  if (atTo.isPiece()
299  && (atTo.owner() == alt (state.turn ())))
300  {
301  move_candidates.push_back(m);
302  }
303  }
304  }//for each move in all_moves
305  moves = NtesukiMoveList(state, move_candidates);
306  }//generate
307  template void GetMultipleAttackMoves::generate<BLACK>(const NumEffectState& state,
308  NtesukiMoveList& moves);
309  template void GetMultipleAttackMoves::generate<WHITE>(const NumEffectState& state,
310  NtesukiMoveList& moves);
311 
312  }//ntesuki
313 }//osl
314 
315 
316 // ;;; Local Variables:
317 // ;;; mode:c++
318 // ;;; c-basic-offset:2
319 // ;;; End: