将棋盤アプリの詰み判定ロジックを考える(打歩詰め判定など)

この記事の所要時間は約 3 分 です。

今年の夏から秋にかけて開発していた将棋盤アプリだが、その後のダウンロード数も順調に増え、インストール数も30を超えた。動作の軽快さは売りにしているものの、対局用のAIは実装していない「ただの」将棋盤アプリなのだが、それでも使ってもらえているのは、ありがたい。

実は、12月初旬にPlayストア上で、初めて評価をつけてくれた方がいた。5点満点中2点という評価は、改善の余地があるということの証に他ならないが、なによりも有難かったのは、そのコメントだ。

打歩詰め、できちゃいましたよ

ということは、このコメントをくれた方は、私のプログラムした『将棋盤アプリ』で、打歩詰めが出現するまで、遊んでくれていたわけだ。打歩詰めの局面など、なかなか出現するものではないのだから、通常の駒操作等については、そこまでストレスなく、遊んでもらえたのではないか、と思った。

詰み判定ロジックについて

折角、コメントと評価をいただいたのだから、これに応えておきたい……と、打ち歩詰め判定の機能を考えてみているのだが、これが、なかなか難しい。

そもそも、その前段階の詰み判定ですら、厄介な代物だ。

「詰み」の条件はなんだろうか?

  1. 玉に王手がかかっていること
  2. 玉の移動先の全てに敵駒の利きがあること
  3. 味方の駒で、王手をかけている敵駒を取ることができないこと
    → または、味方の駒で王手をかけている敵駒を取る動きがピンの制限にかからないこと
  4. 味方の駒で、王手を防ぐこと(合駒)ができないこと
    → または、味方の駒で王手を防ぐ動き(合駒)がピンの制限にかからないこと

なかなかの実装難易度である。ピンの実装自体が難しいと思っていたのだが、「詰み判定」を考慮するならば、先に「ピン」を実装し、駒の稼動域を判定する際に、「ピンの概念」を組み込んでおいたほうがロジックはきれいになりそうだ。

詰み判定を実装するには、少なくとも、「玉を除く味方駒の利き」「自玉の効き」「玉を除く敵駒の利き」「敵玉の効き」の4つの情報を、都度、保持しておく必要がありそうだ。

打ち歩詰めの判定について

さて。前述のような実装が完成したとして、打ち歩詰めを判定するためには、歩を打った後の局面で詰み判定をして、その打ち歩で相手玉が詰んでいないことを確認する必要があるわけだ。

「かる~い将棋盤」では、歩を打てる升目を判定する際に、二歩の判定をしていたりはするのだから、この時に、相手玉との位置関係により、必要に応じて、歩を打った後の「利き」情報を元に、詰み判定をする必要があるわけだ。

ここまで「かる~い将棋盤」では、局面情報を単なるオブジェクトとして持たせており、履歴を保持することで「待った」のように局面を戻す機能は有していたのだが、あくまで局面情報は1つであった。「歩を打った場合」のように仮の局面での詰み判定を実施する必要が出てくるのであれば、局面については、クラスとして、複数オブジェクトを持っておくような工夫をした方がよいかもしれない。

とりあえずのまとめ

詰み判定に関するプログラミング上の留意点をまとめてみたが、なかなかに難しい。実装は、もう少し、先になりそうだ。