予定変更、入玉等の実装について考える
正確に書くと、入玉・千日手・連続王手の千日手・打ち歩詰めの対処。けど長いんで“入玉等”と書きます。
本当は王将周辺の利きの評価をいじる予定だったんですが、時間がかかりそう&頭が入玉モードになっているので。
まず、局面クラスは過去の局面の履歴を初手から全部持ってるんで、千日手とかの検出はここで可能。
で、後は検出した情報をどこでどうやって使うか。
探索ルーチンで使うとなると、既存のαβとABC探索・多分これから作るMTD(f)と、最低3つのクラスで修正が必要になって、後々のメンテとか考えると、ちょっと回避したいところです。
かと言って評価関数で使う*1のは、LEAFノード以外で入玉等になった場合にちゃんと動くかどうか不安です。
という訳で、GPWの時にCSAの山田剛さんに教えてもらった、「入玉宣言勝ちという特別な手を作る」方向で検討中。
一昨日のコメント欄でもちょこっと書きましたが、修正内容は以下の通り。
- 局面クラスで合法手一覧を生成する際に、入玉宣言勝ちが可能なら“宣言勝ち”という特別な手も合法手一覧に追加する。
- 宣言勝ちを“指した”後に合法手一覧を生成しようとした場合、合法手無しとして扱う(詰んでいる場合と同様の処理)
こうしておくと、探索ルーチンには何の修正もしなくても、“宣言勝ち”を“指した”後のノードの評価値は、宣言した側から見て+∞になります。
で、この方法だと入玉・連続王手の千日手・打ち歩詰めには対処可能ですが、千日手だけは対処不可能です。
なので、千日手に関しては、千日手が成立した時点で合法手を“千日手引き分け”という手だけにしておき、探索ルーチン内ではその手を指したら評価値を0なり-∞なりにしてやろうと考えています。
以上をまとめると、局面クラスで入玉等の検出&合法手への宣言の追加、探索ルーチンで千日手の場合のみ対処となるので、修正する必要のあるクラスは割と少なくなります。
ついでに、強化学習していると打ち歩ステイルメイトがたまに起きるので、打ち歩詰めとちゃんと区別出来る様にしておきます。
こっちは「合法手が無い場合に、王手がかかっていれば詰み、かかっていなければステイルメイト」という単純な判断で区別出来るでしょう。
そんな訳で、今日はコードの修正は無し。王将周辺の利きを無効にしたバージョンで学習させておきます。