My Project
pieceOnBoard.tcc
Go to the documentation of this file.
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"
6
7namespace osl
8{
9 namespace move_generator
10 {
11 namespace piece_on_board
12 {
13 /**
14 * ROOK, BISHOP, PROOK, PBISHOPのlong方向の手生成
15 * CanPはNoPromoteかCanPromote, CheckPromoteのみ
16 * NoPromoteはpromoteできない点からの後ろ,横のdirection
17 * CanPromoteはpromoteできる点から
18 * CheckPromoteはpromoteできない点からの前向き direction
19 */
20 template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
21 inline void
22 generateLong(NumEffectState const& state,Piece p,const Piece *ptr,Square from,Action& action,Int2Type<true>,Move moveBase,Ptype ptype)
23 {
24 int num=p.number();
25 const Direction shortDir=longToShort(Dir);
26 Square limit=state.mobilityOf((P==BLACK ? shortDir : inverse(shortDir)),num);
27 const Piece *limitPtr=state.getPiecePtr(limit);
28 assert(ptype!=LANCE);
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){
36 // promoteできない数
37 int count=(P==BLACK ? from.y1()-5 : 7-from.y1());
38 for(int i=0;i<count;i++){
39 if(ptr==limitPtr){
40 Piece p1= *limitPtr;
41 if(!notPromoteCapture && p1.canMoveOn<P>())
42 action.unknownMove(from,to,p1,ptype,false,P,m.newAddCapture(p1));
43 return;
44 }
45 action.simpleMove(from,to,ptype,false,P,m);
46 ptr+=offset.intValue();
47 to+=offset; m=m.newAddTo(offset);
48 }
49 }
50 if(notPromoteCapture) return;
51 while(ptr!=limitPtr){
52 assert(from.canPromote<P>() || to.canPromote<P>());
53 action.simpleMove(from,to,::osl::promote(ptype),true,P,m.promote());
54 ptr+=offset.intValue();
55 to+=offset;
56 m=m.newAddTo(offset);
57 }
58 Piece p1= *limitPtr;
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());
63 }
64 }
65 else{ // NoPromote
66 while(ptr!=limitPtr){
67 action.simpleMove(from,to,ptype,false,P,m);
68 ptr+=offset.intValue();
69 to+=offset; m=m.newAddTo(offset);
70 }
71 if(notPromoteCapture) return;
72 Piece p1= *limitPtr;
73 if(p1.canMoveOn<P>()){
74 m=m.newAddCapture(p1);
75 action.unknownMove(from,to,p1,ptype,false,P,m);
76 }
77 }
78 }
79 template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
80 inline void
81 generateLong(NumEffectState const&,Piece,const Piece *, Square,Action&,Int2Type<false>,Move,Ptype)
82 {
83 }
84
85 template <Player P,Ptype T,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
86 inline void
87 generateLong(NumEffectState const& state,Piece p,const Piece *ptr, Square pos,Action& action,Move moveBase,Ptype ptype)
88 {
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);
93 }
94
95 /**
96 * 短い利きの動き
97 * CanPromoteType - promote可能な動きの時
98 * MustPromoteType - 2段目の歩,3,4段目の桂馬
99 */
100 template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
101 void
102 generateShort(const Piece *ptr,Square from,Action& action,Int2Type<true>,Move moveBase,Ptype ptype)
103 {
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);
113 }
114 }
115
116 template <Player P,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
117 void
118 generateShort(const Piece */*ptr*/,Square /*from*/,Action& /*action*/,Int2Type<false>,Move /*moveBase*/,Ptype /*ptype*/)
119 {
120 }
121
122 template <Player P,Ptype T,class Action,PromoteType CanP,Direction Dir,bool notPromoteCapture>
123 void
124 generateShort(const Piece *ptr,Square from,Action& action,Move moveBase,Ptype /*ptype*/)
125 {
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>(),
130 moveBase,T);
131 }
132
133 template <Player P,Ptype T,class Action,PromoteType CanP,bool useDirMask,bool notPromoteCapture>
134 inline void
135 generatePtypePromote(const NumEffectState& state,Piece p, Action& action,Square from,int dirMask)
136 {
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);
145 }
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);
151 }
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);
157 }
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);
163 }
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);
166 }
167
168 template <Player P,Direction Dir,class Action,bool notPromoteCapture>
169 inline void
170 generateKingDir(const Piece *ptr, Square from,Action& action,unsigned int liberty,Move const& moveBase)
171 {
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);
181 }
182 }
183
184 template <Player P,class Action,bool useDirMask,bool notPromoteCapture>
185 inline void
186 generateKing(const NumEffectState& state, Action& action,Square pos,int dirMask)
187 {
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);
195 }
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);
199 }
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);
203 }
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);
207 }
208 }
209
210 template <Player P,class Action,bool useDirMask,bool notPromoteCapture>
211 inline void
212 generateLance(const NumEffectState& state, Piece p,Action& action,Square from,int dirMask)
213 {
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());
217 Square to=limit;
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);
223 switch(limity){
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;
228 goto escape4;
229 }
230 case 3:
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);
235 }
236 m=m.newAddTo(-offset); to-=offset;
237 goto escape4;
238 case 2:
239 if(!notPromoteCapture && p1.canMoveOn<P>()){
240 Move m1=m.newAddCapture(p1);
241 action.unknownMove(from,to,p1,PLANCE,true,P,m1.promote());
242 }
243 if(fromy==3) return;
244 m=m.newAddTo(-offset); to-=offset;
245 ycount=fromy-4;
246 goto escape2;
247 case 0:
248 m=m.newAddTo(-offset); to-=offset;
249 if(!notPromoteCapture)
250 action.simpleMove(from,to,PLANCE,true,P,m.promote());
251 goto join01;
252 case 1:
253 if(!notPromoteCapture && p1.canMoveOn<P>()){
254 action.unknownMove(from,to,p1,PLANCE,true,P,m.newAddCapture(p1).promote());
255 }
256 join01:
257 if(fromy==2) return;
258 m=m.newAddTo(-offset); to-=offset;
259 if(fromy==3){
260 if(!notPromoteCapture)
261 action.simpleMove(from,to,PLANCE,true,P,m.promote());
262 return;
263 }
264 ycount=fromy-4;
265 goto escape01;
266 default: assert(0);
267 }
268 escape01:
269 if(!notPromoteCapture)
270 action.simpleMove(from,to,PLANCE,true,P,m.promote());
271 m=m.newAddTo(-offset); to-=offset;
272 escape2:
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;
277 escape4:
278 while(ycount-->0){
279 action.simpleMove(from,to,LANCE,false,P,m);
280 m=m.newAddTo(-offset);
281 to-=offset;
282 }
283 }
284 return;
285 }
286
287 template <Player P,class Action,bool useDirMask,bool notPromoteCapture>
288 inline void
289 generatePawn(const NumEffectState& state, Piece p,Action& action,Square from,int dirMask)
290 {
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){
298 if(p1.isEmpty())
299 action.simpleMove(from,to,PAWN,false,P);
300 return;
301 }
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));
308 }
309 else{
310 Move m(from,to,PAWN,PTYPE_EMPTY,false,P);
311 action.unknownMove(from,to,p1,PAWN,false,P,m.newAddCapture(p1));
312 }
313 }
314 }
315 }
316}
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)
321 {
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();
327 if(T==KING){
328 generateKing<P,Action,useDirMask,notPromoteCapture>(state,action,from,dirMask);
329 }
330 else if(T==LANCE){
331 generateLance<P,Action,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
332 }
333 else if(T==PAWN){
334 generatePawn<P,Action,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
335 }
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);
343 else
344 generatePtypePromote<P,T,Action,NoPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
345 }
346 else
347 generatePtypePromote<P,T,Action,NoPromoteType,useDirMask,notPromoteCapture>(state,p,action,from,dirMask);
348 }
349
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)
354{
355 int num=p.number();
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);
363 }
364 else{
365 generatePtypeUnsafe<P,T,useDirMask>(state,p,action,dirMask);
366 }
367}
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)
372{
373
374 switch(p.ptype()){
375 case PPAWN: case PLANCE: case PKNIGHT: case PSILVER: case GOLD:
376 generatePtype<P,GOLD,useDirmask>(state,p,action,dirMask); break;
377 case PAWN:
378 generatePtype<P,PAWN,useDirmask>(state,p,action,dirMask); break;
379 case LANCE:
380 generatePtype<P,LANCE,useDirmask>(state,p,action,dirMask); break;
381 case KNIGHT:
382 generatePtype<P,KNIGHT,useDirmask>(state,p,action,dirMask); break;
383 case SILVER:
384 generatePtype<P,SILVER,useDirmask>(state,p,action,dirMask); break;
385 case BISHOP:
386 generatePtype<P,BISHOP,useDirmask>(state,p,action,dirMask); break;
387 case PBISHOP:
388 generatePtype<P,PBISHOP,useDirmask>(state,p,action,dirMask); break;
389 case ROOK:
390 generatePtype<P,ROOK,useDirmask>(state,p,action,dirMask); break;
391 case PROOK:
392 generatePtype<P,PROOK,useDirmask>(state,p,action,dirMask); break;
393 case KING:
394 generatePtype<P,KING,useDirmask>(state,p,action,dirMask); break;
395 default: break;
396 }
397}
398} // namespace move_generator
399} // namespace osl
400
401#endif /* _GENERATE_PIECE_MOVES_TCC */
402// ;;; Local Variables:
403// ;;; mode:c++
404// ;;; c-basic-offset:2
405// ;;; End:
406