打一手詰
もっとさぼれるところがあると思う。
// // 簡易1手詰(駒打ち) // 呼び出し元で持ち駒があることは確認している // template <Player_t p,Player_t op> inline Move Board::hMate1PlyDrop() { // // 玉の近傍に駒を打って詰ませる const int pos=king[op]; int to; // // 桂馬を打って詰むかな? if(Hand(p,Knight)){ BitBoard b=((p==Black)?bb_white_knight_attack[pos]:bb_black_knight_attack[pos])-occupied; // 桂馬の利きは近傍8箇所じゃないから最初に処理 while((to=b.BitScanClear())!=-1){ //if(!isAttacked(op,to)) continue; // 桂馬の場合は自利きは要らない if(hCanKingEscapeByDrop<op>(pos,to,((p==Black)?bb_black_knight_attack[to]:bb_white_knight_attack[to]))) continue; if(hCanCapture<op>(to)) continue; return Move(p,to,Knight,0); } } if(!(hand[p]&(HANDLANCE|HANDSILVER|HANDGOLD|HANDBISHOP|HANDROOK))){ return Move(0); // 歩・桂馬以外の持ち駒無し } // BitBoard b_drop=bb_king_attack[pos]-occupied; // 玉近傍に駒が打てる場所(玉の回り8箇所-既に駒のある場所) if(b_drop.isZero()) return Move(0); // 打てる場所がない BitBoard b_put(0); if(Hand(p,Silver)) b_put|=((p==Black)?bb_white_silver_attack[pos]:bb_black_silver_attack[pos]); else if(Hand(p,Bishop)) b_put|=bb_cross[pos]; if(Hand(p,Gold)) b_put|=((p==Black)?bb_white_gold_attack[pos]:bb_black_gold_attack[pos]); else if(Hand(p,Rook)) b_put|=bb_plus[pos]; else if(Hand(p,Lance)) b_put|=((p==Black)?bb_white_pawn_attack[pos]:bb_black_pawn_attack[pos]); b_drop&=b_put; if(b_drop.isZero()) return Move(0); // 打って王手になる場所がない BitBoard b=b_drop; foreach_BitScanClear(b,to, \ { \ if(!isAttacked(op,to)){ \ b_drop.Off(to); \ } \ } \ ); if(b_drop.isZero()) return Move(0); // 自利きのある打てる場所がない if(Hand(p,Rook)){ // 飛車を打って詰ませる BitBoard b=b_drop&bb_plus[pos]; // 飛車を打って王手になる場所 while((to=b.BitScanClear())!=-1){ // 飛車が打てる升目を調べる if(hCanKingEscapeByDrop<op>(pos,to,(bb_file[to]|bb_rank[to]))) continue; if(hCanCapture<op>(to)){ b_drop.Off(to); // 打った駒が玉以外の駒で取られるのであれば、ここには何を打っても詰まない continue; // 打った飛車が玉以外の駒で取れるようだ } return Move(p,to,Rook,0); // 逃げられないなら詰み } }else if(Hand(p,Lance) && ((p==Black)?(pos<72):(pos>=9))){ // 飛車を打って詰まないなら香車を打っても詰まない to=(p==Black)?(pos+9):(pos-9); if(board[to]==Empty){ if(hCanKingEscapeByDrop<op>(pos,to,(p==Black)?bb_black_lance_attack[to]:bb_white_lance_attack[to])){ // 玉が逃げて詰まない }else if(hCanCapture<op>(to)){ b_drop.Off(to); // 打った香車が玉以外の駒で取れるようだ }else{ return Move(p,to,Lance,0); // 詰んだ } } } if(Hand(p,Bishop)){ BitBoard b=b_drop&bb_cross[pos]; // 角を打って王手になる場所 while((to=b.BitScanClear())!=-1){ if(hCanKingEscapeByDrop<op>(pos,to,bb_left[to]|bb_right[to])) continue; if(hCanCapture<op>(to)){ b_drop.Off(to); // 打った駒が玉以外の駒で取られるのであれば、ここには何を打っても詰まない continue; } return Move(p,to,Bishop,0); // 逃げられないなら詰み } } if(Hand(p,Gold)){ BitBoard b=((b_drop&((p==Black)?bb_white_gold_attack[pos]:bb_black_gold_attack[pos]))); if(Hand(p,Rook)) b-=((p==Black)?bb_black_pawn_attack[pos]:bb_white_pawn_attack[pos]); // 飛車で詰まないなら尻金でも詰まない while((to=b.BitScanClear())!=-1){ if(hCanKingEscapeByDrop<op>(pos,to,((p==Black)?bb_black_gold_attack[to]:bb_white_gold_attack[to]))) continue; if(hCanCapture<op>(to)) continue; // (b_drop.Offしなくても大丈夫) return Move(p,to,Gold,0); } } if(Hand(p,Silver) && !(Hand(p,Bishop)&&Hand(p,Gold))){ // 角金で詰まないなら、銀を持っていても詰まない BitBoard b=(b_drop&((p==Black)?bb_white_silver_attack[pos]:bb_black_silver_attack[pos])); if(Hand(p,Gold)){ // 金で詰まないのであれば上から打つ詰みはない b-=((p==Black)? (bb_white_gold_attack[pos]&bb_white_silver_attack[pos]): (bb_black_gold_attack[pos]&bb_black_silver_attack[pos])); }else if(Hand(p,Bishop)){ b&=((p==Black)?bb_white_gold_attack[pos]:bb_black_gold_attack[pos]); // 角で詰まないのであれば尻銀は考えなくて良い } while((to=b.BitScanClear())!=-1){ if(hCanKingEscapeByDrop<op>(pos,to,((p==Black)?bb_black_silver_attack[to]:bb_white_silver_attack[to]))) continue; if(hCanCapture<op>(to)) continue; return Move(p,to,Silver,0); } } return Move(0); }