最新

Miyako Shogi System

コツコツ改良、へこたれない
2014| 1|
2013| 12|
2012| 01| 02| 04| 05| 06| 07| 08| 09| 10|
2011| 01| 02| 03| 04| 05| 07| 08| 10| 11| 12|
2010| 02| 03| 06| 07| 08| 09| 10| 12|

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;  // ピンされている方向
  }

2012/07/28

Bitboardによる手の生成(駒を取る手)

駒を取る銀の手の生成。隣接手は簡単。

target=p->bitboard[WHITE][P_OCCUPY];  // 相手駒の位置
org=p->bitboard[BLACK][piece];
while ( test128(org) ) {  // 駒がある
  from=bit_fscan(&org);  // 駒位置
  bit_reset(org,from);   // 駒を消す
  t.x=and128(attack_gin_b[from],target);  // 先手銀の利きのbitboardを押し付ける
  while ( test128(t) ) {  // 利きのある数
    to=bit_fscan(&t); // 移動先の位置
    bit_reset(t,to);  // 移動先を消す
    pin_check()
    手の格納
  }
}

飛び駒の取る手生成には、邪魔駒の判定が必要(相手駒へ利きがあるか)。

target=p->bitboard[WHITE][P_OCCUPY];  // 相手駒の位置
t.x=and128(slider_attack[from],target);  // 先手飛び駒の利きのbitboardを押し付ける
while ( test128(t) ) {  // 利きのある数
  to=bit_fscan(&t); // 移動先の位置
  bit_reset(t,to);  // 移動先を消す
  t.x=and128(slider_attack[from],slider_opposite[to]);	// 間の枡を抽出
   if ( !andtest128(t,p->occ) ) {  // 邪魔駒が無い
     pin_check()
     手の格納
   }
 }
リンクはご自由に (Miyako Shogi System Kyoto Japan)

ダウンロードのページ

Lighttpd

DreamPlug