Bonanzaの指し手生成ルーチン完全解読(6)

■ Bonanzaの指し手生成ルーチン完全解読(6)


今回は指し手生成で使用している利き関係の残りのマクロについて解説する。


■ AttackBishop , AttackHorse , AttackRook , AttackDragon

extern bitboard abb_file_attacks[ nsquare ][ 128 ]; // 縦の利き
extern u32 ai_rook_attacks_r0[ nsquare ][ 128 ];    // 横の利き
extern bitboard abb_bishop_attacks_rl45[ nsquare ][ 128 ]; // 角の利き。右上から左下へ
extern bitboard abb_bishop_attacks_rr45[ nsquare ][ 128 ]; // 角の利き。左上から右下へ

// 飛車の利きを求める。
#define AttackRook(bb,i)     (bb) = AttackFile(i);                  \
                             (bb).p[aslide[i].ir0] |= AttackRank(i)

// 龍 = 飛 + 王
#define AttackDragon(bb,i)  AttackRook(bb,i); bb = bb | abb_king_attacks[i]

// 角の移動可能先を求める その1(左上から右下へ)
#define AttackDiag1(i)                                         \
          (abb_bishop_attacks_rr45[i]                        \
            [((ptree->posi.occupied_rr45.p[aslide[i].irr45]) \
               >> aslide[i].srr45) & 0x7f])

// 角の移動可能先を求める その2(右上から左下へ)
#define AttackDiag2(i)                                         \
          (abb_bishop_attacks_rl45[i]                        \
            [((ptree->posi.occupied_rl45.p[aslide[i].irl45]) \
               >> aslide[i].srl45) & 0x7f])

// 角の利きを求める。
// bb = bitboardで 
#define AttackBishop(bb,i)  bb = AttackDiag1(i) | AttackDiag2(i)

// 馬 = 角 + 王
#define AttackHorse(bb,i)   bb = AttackBishop(bb,i) | abb_king_attacks[i]

// 角の利き bitboardのpのindex別。
#define BishopAttack0(i) ( AttackDiag1(i).p[0] | AttackDiag2(i).p[0] )
#define BishopAttack1(i) ( AttackDiag1(i).p[1] | AttackDiag2(i).p[1] )
#define BishopAttack2(i) ( AttackDiag1(i).p[2] | AttackDiag2(i).p[2] )


■ 利き関係のマクロなど

// 先手による後手玉の打ち歩詰めのチェック
#define IsMateWPawnDrop(ptree,to) ( BOARD[(to)+9] == king                 \
                                     && is_mate_w_pawn_drop( (Tree*)ptree, to ) )

// 後手による先手玉の打ち歩詰めのチェック
#define IsMateBPawnDrop(ptree,to) ( BOARD[(to)-9] == -king                \
                                     && is_mate_b_pawn_drop( (Tree*)ptree, to ) )

/* perpetual check detections are omitted. */
// is_mate_b_pawn_dropは、後手による先手玉の打ち歩詰みチェック
// is_mate_w_pawn_dropは、先手による後手玉の打ち歩詰みチェック
// sq_drop = 歩を打とうとする場所
// 打ち歩詰めならばtrueが返る。
// 千日手による禁則になる打ち歩の王手のチェックはここに含まれない。
bool is_mate_b_pawn_drop( Tree * restrict ptree, BoardPos sq_drop );
bool is_mate_w_pawn_drop( Tree * restrict ptree, BoardPos sq_drop );

// ifromからitoへの障害物を表現するbitboard
// ifromとitoが縦、横、斜めの関係になければすべてのbitがゼロであるbitboard
// さもなくば、その間のマス目が1であるようなbitboard
// (ただしそのbitboardでifrom,itoに相当する箇所は0)
extern bitboard abb_obstacle[ nsquare ][ nsquare ];

// 先手の利きが、sqの地点に到達しているか。
bool is_black_attacked( const Tree * restrict ptree, BoardPos sq );

// 後手の利きが、sqの地点に到達しているか。
bool is_white_attacked( const Tree * restrict ptree, BoardPos sq );

// sqに利いている駒を列挙する。先後の区別なし。
// sqの値別に場合分けすべきだと思う。
bitboard attacks_to_piece( const Tree* restrict ptree, BoardPos sq );

// turnのほうに王手がかかっているか。
#define InCheck(turn)                                        \
         ( (turn) ? is_white_attacked( ptree, SQ_WKING )     \
                  : is_black_attacked( ptree, SQ_BKING ) )