3 #ifndef OSL_CHECKMATE_IMMEDIATE_CHECKMATE_TCC
4 #define OSL_CHECKMATE_IMMEDIATE_CHECKMATE_TCC
24 PieceMask effect=state.effectSetAt(pos)&
26 mask_t mask=effect.getMask(1);
27 mask&=(state.piecesOnBoard(P).getMask(1)<<8);
31 int num=mask.takeOneBit()+NumBitmapEffect::longToNumOffset;
34 if(from.
isU<P>(pos))
goto found;
42 for(
int i=0;i<3;i++,pos+=offset){
43 Piece p=state.pieceAt(pos);
45 if(state.countEffect(P,pos)==1)
return true;
63 if((canMoveMask.
uint64Value()&(0x10000<<
U))==0)
return false;
64 PieceMask effect=state.effectSetAt(to)&state.effectSetAt(pos);
65 mask_t mask=effect.getMask(1);
66 mask&=(state.piecesOnBoard(P).getMask(1)<<8);
69 int num=mask.takeOneBit()+NumBitmapEffect::longToNumOffset;
73 if(to+offset != pos)
continue;
74 if(state.countEffect(P,to)==1)
return true;
76 if(!state.pieceAt(to).isEmpty())
return false;
79 Piece p=state.pieceAt(pos1);
81 state.countEffect(P,pos1)==1){
87 template<Player P,
bool canDrop,
bool setBestMove>
96 Piece p=state.pieceAt(pos);
98 !state.hasEffectByNotPinned(altP,pos)
100 mask_t mask=state.effectSetAt(pos).getMask<
KNIGHT>()&mask1;
102 if(blockingVerticalAttack<P>(state,pos) ||
103 blockingDiagonalAttack<P>(state,pos,
target,canMoveMask))
return false;
106 Piece p1=state.pieceOf(num);
112 else if(canDrop && p.
isEmpty()){
113 if(blockingVerticalAttack<P>(state,pos) ||
114 blockingDiagonalAttack<P>(state,pos,
target,canMoveMask))
return false;
124 template<Player P,
bool setBestMove>
129 if((canMoveMask.
uint64Value()&0xff00)!=0)
return false;
131 mask&=state.piecesOnBoard(P).getMask<
KNIGHT>();
132 mask&= ~state.promotedPieces().getMask<
KNIGHT>();
133 mask&= ~state.pinOrOpen(P).getMask<
KNIGHT>();
134 if(state.hasPieceOnStand<
KNIGHT>(P)){
136 if(hasKnightCheckmate<P,true,setBestMove>(state,target,pos,canMoveMask,bestMove,mask))
139 return hasKnightCheckmate<P,true,setBestMove>(state,
target,pos,canMoveMask,bestMove,mask);
143 if(hasKnightCheckmate<P,false,setBestMove>(state,target,pos,canMoveMask,bestMove,mask))
146 return hasKnightCheckmate<P,false,setBestMove>(state,
target,pos,canMoveMask,bestMove,mask);
150 template<Player P,
bool setBestMove>
154 unsigned int dropMask=(canMoveMask.
uint64Value()&0xff)
165 NumBitmapEffect effect=state.effectSetAt(drop);
166 mask_t longEffect=effect.getMask(1)&NumBitmapEffect::longEffectMask();
167 longEffect&=(state.piecesOnBoard(P).getMask(1)<<8);
168 if(longEffect.any()){
173 NumBitmapEffect effect1=state.effectSetAt(pos);
174 if(effect1.countEffect(P)>1)
continue;
175 mask_t longEffect1=effect1.getMask(1)&longEffect;
176 if(!longEffect1.any())
continue;
178 int num=longEffect1.takeOneBit()+NumBitmapEffect::longToNumOffset;
181 }
while(blockingMask!=0);
186 bestMove=
Move(drop,ptype,P);
197 template<osl::Player P,
bool setBestMove>
204 while(dropPtypeMask.any()){
206 if(state.hasPieceOnStand(P,ptype) &&
207 detail::slowCheckDrop<P,setBestMove>(state,
target,ptype,canMoveMask,
214 template<osl::Player P,
bool setBestMove>
221 int dx=target.
x()-pos.
x();
222 int dy=target.
y()-pos.
y();
223 if(abs(dx)==1 && abs(dy)==1){
226 Piece p1=state.pieceAt(pos1);
236 Square pos2=pos+Offset(2*dx,0);
237 if(state.pieceAt(pos2).template canMoveOn<altP>()){
238 NumBitmapEffect effect2=state.effectSetAt(pos2);
239 if(effect2.countEffect(P)==0 ||
240 (effect2.countEffect(P)==1 &&
241 effect2.test(p.
number())))
251 if(p.
square()==target-Offset(0,2*dy) &&
252 state.hasEffectByPiece(p1,pos))
259 Piece p1=state.pieceAt(pos1);
261 Square pos2=pos+Offset(0,2*dy);
263 if(state.pieceAt(pos2).template canMoveOn<altP>()){
264 NumBitmapEffect effect2=state.effectSetAt(pos2);
265 if(effect2.countEffect(P)==0 ||
266 (effect2.countEffect(P)==1 &&
267 effect2.test(p.
number())))
276 if(p.
square()==target-Offset(2*dx,0) &&
277 state.hasEffectByPiece(p1,pos))
296 NumBitmapEffect effect2=state.effectSetAt(pos);
297 effect2.reset(num+8);
298 mask_t longEffect2=effect2.getMask(1)&NumBitmapEffect::longEffectMask();
299 longEffect2&=(state.piecesOnBoard(P).getMask(1)<<8);
303 NumBitmapEffect effect1=state.effectSetAt(pos1);
304 int count=effect1.countEffect(P);
306 if(effect1.test(num)) count--;
307 if(count==0)
return false;
309 mask_t longEffect1=effect1.getMask(1)&longEffect2;
310 while(longEffect1.any()){
311 int num1=longEffect1.takeOneBit()+NumBitmapEffect::longToNumOffset;
314 if(count==0)
return false;
316 }
while (mask.any());
322 state.pieceAt(pos).ptype(),
328 template<osl::Player P,
bool setBestMove>
340 if(num !=
EMPTY_NUM && state.pieceOf(num).isOnBoardByOwner<altP>())
349 if(slowHasCheckmateMoveDirPiece<P,setBestMove>(state,target,canMoveMask,d,pos,p,pptype,bestMove))
return true;
356 if(slowHasCheckmateMoveDirPiece<P,setBestMove>(state,target,canMoveMask,d,pos,p,ptype,bestMove))
return true;
361 template<osl::Player P,
bool setBestMove>
366 if(state.countEffect(P,pos)<2 &&
368 PieceMask pieceMask=state.piecesOnBoard(P)&state.effectSetAt(pos);
372 for(
int i=0;i<=PieceMask::numToIndex(40);i++){
373 mask_t mask=pieceMask.getMask(i);
375 const int num=mask.takeOneBit()+i*32;
376 if(hasCheckmateMoveDirPiece<P,setBestMove>(state,target,canMoveMask,d,pos,state.pieceOf(num),bestMove))
return true;
383 template<osl::Player P,
bool setBestMove>
388 assert(! state.inCheck());
390 mask_t mask2=mask_t::makeDirect((canMoveMask.
uint64Value()>>24)&0xff);
393 if(hasCheckmateMoveDir<P,setBestMove>(state,target,canMoveMask,d,bestMove))
return true;
398 template<osl::Player P>
407 if(hasCheckmateMove<P,false>(state,target,canMoveMask,dummy))
return true;
408 if(detail::hasCheckmateMoveKnight<P,false>(state,target,canMoveMask,dummy))
return true;
409 return hasCheckmateDrop<P,false>(state,
target,canMoveMask,dummy);
412 template<osl::Player P>
421 King8Info canMoveMask(state.Iking8Info(altP));
422 return hasCheckmateMove<P>(state, canMoveMask);
425 template<osl::Player P>
430 assert(! state.inCheck());
433 if(hasCheckmateMove<P,true>(state,target,canMoveMask,bestMove))
return true;
434 if(detail::hasCheckmateMoveKnight<P,true>(state,target,canMoveMask,bestMove))
return true;
435 return hasCheckmateDrop<P,true>(state,
target,canMoveMask,bestMove);
438 template<osl::Player P>
444 King8Info canMoveMask(state.Iking8Info(altP));
445 return hasCheckmateMove<P>(state, canMoveMask,
target, bestMove);