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