Bonanzaが用いているbitboardの定数配列の意味【前編】

■ Bonanzaが用いているbitboardの定数配列の意味【前編】


Bonanzaではbitboardの定数配列をいくつか持っている。これらの初期化は、ファイルから値を読み込むのではなく、プログラムのなかで動的に初期化している。


初期化している場所はini.cのini_tablesであり、この部分のソースを読めばそれらの配列の意味が明確になる。


ただし、abb_mask,abb_mask_rl90,abb_mask_rl45,abb_mask_rr45に関しては、この配列を用いている指し手生成の部分のソースを読まないと意味が確定しないので、今回はこれらの配列に関しては説明しない。

  bitboard_t abb_plus1dir[ nsquare ];   // 右
  bitboard_t abb_plus8dir[ nsquare ];   // 左下
  bitboard_t abb_plus9dir[ nsquare ];   // 下
  bitboard_t abb_plus10dir[ nsquare ];  // 右下
  bitboard_t abb_minus1dir[ nsquare ];  // 左
  bitboard_t abb_minus8dir[ nsquare ];  // 右上
  bitboard_t abb_minus9dir[ nsquare ];  // 上
  bitboard_t abb_minus10dir[ nsquare ]; // 左上

これらはローカル変数として定義されているので、一時的に使用しているbitboard配列である。


例えば、abb_plus8dir[isquare]ならば、盤面上の座標isquareから、プラス8(これは盤面上で右下方向を意味する)方向がすべて1になっているbitboardである。


ini_tablesでこの直後に出てくるadirec[ifrom][ito]は、ifromとitoとの位置関係が、縦、横、斜めの位置関係にあるかを判定するためのテーブルである。


このadirecで使用する定数はshogi.hで定義されており、次のような意味になっている。(なおこのblogで引用しているBonanzaのソースは私がコメントを追記したり、ソースを多少書き換えたりしていることが多々あることを改めて補足しておきたい。)

// 方向を意味するbit
enum Direction
{
  direc_misc           = b0000,						// 方向が縦横斜めの関係にない場合
  direc_file           = b0010, /* | */		// 方向が縦方向の関係である場合
  direc_rank           = b0011, /* - */		// 方向が横方向の関係にある場合
  direc_diag1          = b0100, /* / */		// 方向が右上から左下方向の斜め関係にある場合
  direc_diag2          = b0101, /* \ */		// 方向が左上から右下方向の斜め関係にある場合
  flag_cross           = b0010, // 縦と横ならば持ているbitmask
  flag_diag            = b0100	 // 斜め方向ならば持っているbitmask
};

このような意味になっている。abb_obstacleは次のように初期化されるので、これは、以下のコメントにあるようにifromからitoへの障害物を意味するbitboardである。

  // abb_obstacleは、ifromからitoへの障害物を設定する
  // ifromとitoが縦、横、斜めの関係になければゼロ
  // さもなくば、その間のマス目が1であるようなbitboard
  // (ただしそのbitboardでifrom,itoに相当する箇所は0)
  for (int ifrom = 0; ifrom < nsquare; ifrom++ )
    for (int ito = 0; ito < nsquare; ito++ )
      {
        abb_obstacle[ifrom][ito].Init(); // まずゼロクリア

				// ifrom > itoならば
        if ( ifrom-ito > 0 ) switch ( adirec[ifrom][ito] )
          {
          // ifromから見て..
          case direc_rank: // 左
            abb_obstacle[ifrom][ito].Xor(
                   abb_minus1dir[ito+1], abb_minus1dir[ifrom] );
            break;
          case direc_file: // 上
            abb_obstacle[ifrom][ito].Xor(
                   abb_minus9dir[ito+9], abb_minus9dir[ifrom] );
            break;
          case direc_diag1: // 右上
            abb_obstacle[ifrom][ito].Xor(
                   abb_minus8dir[ito+8], abb_minus8dir[ifrom] );
            break;
          case direc_diag2: // 左上
            abb_obstacle[ifrom][ito].Xor(
                   abb_minus10dir[ito+10], abb_minus10dir[ifrom] );
            break;
          }
        else switch ( adirec[ifrom][ito] )
          {
          case direc_rank: // 右
            abb_obstacle[ifrom][ito].Xor(
                   abb_plus1dir[ito-1], abb_plus1dir[ifrom] );
            break;
          case direc_file: // 下
            abb_obstacle[ifrom][ito].Xor(
                   abb_plus9dir[ito-9], abb_plus9dir[ifrom] );
            break;
          case direc_diag1: // 左下
            abb_obstacle[ifrom][ito].Xor(
                   abb_plus8dir[ito-8], abb_plus8dir[ifrom] );
            break;
          case direc_diag2: // 右下
            abb_obstacle[ifrom][ito].Xor(
                   abb_plus10dir[ito-10], abb_plus10dir[ifrom] );
            break;
          }
      }


■ まとめ


今回はBonanzaが用いているbitboardの定数配列のうちの半分ぐらい解説した。残り半分は後編で説明する。


これらの定数配列の意味がわかるとBonanzaのソースがとても読みやすくなる。