Bonanzaの指し手生成ルーチン完全解読(7)
■ Bonanzaの指し手生成ルーチン完全解読(7)
今回は、一通り利きに関するマクロや関数の紹介が終わったのでis_pinned_on_black_kingの実装を読んでみる。
■ is_pinned_on_black_kingの実装
この実装は以下のようになっている。なお、ソース自体は私が少し手を入れている。
説明の代わりにコメントを読んでいただきたい。
// isquareにある先手の駒が、idirec方向にpinされているのか。 // この駒を動かすと先手玉を取られてしまうときtrue。 bool is_pinned_on_black_king( const Tree * restrict ptree, BoardPos isquare, Direction idirec ) { u32 ubb_attacks; bitboard bb_attacks, bb_attacker; switch ( idirec ) { // 横方向にpinされているなら、飛車によってしかpinされている可能性がないので // それだけ調べれば良い。 case direc_rank: ubb_attacks = AttackRank( isquare ); if ( ubb_attacks & (BB_BKING.p[aslide[isquare].ir0]) ) { // RD = 飛と龍(rook & dragon) return (ubb_attacks & BB_W_RD.p[aslide[isquare].ir0]) !=0; } break; // 縦方向にpinされているなら飛車か香だろう。 case direc_file: bb_attacks = AttackFile( isquare ); if ( ( bb_attacks & BB_BKING ).ToU() ) { // 香 + 飛龍 bb_attacker = (BB_WLANCE & abb_minus_rays[isquare] ) | BB_W_RD; return ( bb_attacks & bb_attacker ).ToU()!=0; /* return! */ } break; // 斜め方向にpinされているなら角と馬だろう。 case direc_diag1: bb_attacks = AttackDiag1( isquare ); if ( ( bb_attacks & BB_BKING ).ToU() ) { // BH = Bishop + Horse return ( bb_attacks & BB_W_BH ).ToU() != 0; /* return! */ } break; case direc_diag2: bb_attacks = AttackDiag2( isquare ); if ( ( bb_attacks & BB_BKING ).ToU() ) { return ( bb_attacks & BB_W_BH ).ToU() != 0; /* return! */ } break; default: // こう書いて心持ち高速化 __assume(0); } return false; }