All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
pieceOnBoard.tcc
Go to the documentation of this file.
1 #ifndef _GENERATE_PIECE_MOVES_TCC
2 #define _GENERATE_PIECE_MOVES_TCC
8 #include <iostream>
9 namespace osl
10 {
11  namespace move_generator
12  {
13  namespace piece_on_board
14  {
22  template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
23  inline void
24  generateLong(NumEffectState const& state,Piece p,const Piece *ptr,Square from,Action& action,Int2Type<true>,Move moveBase,Ptype ptype)
25  {
26  int num=p.number();
27  const Direction shortDir=longToShort(Dir);
28  Square limit=state.mobilityOf((P==BLACK ? shortDir : inverse(shortDir)),num);
29  const Piece *limitPtr=state.getPiecePtr(limit);
30  assert(ptype!=LANCE);
32  assert(!offset.zero());
33  ptr+=offset.intValue();
34  Square to=from+offset;
35  Move m=moveBase.newAddTo(offset);
36  if(CanP==CheckPromoteType || CanP==CanPromoteType){
37  if(CanP==CheckPromoteType){
38  // promoteできない数
39  int count=(P==BLACK ? from.y1()-5 : 7-from.y1());
40  for(int i=0;i<count;i++){
41  if(ptr==limitPtr){
42  Piece p1= *limitPtr;
43  if(!notPromoteCapture && p1.canMoveOn<P>())
44  action.unknownMove(from,to,p1,ptype,false,P,m.newAddCapture(p1));
45  return;
46  }
47  action.simpleMove(from,to,ptype,false,P,m);
48  ptr+=offset.intValue();
49  to+=offset; m=m.newAddTo(offset);
50  }
51  }
52  if(notPromoteCapture) return;
53  while(ptr!=limitPtr){
54  assert(from.canPromote<P>() || to.canPromote<P>());
55  action.simpleMove(from,to,promote(ptype),true,P,m.promote());
56  ptr+=offset.intValue();
57  to+=offset;
58  m=m.newAddTo(offset);
59  }
60  Piece p1= *limitPtr;
61  if(p1.canMoveOn<P>()){
62  m=m.newAddCapture(p1);
63  assert(from.canPromote<P>() || to.canPromote<P>());
64  action.unknownMove(from,to,p1,promote(ptype),true,P,m.promote());
65  }
66  }
67  else{ // NoPromote
68  while(ptr!=limitPtr){
69  action.simpleMove(from,to,ptype,false,P,m);
70  ptr+=offset.intValue();
71  to+=offset; m=m.newAddTo(offset);
72  }
73  if(notPromoteCapture) return;
74  Piece p1= *limitPtr;
75  if(p1.canMoveOn<P>()){
76  m=m.newAddCapture(p1);
77  action.unknownMove(from,to,p1,ptype,false,P,m);
78  }
79  }
80  }
81  template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
82  inline void
83  generateLong(NumEffectState const&,Piece,const Piece *, Square,Action&,Int2Type<false>,Move,Ptype)
84  {
85  }
86 
87  template <Player P,Ptype T,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
88  inline void
89  generateLong(NumEffectState const& state,Piece p,const Piece *ptr, Square pos,Action& action,Move moveBase,Ptype ptype)
90  {
91  generateLong<P,Action,
93  Dir,notPromoteCapture>(state,p,ptr,pos,action,
94  Int2Type<(PtypeTraits<T>::moveMask & DirectionTraits<Dir>::mask) !=0>(),moveBase,ptype);
95  }
96 
102  template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
103  void
104  generateShort(const Piece *ptr,Square from,Action& action,Int2Type<true>,Move moveBase,Ptype ptype)
105  {
107  Piece p1=ptr[offset.intValue()];
108  Square to=from+offset;
109  Move m=moveBase.newAddTo(offset).newAddCapture(p1);
110  if ((notPromoteCapture ? p1.isEmpty() : p1.canMoveOn<P>())){
111  if (!notPromoteCapture && (CanP==CanPromoteType || CanP==MustPromoteType))
112  action.unknownMove(from,to,p1,promote(ptype),true,P,m.promote());
113  if (CanP!=MustPromoteType)
114  action.unknownMove(from,to,p1,ptype,false,P,m);
115  }
116  }
117 
118  template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
119  void
120  generateShort(const Piece */*ptr*/,Square /*from*/,Action& /*action*/,Int2Type<false>,Move /*moveBase*/,Ptype /*ptype*/)
121  {
122  }
123 
124  template <Player P,Ptype T,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
125  void
126  generateShort(const Piece *ptr,Square from,Action& action,Move moveBase,Ptype /*ptype*/)
127  {
128  generateShort<P,Action,
130  Dir,notPromoteCapture>(ptr,from,action,
131  Int2Type<(PtypeTraits<T>::moveMask & DirectionTraits<Dir>::mask) !=0>(),
132  moveBase,T);
133  }
134 
135  template <Player P,Ptype T,class Action,PromoteType CanP,bool useDirMask,bool notPromoteCapture>
136  inline void
137  generatePtypePromote(const NumEffectState& state,Piece p, Action& action,Square from,int dirMask)
138  {
139  const Ptype ptype=(T==GOLD ? p.ptype() : T);
140  Move moveBase=Move(from,from,ptype,(Ptype)0,false,P);
141  const Piece *ptr=state.getPiecePtr(from);
142  if(!useDirMask || (dirMask&(1<<UL))==0){
143  generateShort<P,T,Action,CanP,UL,notPromoteCapture>(ptr,from,action,moveBase,ptype);
144  generateShort<P,T,Action,CanP,DR,notPromoteCapture>(ptr,from,action,moveBase,ptype);
145  generateLong<P,T,Action,CanP,LONG_UL,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
146  generateLong<P,T,Action,CanP,LONG_DR,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
147  }
148  if(!useDirMask || (dirMask&(1<<UR))==0){
149  generateShort<P,T,Action,CanP,UR,notPromoteCapture>(ptr,from,action,moveBase,ptype);
150  generateShort<P,T,Action,CanP,DL,notPromoteCapture>(ptr,from,action,moveBase,ptype);
151  generateLong<P,T,Action,CanP,LONG_UR,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
152  generateLong<P,T,Action,CanP,LONG_DL,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
153  }
154  if(!useDirMask || (dirMask&(1<<U))==0){
155  generateShort<P,T,Action,CanP,U,notPromoteCapture>(ptr,from,action,moveBase,ptype);
156  generateShort<P,T,Action,CanP,D,notPromoteCapture>(ptr,from,action,moveBase,ptype);
157  generateLong<P,T,Action,CanP,LONG_U,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
158  generateLong<P,T,Action,CanP,LONG_D,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
159  }
160  if(!useDirMask || (dirMask&(1<<L))==0){
161  generateShort<P,T,Action,CanP,L,notPromoteCapture>(ptr,from,action,moveBase,ptype);
162  generateShort<P,T,Action,CanP,R,notPromoteCapture>(ptr,from,action,moveBase,ptype);
163  generateLong<P,T,Action,CanP,LONG_L,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
164  generateLong<P,T,Action,CanP,LONG_R,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
165  }
166  generateShort<P,T,Action,CanP,UUL,notPromoteCapture>(ptr,from,action,moveBase,ptype);
167  generateShort<P,T,Action,CanP,UUR,notPromoteCapture>(ptr,from,action,moveBase,ptype);
168  }
169 
170  template <Player P,Direction Dir,class Action,bool notPromoteCapture>
171  inline void
172  generateKingDir(const Piece *ptr, Square from,Action& action,unsigned int liberty,Move const& moveBase)
173  {
174  if((liberty&(1<<Dir))!=0){
176  Move m=moveBase.newAddTo(offset);
177  Square to=from+offset;
178  Piece p1=ptr[offset.intValue()];
179  assert(p1.canMoveOn<P>());
180  if(notPromoteCapture && !p1.isEmpty()) return;
181  m=m.newAddCapture(p1);
182  action.unknownMove(from,to,p1,KING,false,P,m);
183  }
184  }
185 
186  template <Player P,class Action,bool useDirMask,bool notPromoteCapture>
187  inline void
188  generateKing(const NumEffectState& state, Action& action,Square pos,int dirMask)
189  {
190  King8Info king8info(state.Iking8Info(P));
191  unsigned int liberty=king8info.liberty();
192  Move moveBase(pos,pos,KING,(Ptype)0,false,P);
193  const Piece *ptr=state.getPiecePtr(pos);
194  if(!useDirMask || (dirMask&(1<<UL))==0){
195  generateKingDir<P,UL,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
196  generateKingDir<P,DR,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
197  }
198  if(!useDirMask || (dirMask&(1<<U))==0){
199  generateKingDir<P,U,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
200  generateKingDir<P,D,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
201  }
202  if(!useDirMask || (dirMask&(1<<UR))==0){
203  generateKingDir<P,UR,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
204  generateKingDir<P,DL,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
205  }
206  if(!useDirMask || (dirMask&(1<<L))==0){
207  generateKingDir<P,L,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
208  generateKingDir<P,R,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
209  }
210  }
211 
212  template <Player P,class Action,bool useDirMask,bool notPromoteCapture>
213  inline void
214  generateLance(const NumEffectState& state, Piece p,Action& action,Square from,int dirMask)
215  {
216  if(!useDirMask || (dirMask&(1<<U))==0){
218  Square limit=state.mobilityOf((P==BLACK ? U : D),p.number());
219  Square to=limit;
220  Piece p1=state.pieceAt(to);
221  int limity=(P==BLACK ? to.y() : 10-to.y());
222  int fromy=(P==BLACK ? from.y() : 10-from.y());
223  int ycount=fromy-limity-1;
224  Move m(from,to,LANCE,(Ptype)0,false,P);
225  switch(limity){
226  case 4: case 5: case 6: case 7: case 8: case 9:{
227  if(!notPromoteCapture && p1.canMoveOn<P>())
228  action.unknownMove(from,to,p1,LANCE,false,P,m.newAddCapture(p1));
229  m=m.newAddTo(-offset); to-=offset;
230  goto escape4;
231  }
232  case 3:
233  if(!notPromoteCapture && p1.canMoveOn<P>()){
234  Move m1=m.newAddCapture(p1);
235  action.unknownMove(from,to,p1,PLANCE,true,P,m1.promote());
236  action.unknownMove(from,to,p1,LANCE,false,P,m1);
237  }
238  m=m.newAddTo(-offset); to-=offset;
239  goto escape4;
240  case 2:
241  if(!notPromoteCapture && p1.canMoveOn<P>()){
242  Move m1=m.newAddCapture(p1);
243  action.unknownMove(from,to,p1,PLANCE,true,P,m1.promote());
244  }
245  if(fromy==3) return;
246  m=m.newAddTo(-offset); to-=offset;
247  ycount=fromy-4;
248  goto escape2;
249  case 0:
250  m=m.newAddTo(-offset); to-=offset;
251  if(!notPromoteCapture)
252  action.simpleMove(from,to,PLANCE,true,P,m.promote());
253  goto join01;
254  case 1:
255  if(!notPromoteCapture && p1.canMoveOn<P>()){
256  action.unknownMove(from,to,p1,PLANCE,true,P,m.newAddCapture(p1).promote());
257  }
258  join01:
259  if(fromy==2) return;
260  m=m.newAddTo(-offset); to-=offset;
261  if(fromy==3){
262  if(!notPromoteCapture)
263  action.simpleMove(from,to,PLANCE,true,P,m.promote());
264  return;
265  }
266  ycount=fromy-4;
267  goto escape01;
268  default: assert(0);
269  }
270  escape01:
271  if(!notPromoteCapture)
272  action.simpleMove(from,to,PLANCE,true,P,m.promote());
273  m=m.newAddTo(-offset); to-=offset;
274  escape2:
275  if(!notPromoteCapture)
276  action.simpleMove(from,to,PLANCE,true,P,m.promote());
277  action.simpleMove(from,to,LANCE,false,P,m);
278  m=m.newAddTo(-offset); to-=offset;
279  escape4:
280  while(ycount-->0){
281  action.simpleMove(from,to,LANCE,false,P,m);
282  m=m.newAddTo(-offset);
283  to-=offset;
284  }
285  }
286  return;
287  }
288 
289  template <Player P,class Action,bool useDirMask,bool notPromoteCapture>
290  inline void
291  generatePawn(const NumEffectState& state, Piece p,Action& action,Square from,int dirMask)
292  {
293  assert(from == p.square());
294  if(!useDirMask || (dirMask&(1<<U))==0){
295  if(notPromoteCapture && (P==BLACK ? from.yLe<4>() : from.yGe<6>())) return;
297  Square to=from+offset;
298  Piece p1=state.pieceAt(to);
299  if(notPromoteCapture){
300  if(p1.isEmpty())
301  action.simpleMove(from,to,PAWN,false,P);
302  return;
303  }
304  if(p1.canMoveOn<P>()){
305  if(P==BLACK ? to.yLe<3>() : to.yGe<7>()){ // canPromote
306  if(notPromoteCapture) return;
307  Move m(from,to,PPAWN,PTYPE_EMPTY,true,P);
308  action.unknownMove(from,to,p1,PPAWN,true,P,
309  m.newAddCapture(p1));
310  }
311  else{
312  Move m(from,to,PAWN,PTYPE_EMPTY,false,P);
313  action.unknownMove(from,to,p1,PAWN,false,P,m.newAddCapture(p1));
314  }
315  }
316  }
317  }
318 }
319  template <class Action,bool notPromoteCapture>
320  template <Player P,Ptype T,bool useDirMask>
322  generatePtypeUnsafe(const NumEffectState& state,Piece p, Action& action,int dirMask)
323  {
328  const Square from=p.square();
329  if(T==KING){
330  generateKing<P,Action,useDirMask,notPromoteCapture>(state,action,from,dirMask);
331  }
332  else if(T==LANCE){
333  generateLance<P,Action,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
334  }
335  else if(T==PAWN){
336  generatePawn<P,Action,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
337  }
338  else if(canPromote(T)){
340  generatePtypePromote<P,T,Action,MustPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
342  generatePtypePromote<P,T,Action,CanPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
344  generatePtypePromote<P,T,Action,CheckPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
345  else
346  generatePtypePromote<P,T,Action,NoPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
347  }
348  else
349  generatePtypePromote<P,T,Action,NoPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
350  }
351 
352  template <class Action,bool notPromoteCapture>
353 template <Player P,Ptype T,bool useDirMask>
355 generatePtype(const NumEffectState& state,Piece p, Action& action,int dirMask)
356 {
357  int num=p.number();
358 // if(T==SILVER) std::cerr << "p=" << p << std::endl;
359  if(state.pin(P).test(num)){
360  if(T==KNIGHT) return;
361  Direction d=state.pinnedDir<P>(p);
362  dirMask|=(~(1<<primDir(d)));
363 // std::cerr << "pinned direction=" << d << ",dirMask=" << dirMask << std::endl;
364  generatePtypeUnsafe<P,T,true>(state,p,action,dirMask);
365  }
366  else{
367  generatePtypeUnsafe<P,T,useDirMask>(state,p,action,dirMask);
368  }
369 }
370  template <class Action,bool notPromoteCapture>
371 template <Player P,bool useDirmask>
373 generate(const NumEffectState& state,Piece p, Action& action,int dirMask)
374 {
375 
376  switch(p.ptype()){
377  case PPAWN: case PLANCE: case PKNIGHT: case PSILVER: case GOLD:
378  generatePtype<P,GOLD,useDirmask>(state,p,action,dirMask); break;
379  case PAWN:
380  generatePtype<P,PAWN,useDirmask>(state,p,action,dirMask); break;
381  case LANCE:
382  generatePtype<P,LANCE,useDirmask>(state,p,action,dirMask); break;
383  case KNIGHT:
384  generatePtype<P,KNIGHT,useDirmask>(state,p,action,dirMask); break;
385  case SILVER:
386  generatePtype<P,SILVER,useDirmask>(state,p,action,dirMask); break;
387  case BISHOP:
388  generatePtype<P,BISHOP,useDirmask>(state,p,action,dirMask); break;
389  case PBISHOP:
390  generatePtype<P,PBISHOP,useDirmask>(state,p,action,dirMask); break;
391  case ROOK:
392  generatePtype<P,ROOK,useDirmask>(state,p,action,dirMask); break;
393  case PROOK:
394  generatePtype<P,PROOK,useDirmask>(state,p,action,dirMask); break;
395  case KING:
396  generatePtype<P,KING,useDirmask>(state,p,action,dirMask); break;
397  default: break;
398  }
399 }
400 } // namespace move_generator
401 } // namespace osl
402 
403 #endif /* _GENERATE_PIECE_MOVES_TCC */
404 // ;;; Local Variables:
405 // ;;; mode:c++
406 // ;;; c-basic-offset:2
407 // ;;; End:
408