All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
escape_.tcc
Go to the documentation of this file.
1 #ifndef OSL_GENERATE_ESCAPE_MOVES_TCC
2 #define OSL_GENERATE_ESCAPE_MOVES_TCC
3 
9 namespace osl
10 {
11  namespace move_generator
12  {
13  namespace escape
14  {
19  template<Player P,class Action,Ptype Type>
20  bool generateDrop(const NumEffectState& state,Square to,Action& action){
21  if(state.template hasPieceOnStand<Type>(P)){
22  if((Type!=PAWN || !state.isPawnMaskSet(P,to.x())) &&
24  action.dropMove(to,Type,P);
25  return true;
26  }
27  }
28  return false;
29  }
30  /*
31  * 駒をtoに打つ手を生成する.
32  * CheapOnlyの時は最も価値の低い駒を打つ手のみ生成する.
33  */
34  template<Player P,class Action,bool CheapOnly>
35  void generateDropAll(const NumEffectState& state,Square to,Action& action)
36  {
37  bool gen = generateDrop<P,Action,PAWN>(state,to,action); if (CheapOnly && gen) return;
38  gen = generateDrop<P,Action,LANCE>(state,to,action); if (CheapOnly && gen) return;
39  gen = generateDrop<P,Action,KNIGHT>(state,to,action); if (CheapOnly && gen) return;
40  gen = generateDrop<P,Action,SILVER>(state,to,action); if (CheapOnly && gen) return;
41  gen = generateDrop<P,Action,GOLD>(state,to,action); if (CheapOnly && gen) return;
42  gen = generateDrop<P,Action,BISHOP>(state,to,action); if (CheapOnly && gen) return;
43  generateDrop<P,Action,ROOK>(state,to,action);
44  }
45 
51  template<Player P,class Action,bool CheapOnly>
52  void
53  blockByMoveOne(const NumEffectState& state, Square pos, Action &action)
54  {
55  const PieceMask pieces = state.effectSetAt(pos) & state.piecesOnBoard(P);
56  int offset = 0;
57  mask_t m = pieces.selectBit<PAWN>();
58  if (m.none()) {
59  m = pieces.selectBit<LANCE>();
60  offset = PtypeFuns<LANCE>::indexNum*32;
61  if (m.none()) {
62  m = pieces.selectBit<KNIGHT>();
63  offset = PtypeFuns<KNIGHT>::indexNum*32;
64  if (m.none()) {
65  m = pieces.selectBit<SILVER>();
66  offset = PtypeFuns<SILVER>::indexNum*32;
67  if (m.none()) {
68  m = pieces.selectBit<GOLD>();
69  offset = PtypeFuns<GOLD>::indexNum*32;
70  if (m.none()) {
71  m = pieces.selectBit<BISHOP>();
72  offset = PtypeFuns<BISHOP>::indexNum*32;
73  if (m.none()) {
74  m = pieces.selectBit<ROOK>();
75  offset = PtypeFuns<ROOK>::indexNum*32;
76  if (m.none())
77  return;
78  }
79  }
80  }
81  }
82  }
83  }
84  const Piece p = state.pieceOf(m.takeOneBit() + offset);
85  PieceOnBoard<Action>::template generatePiece<P>(state,p,pos,Piece::EMPTY(),action);
86  }
87  } // end of namespace escape
90 
99  template<class Action>
100  template<Player P,bool CheapOnly>
101  void Escape<Action>::
102  generateBlocking(const NumEffectState& state,Piece p,Square to,Square from,Action &action)
103  {
104  assert(from.isOnBoard());
105  Offset offset=Board_Table.getShortOffset(Offset32(from,to));
106  assert(!offset.zero());
107  for(Square pos=to+offset;pos!=from;pos+=offset){
108  assert(state.pieceAt(pos).isEmpty());
109  if (! CheapOnly) {
110  Capture<Action>::template escapeByCapture<P>(state,pos,p,action);
111  // 駒を置いて
112  generateDropAll<P,Action,false>(state,pos,action);
113  }
114  else {
115  // 駒を動かして
116  const int e = state.countEffect(P, pos);
117  if (e >= 2)
118  blockByMoveOne<P,Action,CheapOnly>(state, pos, action);
119  // 駒を置いて
120  if (e)
121  generateDropAll<P,Action,true>(state,pos,action);
122  }
123  }
124  }
130  template<class Action>
131  template<Player P,bool CheapOnly>
132  void Escape<Action>::
133  generateBlockingKing(const NumEffectState& state,Piece p,Square from,Action &action)
134  {
135  Square to=p.square();
136  Offset offset=Board_Table.getShortOffset(Offset32(from,to));
137  assert(!offset.zero());
138  for(Square pos=to+offset;pos!=from;pos+=offset){
139  assert(state.pieceAt(pos).isEmpty());
140  Capture<Action>::template escapeByCapture<P>(state,pos,p,action);
141  // 駒を置いて
142  generateDropAll<P,Action,CheapOnly>(state,pos,action);
143  }
144  }
145  template<class Action>
146  template<Player P,Ptype Type,bool CheapOnly>
147  void Escape<Action>::
148  generateMovesBy(const NumEffectState& state,Piece p,Piece const attacker,Action& action)
149  {
150  if(attacker==Piece::EMPTY()){
152  generateEscape<P,Type>(state,p,action);
153  }
154  else if(Type == KING){
155 #ifndef NDEBUG
156  {
157  Piece attack_by_position;
158  state.template findCheckPiece<P>(attack_by_position);
159  assert(attacker == attack_by_position);
160  }
161 #endif
162  Square attackFrom=attacker.square();
163 
164  generateCaptureKing<P>( state, p, attackFrom, action );
166  generateEscape<P,Type>( state,p,action);
168  generateBlockingKing<P,CheapOnly>(state,p,attackFrom,action);
169  }
170  else{
171  Square attackFrom=attacker.square();
172  generateCapture<P>( state, p, attackFrom, action );
174  generateEscape<P,Type>( state,p,action);
176  generateBlocking<P,CheapOnly>(state,p,p.square(),attackFrom,action);
177  }
178  }
179 
180  template<class Action>
181  template<Player P,bool CheapOnly>
182  void Escape<Action>::
183  generateKingEscape(const NumEffectState& state,Action& action){
184  Piece kingPiece=state.pieceOf(KingTraits<P>::index);
185  Piece attacker;
186 #ifndef NDEBUG
187  const bool is_attacked=
188 #endif
189  state.template findCheckPiece<P>(attacker);
190  assert(is_attacked); // 相手からの利きがないのに呼ぶな
191  generateMovesBy<P,KING,CheapOnly>(state,kingPiece,attacker,action);
192  }
193 
194  template<class Action>
195  template<Player P,Ptype TYPE,bool CheapOnly>
196  void Escape<Action>::
197  generateMovesBy(const NumEffectState& state,Piece p,Action& action)
198  {
199  Square target=p.square();
200  Piece attacker;
201 #ifndef NDEBUG
202  const bool is_attacked=
203 #endif
204  state.template hasEffectAt<PlayerTraits<P>::opponent>(target,attacker);
205  assert(is_attacked); // 相手からの利きがないのに呼ぶな
206  generateMovesBy<P,TYPE,CheapOnly>(state,p,attacker,action);
207  }
208 
209  template<class Action>
210  template<Player P,bool CheapOnly>
211  void Escape<Action>::
212  generateMoves(const NumEffectState& state,Piece piece,Piece attacker,Action& action)
213  {
214  switch(piece.ptype()){
215  case PAWN: generateMovesBy<P,PAWN,CheapOnly>(state,piece,attacker,action); break;
216  case LANCE: generateMovesBy<P,LANCE,CheapOnly>(state,piece,attacker,action); break;
217  case KNIGHT: generateMovesBy<P,KNIGHT,CheapOnly>(state,piece,attacker,action); break;
218  case SILVER: generateMovesBy<P,SILVER,CheapOnly>(state,piece,attacker,action); break;
219  case PPAWN: generateMovesBy<P,PPAWN,CheapOnly>(state,piece,attacker,action); break;
220  case PLANCE: generateMovesBy<P,PLANCE,CheapOnly>(state,piece,attacker,action); break;
221  case PKNIGHT: generateMovesBy<P,PKNIGHT,CheapOnly>(state,piece,attacker,action); break;
222  case PSILVER: generateMovesBy<P,PSILVER,CheapOnly>(state,piece,attacker,action); break;
223  case GOLD: generateMovesBy<P,GOLD,CheapOnly>(state,piece,attacker,action); break;
224  case BISHOP: generateMovesBy<P,BISHOP,CheapOnly>(state,piece,attacker,action); break;
225  case PBISHOP: generateMovesBy<P,PBISHOP,CheapOnly>(state,piece,attacker,action); break;
226  case ROOK: generateMovesBy<P,ROOK,CheapOnly>(state,piece,attacker,action); break;
227  case PROOK: generateMovesBy<P,PROOK,CheapOnly>(state,piece,attacker,action); break;
228  case KING: generateMovesBy<P,KING,CheapOnly>(state,piece,attacker,action); break;
229  default: assert(0);
230 
231  }
232  }
233  template<class Action>
234  template<Player P,bool shouldPromote,bool CheapOnly>
235  void Escape<Action>::
236  generate(const NumEffectState& state,Piece piece,Action& action)
237  {
238  assert(piece.owner() == P);
239  Square target=piece.square();
240  Piece attacker;
241  state.template hasEffectAt<PlayerTraits<P>::opponent>(target,attacker);
242  generateMoves<P,CheapOnly>(state,piece,attacker,action);
243  }
244  } // namespace move_generator
245 
246 } // namespace osl
247 
248 #endif // OSL_GENERATE_ESCAPE_MOVES_TCC
249 // ;;; Local Variables:
250 // ;;; mode:c++
251 // ;;; c-basic-offset:2
252 // ;;; End:
253