2012/07/29
■ 王手とピン駒の求め方
隣接による王手は王の位置に相手駒の利きをorすれば良い
pos=bit_fscan(p->bitboard[BLACK][P_OU]); // 王の位置 and128(stack->check,p->bitboard[WHITE][P_FU],pos2bb[pos-9]); // 歩 andor128(stack->check,p->bitboard[WHITE][P_KEI],attack_kei_b[pos]); // 桂 andor128(stack->check,p->bitboard[WHITE][P_GIN],attack_gin_b[pos]); // 銀 andor128(stack->check,p->zenkin[WHITE],attack_kin_b[pos]); // 金・成金 andor128(stack->check,p->bitboard[WHITE][P_N_KAKU],attack_uma[pos]); // 馬 andor128(stack->check,p->bitboard[WHITE][P_N_HISH],attack_ryu[pos]); // 竜
stack->checkには王への利きが入っている。
飛び利き王手は、たとえば飛車の横利きで王手されている時、
K0000000R
王からの利きデータで飛車の位置を出す(to)
王の位置からと飛車の位置までの間の枡を求める
011111110
これと全駒位置とandをとる(between)
もし立っているビット数が0なら間に駒が無いので、飛び利き王手である
もし立っているビット数が1ならピン駒である(自分の駒か相手の駒かの判定は不必要、手生成の時相手の駒は動かせない)
betweenは王手を受けるとき使うので保存しておく(合駒位置である)
and128(t,slider_attack[pos],piece); // 飛び利きをしている駒を探す if ( test128(t) ) { // 飛び利きをしている駒があった BITBOARD between, pin; to=bit_rscan(t); // 飛び利きをしている駒の位置 and128(between,slider_attack[pos],slider_opposite[to]); // 間のマスを抽出 and128(pin,between,p->occ); // 間の駒を抽出 n=bit_popcount(pin); // 間の駒の数 if ( n == 0 ) { // 飛び利き王手 or128(stack->check,stack->check,t); // 王手している駒 stack->between=between; // 合い駒生成で使う } else if ( n == 1 ) { // ピン駒である to=bit_fscan(pin); // ピン駒の位置 stack->pin_dir[to]=dir; // ピンされている方向 }