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

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


今回は、指し手生成関係の関数の一覧を書いておく。


■ 指し手生成関係の関数


Bonanzaの指し手生成関係の関数は以下のものがある。b_gen_XXXは、先手用。w_gen_XXXは後手用。第二引数にMove*を渡しているが、ここに指し手が格納される。例えば、3つの指し手が生成された場合、*(pmove + 0) , *(pmove + 1) , *(pmove + 2) にそれらの指し手が格納され、pmove + 3 を関数の返し値として返す。

// 指し手生成。駒捕獲なし。先手用/後手用。詳しくはgennocap.cppを。
Move* b_gen_nocaptures( const Tree * restrict ptree, Move * restrict pmove );
Move* w_gen_nocaptures( const Tree * restrict ptree, Move * restrict pmove );

// 指し手生成。駒捕獲あり。駒捕獲しないが、↑のX_gen_nocapturesで生成しなかったものもここで生成。
Move* b_gen_captures( const Tree * restrict ptree, Move * restrict pmove );
Move* w_gen_captures( const Tree * restrict ptree, Move * restrict pmove );

// 指し手生成。打つ手。
Move* b_gen_drop( const Tree * restrict __ptree__, Move* restrict pmove );
Move* w_gen_drop( const Tree * restrict __ptree__, Move* restrict pmove );

// 王手に対する応手生成。王手されている局面を渡すこと。
Move* b_gen_evasion( const Tree * restrict __ptree__, Move * restrict pmove );
Move* w_gen_evasion( const Tree * restrict __ptree__, Move * restrict pmove );

// 王手のみ生成。
Move* b_gen_checks(const Tree * restrict ptree, Move * restrict pmove );
Move* w_gen_checks(const Tree * restrict ptree, Move * restrict pmove );


// 駒は取るが成らない指し手を生成その2。
Move* b_gen_cap_nopro_ex2( const Tree * restrict ptree , Move * restrict pmove );
Move* w_gen_cap_nopro_ex2( const Tree * restrict ptree , Move * restrict pmove );

// 駒を捕獲せずに成らない手の生成その2
Move* b_gen_nocap_nopro_ex2( const Tree * restrict ptree , Move* restrict pmove );
Move* w_gen_nocap_nopro_ex2( const Tree * restrict ptree , Move* restrict pmove );


// -- 手番に応じて自動的に適切なほうを振り分けるためのマクロ

#define GenCaptures(turn,pmove) ( (turn) ? w_gen_captures( ptree, pmove )   \
                                         : b_gen_captures( ptree, pmove ) )

#define GenNoCaptures(turn,pmove)                                             \
                               ( (turn) ? w_gen_nocaptures( ptree, pmove )  \
                                        : b_gen_nocaptures( ptree, pmove ) )

#define GenDrop(turn,pmove)     ( (turn) ? w_gen_drop( ptree, pmove )       \
                                         : b_gen_drop( ptree, pmove ) )

#define GenCapNoProEx2(turn,pmove)                                 \
                ( (turn) ? w_gen_cap_nopro_ex2( ptree, pmove )   \
                         : b_gen_cap_nopro_ex2( ptree, pmove ) )

#define GenNoCapNoProEx2(turn,pmove)                                \
                ( (turn) ? w_gen_nocap_nopro_ex2( ptree, pmove )  \
                         : b_gen_nocap_nopro_ex2( ptree, pmove ) )

#define GenEvasion(turn,pmove)                                  \
                ( (turn) ? w_gen_evasion( ptree, pmove )      \
                         : b_gen_evasion( ptree, pmove ) )

#define GenCheck(turn,pmove)                                  \
                ( (turn) ? w_gen_checks( ptree, pmove )      \
                         : b_gen_checks( ptree, pmove ) )


X_gen_cap_nopro_ex2 と X_gen_nocap_nopro_ex2はいままで解説していなかったが、movegenex.cに書かれている。「歩・角・飛」の場合、gencapでは、敵の駒を取ろうと取るまいと成れるなら成るという指し手を生成していた。gencapは名ばかりで、「駒を捕獲する手」ではなく、評価値が大きく変動する手を生成する指し手生成関数であることはすでに解説したが、ここで生成が漏れている手がある。


それは、「歩を(成れるのに)不成で駒をとる手」や「歩を(成れるのに)不成で駒をとらない手」などである。これらを生成するのが、X_gen_cap_nopro_ex2(駒をとるが成れるのに成らない手)や、X_gen_nocap_nopro_ex2(駒を取らずにかつ成れるのに成らない手)である。あまり呼び出されない関数だが、一応この2つも用意して、指し手を網羅できるようになっている。