Bonanzaの先手・後手の表現
昨日の記事で書き忘れましたが、昨日以降、このブログで単にBonanzaと表記するときは現時点で最新であるBonanza 6.0のことを指します。
とは言ってもBonanza 6.0も以前のソース(Bonanza 4.1.2あたり)からあまり大きな変更はないのですが。
今回は、Bonanzaの先後の表現について思っていることを書いておきます。
Bonanzaでは先後の定数は、shogi.hにある次のenumで表現されます。
enum { black = 0, white = 1 };
先手(chessに基づき、先手=black)ならば0、後手ならば1というわけですね。
ところが、この定数を用いずに判定している箇所があります。
例えば、csa.cです。これはcsaの読み込み部なのですが、ずいぶん開発の初期に書かれたコードのまま変わっていなくて、おそらくなおし忘れに属するものではないかと思います。
color = str_line[1] == '+' ? black : white; (中略) if ( color ) { pmin_posi->hand_white += handv; } else { pmin_posi->hand_black += handv; }
これは、CSA形式で"00AL"と書いたときに、盤上にない駒すべてが手駒ですよという省略表現が出来るのですが、そのための処理の一部です。
上の処理部は、先後を判定して("+"ならば先手の駒、"-"ならば後手の駒)、それをcolorという変数に代入し、そのあと、盤上の駒を駒種ごとにカウントして、不足している見当たらない駒を手駒として加算しています。
ところが if ( color ) という書き方は、後手を意味するcolorが非0であることを前提としているため、結局この書き方ですとここにマジックナンバーが埋め込まれているのと同様であり、次のように先後の値を入れ替えた場合、うまく動作しません。
enum { black = 1, white = 0 };
ということで、この問題の部分は次のように書かれるべきです。
if ( color == white ) { pmin_posi->hand_white += handv; } else { pmin_posi->hand_black += handv; }
とは言え、これはソースコードを読まない限り気づきにくいバグ(?)です。
なぜなら
1) black , whiteの定義を変更しない限り問題とならない。
2) そもそも"00AL"という記法を使ってCSA形式のファイルを出力する将棋ソフトが少ない。プログラムを書く立場になって考えれば、何も考えず手駒を順番に出力していくほうが簡単なので、わざわざ"00AL"と出力するようにはしない。
そういう意味では、あまり問題ではない、重箱の隅をつつくような話ですが、if ( color ) というような書き方自体は「マジックナンバーを埋め込んでいるのと同じですよ」ということを開発者の人たちに知っておいて欲しかったので今回書きました。