前回の記事で将棋アプリの静的評価関数内で玉を2枚持っていれば勝ち(玉を取れば勝ち)と判定していて、ステイルメイト=引き分けというチェスのルールに対応出来ないことを書きましたが、ステイルメイトに対応するために2つのやり方を試してみました。方法1:詰み判定(ゲーム終了判定)処理を追加する王様が取られていたらゲーム終了とするのではなく、手番と駒の利きと王手(チェック)の有無などの情報を駆使して現時点の局面が詰んでいる(チェックメイト状態)かどうかの判断を含めて評価関数内で評価するやり方です。王様(キング)が取られているかどうかだけを見て判断するより処理は複雑で重い処理になります。いう場合は先手勝ち、こういう場合は王手放置で後手負け、こういう場合はステイルメイトで引き分け、と評価関数内でいちいち定義していくのでif文、case文だらけになり重たい処理になります。その分先読みの深さを一手から二手省略できるのでメリットも大きいです。じつは以前にも将棋アプリで思考時間短縮になるかと思い試してみたことがあったのですが、思ったほど効果が上がらなかったのでリリース版には採用しませんでした。それに一つ一つのケースについて勝ち負けの判定をするので漏れが生じてバグが発生し易いのも採用を見送った理由です。あと、この方法で作ると王様を取る以前の段階で評価しますので、ユーザーに相手玉を取るところまで指し手を進めさせることが出来なくなりますが、チェスの場合もチェックメイト(詰み)の段階でゲームを終えるのが一般的なようなので問題ないと思います。方法2:一定条件下で追加で先読みする王様(キング)を二つ持っていれば勝ちという評価関数は変更せずに、先読みの過程でキングがチェックされていなくてキングを動かせない局面の場合には指定されている先読みの深さを無視して、さらに一手余計に先読みするという方法です。以前の記事に書いた打ち歩詰めチェックの方法と同じです。ステイルメイトの局面である可能性がある時は、先読み時に指定する何手先まで読むかを制限する引数を無視してさらに一手読むようにするところがミソです。打ち歩詰めと違って2手読む必要はなく、次にキングが取られるかどうかだけを見ればいいので追加で先読みするのは一手(チェス流に言えば0.5手読み)で済みます。打ち歩詰めチェックよりは楽だし、十分実績のある既存のコードなので新たなバグが発生する可能性も低いと思って、まずこの方法で実装しました。このサイトによるとステイルメイトの定義は以下のようになっています。チェックされていないキング以外に動かせる駒がない。キングをどこに動かしても取られてしまう。(自殺行為でルール上そのようなマスには移動できない)条件1.と3.は軽い処理で済みますが、2.の条件をチェックするには結局全ての駒の動きを調べる必要があるので、それをするぐらいならもう一手余分に先読みさせて済まそうという考え方です。条件1.と3.を満たす局面が現れた時だけ条件2.を調べて、勝ち(最大値)か負け(最小値)の評価値が返ってきたら評価値を強制的にDraw(評価値=0)に変更するということです。打ち歩詰め対策の時は評価値に−1を掛けて打ち歩詰めをした方が負けになるようにしましたが、ステイルメイトの場合は評価が逆転するわけではないので0に置き換えるだけでいいと思います。例1:Bf6のステイルメイトを避ける(クリックで画像拡大)前回の記事で挙げた例ではとりあえずステイルメイトを避けるようになりました。Nf7(Knightをf7に移動する手)がこの局面での最善手かどうかは分かりません。例2:c8=Qのステイルメイトを避ける(クリックで画像拡大)修正前はポーンがc8に移動してQueenに成っていた(=ステイルメイト)のですが、修正後はBishopに成ってステイルメイトを避けるようになりました。以下Kb8,Qb7と進んでチェックメイトで白の勝ちです。以下のコードはgithubの将棋アプリの先読み探索部分のコードですが、全コードの25%(青い部分)が打ち歩詰めチェックのためだけのコードになっています。今回のチェスプログラムのコードも同様にステイルメイトチェックのために随分プログラムのレスポンスが悪くなってしまいました。仕方がないこととは言えこの特殊なルールのためにパフォーマンスが低下してしまいます。buf[1])今回は方法2でステイルメイト対策をしましたが、方法1のやり方も検討中です。ステイルメイトも打ち歩詰めもゲームを面白くする要素かもチェスプログラムのテストをしている際に「引き分けがチェスを面白くしている」という意見を見かけました(質問1に対する回答)。前回の記事でステイルメイトは合理的でないと貶しましたが、いろいろなケースをテストしている内に「ステイルメイト(引き分け)がチェスを面白くしている」という意見の意味が少し分かってきました。将棋の打ち歩詰め同様ゲームを面白くしている要素なのかもしれません。