将棋所なしのiPad単独で対局ができるようにするため、CSAプロトコルの実装に引き続き独自のGUIによる局面表示を実装します。
実は大会ルールで画面表示に関する要件が定められており、これに準拠した設計を行う必要があります。
ルールのうち表示に関する部分を抜粋し、対策を示します。
- 一 任意の局面・手番・残り時間からの将棋の対局の開始と継続。
- 過去数回の大会で発生事例を見たことがなく、実装が面倒なため将棋所+USIで実現する。
- 二 任意の時点での対局中断。
- サーバから中断メッセージ(#CHUDAN)が来れば停止する。発生することが極めて稀であり、同一TCPコネクション上で再開することまでは求められていないと考える。再開は将棋所+USIで実現する。
- 三 対局中の現在局面の表示。テキストでも良い。
- 指し手を受信するたびにUI上で局面表示を更新する。
- 四 第24条の規定による、1手毎の消費時間の計測、及び累計消費時間の画面への表示。
- 24条で、LAN対戦の場合はサーバが消費時間を計測することになっている。計測された1手の消費時間は指し手とともにクライアントに送られる。1手ごとの消費時間はこれをそのまま表示すれば良い。累積消費時間は送信されないため、クライアント側で合計を計算して表示する。手入力対戦の場合は自分で計測する必要があるが、将棋所+USIに任せる。
- 五 1手毎の指し手と消費時間の記録。対局中断時も、そこまでのすべての指し手と消費時間を取り出せなければならない。
- サーバから送られた指し手と1手ごとの消費時間を画面に表示する。中断等でも表示を続けるため、コネクションが切れた際に消去するのではなく、次の対局のAGREEを送る時点で消去する。できれば、ファイルにも保存する(iPadOSのため取り出すインターフェースが別途必要となる)。
- 六 CSA サーバプロトコル ver.1.2.1 に基づく、LAN による対局。
- 前回実装した。
- 七 相手の指し手の手入力による対局。
- 将棋所+USIで実現。
- 第9条 参加プログラムは、次の各号に掲げる機能を持つことが推奨される。但し、機能を持たないことによって不利になることはない。
- 一 LAN による通信で送受信した文字列の必要に応じた表示。
- 通信内容のデバッグ表示機能を設ける。
通常の対局では不要な機能は将棋所に任せることにして、以上の機能を実装しました。累積消費時間が必須というのはルールを読まないと気付かないので要注意です。
以下のような画面になりました。
細かいことはソースコードを読んでいただくとして、実装のポイントを示します。
- UIライブラリはSwift標準のSwiftUI
- 画面
- 大きく分けて2つの画面レイアウトがあり、対局前の接続設定と、対局中の局面表示です。接続設定はテキストボックスを並べた最低限のものです。以下では対局中の画面を説明します。
- 主なUI部品
- 盤面
- 評価値バー
- 対局者名と、その時点で最新の評価値を表示
- 評価値グラフ
- 評価値の履歴を表示
- 読み筋表示
- 独自の表示を考えたので、次回解説
- 指し手の履歴
- 指し手のほかに1手の消費時間、合計消費時間、評価値(自分の手番のみ)
- 詳細な指し手情報
- 探索部では、「移動元、移動先、成りかどうか」という情報で指し手を管理していますが、「▲7六歩」のような文字列を表示するには移動する駒の情報が不足しています。
- 表示のためのDetailedMoveという構造体を定義しました。以下の情報を含んでいます。
- 特殊な指し手(投了、入玉宣言)
- 移動元(または駒台)
- 移動先
- 手番
- 移動前の駒の種類
- 移動後の駒の種類(成りがある場合に移動前と変わる)
- 成りかどうか
- 駒打ちかどうか
- これらの情報で、「▲7六歩(77)」というような移動元をカッコで示す将棋所と同等の表示ができます。「同歩」のような前の指し手に依存する情報や、「5八金左」のような他の駒との関係が絡む情報は含められていません。
- モジュール間の通信
- UIから通信部、通信部から思考部を起動する。
- 局面・指し手履歴情報は通信部からUIへ、読み筋情報は思考部からUIへ送信。
- 画像アセット