1#ifndef OSL_GENERATE_PIECE_MOVES_TCC
2#define OSL_GENERATE_PIECE_MOVES_TCC
3#include "osl/move_generator/pieceOnBoard.h"
4#include "osl/move_generator/move_action.h"
5#include "osl/bits/king8Info.h"
9 namespace move_generator
11 namespace piece_on_board
14 * ROOK, BISHOP, PROOK, PBISHOPのlong方向の手生成
15 * CanPはNoPromoteかCanPromote, CheckPromoteのみ
16 * NoPromoteはpromoteできない点からの後ろ,横のdirection
17 * CanPromoteはpromoteできる点から
18 * CheckPromoteはpromoteできない点からの前向き direction
20 template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
22 generateLong(NumEffectState const& state,Piece p,const Piece *ptr,Square from,Action& action,Int2Type<true>,Move moveBase,Ptype ptype)
25 const Direction shortDir=longToShort(Dir);
26 Square limit=state.mobilityOf((P==BLACK ? shortDir : inverse(shortDir)),num);
27 const Piece *limitPtr=state.getPiecePtr(limit);
29 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
30 assert(!offset.zero());
31 ptr+=offset.intValue();
32 Square to=from+offset;
33 Move m=moveBase.newAddTo(offset);
34 if(CanP==CheckPromoteType || CanP==CanPromoteType){
35 if(CanP==CheckPromoteType){
37 int count=(P==BLACK ? from.y1()-5 : 7-from.y1());
38 for(int i=0;i<count;i++){
41 if(!notPromoteCapture && p1.canMoveOn<P>())
42 action.unknownMove(from,to,p1,ptype,false,P,m.newAddCapture(p1));
45 action.simpleMove(from,to,ptype,false,P,m);
46 ptr+=offset.intValue();
47 to+=offset; m=m.newAddTo(offset);
50 if(notPromoteCapture) return;
52 assert(from.canPromote<P>() || to.canPromote<P>());
53 action.simpleMove(from,to,::osl::promote(ptype),true,P,m.promote());
54 ptr+=offset.intValue();
59 if(p1.canMoveOn<P>()){
60 m=m.newAddCapture(p1);
61 assert(from.canPromote<P>() || to.canPromote<P>());
62 action.unknownMove(from,to,p1,::osl::promote(ptype),true,P,m.promote());
67 action.simpleMove(from,to,ptype,false,P,m);
68 ptr+=offset.intValue();
69 to+=offset; m=m.newAddTo(offset);
71 if(notPromoteCapture) return;
73 if(p1.canMoveOn<P>()){
74 m=m.newAddCapture(p1);
75 action.unknownMove(from,to,p1,ptype,false,P,m);
79 template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
81 generateLong(NumEffectState const&,Piece,const Piece *, Square,Action&,Int2Type<false>,Move,Ptype)
85 template <Player P,Ptype T,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
87 generateLong(NumEffectState const& state,Piece p,const Piece *ptr, Square pos,Action& action,Move moveBase,Ptype ptype)
89 generateLong<P,Action,
90 (CanP != CheckPromoteType ? CanP : (DirectionTraits<Dir>::canPromoteTo ? CheckPromoteType : NoPromoteType)),
91 Dir,notPromoteCapture>(state,p,ptr,pos,action,
92 Int2Type<(PtypeTraits<T>::moveMask & DirectionTraits<Dir>::mask) !=0>(),moveBase,ptype);
97 * CanPromoteType - promote可能な動きの時
98 * MustPromoteType - 2段目の歩,3,4段目の桂馬
100 template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
102 generateShort(const Piece *ptr,Square from,Action& action,Int2Type<true>,Move moveBase,Ptype ptype)
104 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
105 Piece p1=ptr[offset.intValue()];
106 Square to=from+offset;
107 Move m=moveBase.newAddTo(offset).newAddCapture(p1);
108 if ((notPromoteCapture ? p1.isEmpty() : p1.canMoveOn<P>())){
109 if (!notPromoteCapture && (CanP==CanPromoteType || CanP==MustPromoteType))
110 action.unknownMove(from,to,p1,::osl::promote(ptype),true,P,m.promote());
111 if (CanP!=MustPromoteType)
112 action.unknownMove(from,to,p1,ptype,false,P,m);
116 template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
118 generateShort(const Piece */*ptr*/,Square /*from*/,Action& /*action*/,Int2Type<false>,Move /*moveBase*/,Ptype /*ptype*/)
122 template <Player P,Ptype T,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
124 generateShort(const Piece *ptr,Square from,Action& action,Move moveBase,Ptype /*ptype*/)
126 generateShort<P,Action,
127 (CanP != CheckPromoteType ? CanP : (DirectionTraits<Dir>::canPromoteTo ? CanPromoteType : NoPromoteType)),
128 Dir,notPromoteCapture>(ptr,from,action,
129 Int2Type<(PtypeTraits<T>::moveMask & DirectionTraits<Dir>::mask) !=0>(),
133 template <Player P,Ptype T,class Action,PromoteType CanP,bool useDirMask,bool notPromoteCapture>
135 generatePtypePromote(const NumEffectState& state,Piece p, Action& action,Square from,int dirMask)
137 const Ptype ptype=(T==GOLD ? p.ptype() : T);
138 Move moveBase=Move(from,from,ptype,(Ptype)0,false,P);
139 const Piece *ptr=state.getPiecePtr(from);
140 if(!useDirMask || (dirMask&(1<<UL))==0){
141 generateShort<P,T,Action,CanP,UL,notPromoteCapture>(ptr,from,action,moveBase,ptype);
142 generateShort<P,T,Action,CanP,DR,notPromoteCapture>(ptr,from,action,moveBase,ptype);
143 generateLong<P,T,Action,CanP,LONG_UL,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
144 generateLong<P,T,Action,CanP,LONG_DR,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
146 if(!useDirMask || (dirMask&(1<<UR))==0){
147 generateShort<P,T,Action,CanP,UR,notPromoteCapture>(ptr,from,action,moveBase,ptype);
148 generateShort<P,T,Action,CanP,DL,notPromoteCapture>(ptr,from,action,moveBase,ptype);
149 generateLong<P,T,Action,CanP,LONG_UR,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
150 generateLong<P,T,Action,CanP,LONG_DL,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
152 if(!useDirMask || (dirMask&(1<<U))==0){
153 generateShort<P,T,Action,CanP,U,notPromoteCapture>(ptr,from,action,moveBase,ptype);
154 generateShort<P,T,Action,CanP,D,notPromoteCapture>(ptr,from,action,moveBase,ptype);
155 generateLong<P,T,Action,CanP,LONG_U,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
156 generateLong<P,T,Action,CanP,LONG_D,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
158 if(!useDirMask || (dirMask&(1<<L))==0){
159 generateShort<P,T,Action,CanP,L,notPromoteCapture>(ptr,from,action,moveBase,ptype);
160 generateShort<P,T,Action,CanP,R,notPromoteCapture>(ptr,from,action,moveBase,ptype);
161 generateLong<P,T,Action,CanP,LONG_L,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
162 generateLong<P,T,Action,CanP,LONG_R,notPromoteCapture>(state,p,ptr,from,action,moveBase,ptype);
164 generateShort<P,T,Action,CanP,UUL,notPromoteCapture>(ptr,from,action,moveBase,ptype);
165 generateShort<P,T,Action,CanP,UUR,notPromoteCapture>(ptr,from,action,moveBase,ptype);
168 template <Player P,Direction Dir,class Action,bool notPromoteCapture>
170 generateKingDir(const Piece *ptr, Square from,Action& action,unsigned int liberty,Move const& moveBase)
172 if((liberty&(1<<Dir))!=0){
173 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
174 Move m=moveBase.newAddTo(offset);
175 Square to=from+offset;
176 Piece p1=ptr[offset.intValue()];
177 assert(p1.canMoveOn<P>());
178 if(notPromoteCapture && !p1.isEmpty()) return;
179 m=m.newAddCapture(p1);
180 action.unknownMove(from,to,p1,KING,false,P,m);
184 template <Player P,class Action,bool useDirMask,bool notPromoteCapture>
186 generateKing(const NumEffectState& state, Action& action,Square pos,int dirMask)
188 King8Info king8info(state.Iking8Info(P));
189 unsigned int liberty=king8info.liberty();
190 Move moveBase(pos,pos,KING,(Ptype)0,false,P);
191 const Piece *ptr=state.getPiecePtr(pos);
192 if(!useDirMask || (dirMask&(1<<UL))==0){
193 generateKingDir<P,UL,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
194 generateKingDir<P,DR,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
196 if(!useDirMask || (dirMask&(1<<U))==0){
197 generateKingDir<P,U,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
198 generateKingDir<P,D,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
200 if(!useDirMask || (dirMask&(1<<UR))==0){
201 generateKingDir<P,UR,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
202 generateKingDir<P,DL,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
204 if(!useDirMask || (dirMask&(1<<L))==0){
205 generateKingDir<P,L,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
206 generateKingDir<P,R,Action,notPromoteCapture>(ptr,pos,action,liberty,moveBase);
210 template <Player P,class Action,bool useDirMask,bool notPromoteCapture>
212 generateLance(const NumEffectState& state, Piece p,Action& action,Square from,int dirMask)
214 if(!useDirMask || (dirMask&(1<<U))==0){
215 const Offset offset=DirectionPlayerTraits<U,P>::offset();
216 Square limit=state.mobilityOf((P==BLACK ? U : D),p.number());
218 Piece p1=state.pieceAt(to);
219 int limity=(P==BLACK ? to.y() : 10-to.y());
220 int fromy=(P==BLACK ? from.y() : 10-from.y());
221 int ycount=fromy-limity-1;
222 Move m(from,to,LANCE,(Ptype)0,false,P);
224 case 4: case 5: case 6: case 7: case 8: case 9:{
225 if(!notPromoteCapture && p1.canMoveOn<P>())
226 action.unknownMove(from,to,p1,LANCE,false,P,m.newAddCapture(p1));
227 m=m.newAddTo(-offset); to-=offset;
231 if(!notPromoteCapture && p1.canMoveOn<P>()){
232 Move m1=m.newAddCapture(p1);
233 action.unknownMove(from,to,p1,PLANCE,true,P,m1.promote());
234 action.unknownMove(from,to,p1,LANCE,false,P,m1);
236 m=m.newAddTo(-offset); to-=offset;
239 if(!notPromoteCapture && p1.canMoveOn<P>()){
240 Move m1=m.newAddCapture(p1);
241 action.unknownMove(from,to,p1,PLANCE,true,P,m1.promote());
244 m=m.newAddTo(-offset); to-=offset;
248 m=m.newAddTo(-offset); to-=offset;
249 if(!notPromoteCapture)
250 action.simpleMove(from,to,PLANCE,true,P,m.promote());
253 if(!notPromoteCapture && p1.canMoveOn<P>()){
254 action.unknownMove(from,to,p1,PLANCE,true,P,m.newAddCapture(p1).promote());
258 m=m.newAddTo(-offset); to-=offset;
260 if(!notPromoteCapture)
261 action.simpleMove(from,to,PLANCE,true,P,m.promote());
269 if(!notPromoteCapture)
270 action.simpleMove(from,to,PLANCE,true,P,m.promote());
271 m=m.newAddTo(-offset); to-=offset;
273 if(!notPromoteCapture)
274 action.simpleMove(from,to,PLANCE,true,P,m.promote());
275 action.simpleMove(from,to,LANCE,false,P,m);
276 m=m.newAddTo(-offset); to-=offset;
279 action.simpleMove(from,to,LANCE,false,P,m);
280 m=m.newAddTo(-offset);
287 template <Player P,class Action,bool useDirMask,bool notPromoteCapture>
289 generatePawn(const NumEffectState& state, Piece p,Action& action,Square from,int dirMask)
291 assert(from == p.square());
292 if(!useDirMask || (dirMask&(1<<U))==0){
293 if(notPromoteCapture && (P==BLACK ? from.yLe<4>() : from.yGe<6>())) return;
294 const Offset offset=DirectionPlayerTraits<U,P>::offset();
295 Square to=from+offset;
296 Piece p1=state.pieceAt(to);
297 if(notPromoteCapture){
299 action.simpleMove(from,to,PAWN,false,P);
302 if(p1.canMoveOn<P>()){
303 if(P==BLACK ? to.yLe<3>() : to.yGe<7>()){ // canPromote
304 if(notPromoteCapture) return;
305 Move m(from,to,PPAWN,PTYPE_EMPTY,true,P);
306 action.unknownMove(from,to,p1,PPAWN,true,P,
307 m.newAddCapture(p1));
310 Move m(from,to,PAWN,PTYPE_EMPTY,false,P);
311 action.unknownMove(from,to,p1,PAWN,false,P,m.newAddCapture(p1));
317 template <class Action,bool notPromoteCapture>
318 template <Player P,Ptype T,bool useDirMask>
319 void PieceOnBoard<Action,notPromoteCapture>::
320 generatePtypeUnsafe(const NumEffectState& state,Piece p, Action& action,int dirMask)
322 using piece_on_board::generatePtypePromote;
323 using piece_on_board::generateKing;
324 using piece_on_board::generateLance;
325 using piece_on_board::generatePawn;
326 const Square from=p.square();
328 generateKing<P,Action,useDirMask,notPromoteCapture>(state,action,from,dirMask);
331 generateLance<P,Action,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
334 generatePawn<P,Action,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
336 else if(canPromote(T)){
337 if(PtypePlayerTraits<T,P>::mustPromote(from))
338 generatePtypePromote<P,T,Action,MustPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
339 else if(PtypePlayerTraits<T,P>::canPromote(from))
340 generatePtypePromote<P,T,Action,CanPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
341 else if(PtypePlayerTraits<T,P>::checkPromote(from))
342 generatePtypePromote<P,T,Action,CheckPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
344 generatePtypePromote<P,T,Action,NoPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
347 generatePtypePromote<P,T,Action,NoPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
350 template <class Action,bool notPromoteCapture>
351template <Player P,Ptype T,bool useDirMask>
352 void PieceOnBoard<Action,notPromoteCapture>::
353generatePtype(const NumEffectState& state,Piece p, Action& action,int dirMask)
356// if(T==SILVER) std::cerr << "p=" << p << std::endl;
357 if(state.pin(P).test(num)){
358 if(T==KNIGHT) return;
359 Direction d=state.pinnedDir<P>(p);
360 dirMask|=(~(1<<primDir(d)));
361// std::cerr << "pinned direction=" << d << ",dirMask=" << dirMask << std::endl;
362 generatePtypeUnsafe<P,T,true>(state,p,action,dirMask);
365 generatePtypeUnsafe<P,T,useDirMask>(state,p,action,dirMask);
368 template <class Action,bool notPromoteCapture>
369template <Player P,bool useDirmask>
370 void PieceOnBoard<Action,notPromoteCapture>::
371generate(const NumEffectState& state,Piece p, Action& action,int dirMask)
375 case PPAWN: case PLANCE: case PKNIGHT: case PSILVER: case GOLD:
376 generatePtype<P,GOLD,useDirmask>(state,p,action,dirMask); break;
378 generatePtype<P,PAWN,useDirmask>(state,p,action,dirMask); break;
380 generatePtype<P,LANCE,useDirmask>(state,p,action,dirMask); break;
382 generatePtype<P,KNIGHT,useDirmask>(state,p,action,dirMask); break;
384 generatePtype<P,SILVER,useDirmask>(state,p,action,dirMask); break;
386 generatePtype<P,BISHOP,useDirmask>(state,p,action,dirMask); break;
388 generatePtype<P,PBISHOP,useDirmask>(state,p,action,dirMask); break;
390 generatePtype<P,ROOK,useDirmask>(state,p,action,dirMask); break;
392 generatePtype<P,PROOK,useDirmask>(state,p,action,dirMask); break;
394 generatePtype<P,KING,useDirmask>(state,p,action,dirMask); break;
398} // namespace move_generator
401#endif /* _GENERATE_PIECE_MOVES_TCC */
402// ;;; Local Variables:
404// ;;; c-basic-offset:2