以下の内容はhttps://smooth-pudding.hatenablog.com/entry/2025/05/24/205105より取得しました。


【AI×Tauri】第二回:アプリの仕様を検討する(後編)

前回の記事では、アプリ開発のざっくり方針を決めました。
smooth-pudding.hatenablog.com
今回はより具体的に仕様の検討を進めていきます。

画面設計・ユーザーインターフェースの検討

ここを考えるのが醍醐味ではあるのですが、まずはAIにたたき台を作ってもらいましょう。先程のチャットに続けて以下のように ChatGPT に投げてみます。

3画面ほどの画面遷移で十分遊べるようにしたいです。それぞれの画面の役割の組み合わせの案をいくつか挙げてください。ボタンなどの具体的なコンポーネントの配置などについては含めないでください。

5つの案が返ってきました。

案A : もっとも基本的な構成
案B : 結果画面を省略し、ループするスタイル
案C : 学習性や戦略性を重視した構成
案D : ユーザーが一人で遊ぶことを前提としたコンパクト構成
案E : 複数モード (例 : AI対戦・自由対戦) を想定

補足:構成選びのポイント

  • 最も自然な導線(A・B案):
    最低限で動かしたいならこれ。
  • 教育的な側面を重視するなら(C案):
    Second Best の解説なども載せたい場合。
  • 開発コストを抑えたいなら(D案):
    画面遷移の実装を最小限にできる。
  • 今後の拡張を見据えるなら(E案):
    モード追加や設定の幅がある。

AIの意見としてはAとBが本命のようですね。対戦画面と結果の画面は同じ方がわかりやすそうなので、案Bを採用することにします。状態の管理を簡単にするため、以下のふたつの動線のみを考えることにします。

  • ホーム画面\iffゲーム画面
  • ホーム画面\iff設定画面

では各画面の具体的なデザインも決めていきます。この部分は楽しいので、自分で考えることにします。

ホーム画面

  • タイトル表示
  • 「対戦開始」ボタン
  • 「設定」ボタン:⚙アイコンがよさそう

色:

  • 背景色: D7CCC8
  • 文字色: 3E2723
ホーム画面案

設定画面

  • 「ホームに戻る」ボタン:🏠アイコンが良さそう
  • プレイヤーの色の選択

色:

  • 選択枠: D32F2F
設定画面案

ゲーム画面

  • ボード表示
  • 手番の色の表示
  • 「ホームに戻る」ボタン:🏠アイコンがよさそう
  • 「ゲーム開始に戻る」ボタン:\circlearrowrightアイコンがよさそう
  • 「セカンドベスト」ボタン
  • ボードのすぐ下にステータス表示
    • (進行中) 手番の表示
    • (終了後) 勝者の表示
ゲーム画面案

ボード表示は以下のようにする。

  • 8つの丸が円状に並んでいるようにする
  • コマを積んでいる状態が立体的に見えるようにする
    • テーマの色の線で輪郭を書いて、中を塗りつぶすとよさそう。
  • 選択可能なマスと選択不可のマスを色分けする
  • コマの移動の際は「移動元をクリック→移動先をクリック」という順にする。移動元をクリックしたときは、そのマスの枠の色を変える。移動元をもう一度クリックすると選択解除となる。
  • セカンドベスト宣言した場合は、画面中央に大きく「Second Best」と一定時間表示するようにする。
コマの案
ボードの案

フロントエンドの構成の検討

画面のデザインがざっくり決まったので、React のコンポーネントでどう表現していくか考えていきます。ところが、私は React のコンポーネントにどういったものがあるか分かりません。そこで AI に聞いてみます。

以下を ChatGPT に投げてみます。セカンドベストと言っても伝わらない恐れがあるので、オセロを題材にして聞いてみます。

シンプルなボードゲームの UI を React で作成しようとしています。ところが、私は React の経験が無いため、どのようなコンポーネントが React に用意されているのか全く分かりません。
そこで、オセロのようなボードゲームのUIを設計する場合を想定して、実装に使えそうな React のコンポーネントを紹介してください。初心者にもわかりやすい説明になるよう心がけてください。

すると以下のように返ってきました。

目標と前提
マス目のコンポーネント
ボードのコンポーネント
ゲーム全体のコンポーネント
補足

注文通り、シンプルな例が返ってきました。ボタンを使ってマス目を作り、マス目を並べたものとしてボードを作り、最後にボードの状態を管理するコンポーネントを作っているようです。オセロの場合は入れ子構造がとてもうまく使えそうですね。

React の簡単な雰囲気は分かりましたが、先程の画面設計を実現するには、html 要素として組み立てていくのは少々無理がありそうです。可能なら、キャンバスの上に画像を配置していくようなことができれば嬉しそうです。

そこで以下のように追加質問してみます。

React でキャンバスの領域を用意して、その上に自由に画像を配置することは可能でしょうか?また、ある画像の上をクリックするイベントを検出して、それに応じて画像の様子を変化させることは可能でしょうか?
もし可能なら、最もシンプルな実現方法を教えてください。

今度は以下のように返ってきました。

できること



▼ソースコードをクリックで表示

解説・補足・まとめ

キャンバスの上でクリックすると画像が切り替わるコンポーネントを紹介してくれました。ざっくり雰囲気は分かりましたが、useEffect がどういう役割なのか掴みきれないので、追加で質問してみます。

useEffect がどのような関数なのか、丁寧に教えてください。引数にどのようなものを与えれば、どのような振る舞いをするのかが知りたいです。

すぐに返答が返ってきました。

とても良い質問です!React の useEffect は、React コンポーネントの「副作用(=画面の更新以外にやりたい処理)」を扱うための関数です。React を使う上で必ず知っておくべき重要なフックの1つです。

useEffect とは
基本の形
各パターンの説明
例とまとめ

どうやら副作用を制御するための便利関数のようですね。さきほどの CanvasWithImage の例だと、isAltImage という変数を監視して、値が変更されたときに「キャンバスの全体を削除→画像を描画」という処理を走らせる役割を担っているというわけですね。

ちなみに、useEffect というキーワードでググってみたところ、こんな記事もヒットしました。これ以外にもいろいろと hook と呼ばれるものがあり、それぞれ重要な役割を果たしそうです。
qiita.com

実際にボードを表現しようとした場合、コマやボード上の丸の部分もコンポーネントとして扱いたくなります。上記の例では画像は単なる画像になっているので、やや扱いが大変そうです。そこで、以下のように質問してみました。

オセロのボードやコマをキャンバス上の画像として表現する際に、ボードやコマをコンポーネントとして扱う方法はありますか?

返答は以下のとおりです。

方針


▼実装の例をクリックで表示

結論

なるほど、つまり、「コマ」「ボード」というモノで表現するのではなく、「コマを描く」「ボードを描く」というコトで表現すればよいってことですね。この技術をうまく組み合わせれば、ボードの表現はなんとかできそうです。

とりあえず、ボードはキャンバス上の描画でなんとか表現できそうです。ただ画面にはいくつかのコンポーネントがまだあります。もし自分で実装するのであれば、それぞれ何を使うのか確認が必要です。でも今回はAIにコードを書いてもらう予定なので、生成されたものを見て都度調べる作戦で行こうと思います。

バックエンドAPIの設計

めちゃくちゃざっくりフロントエンドの構成が決まりました。次はバックエンドの設計案を作ってもらいます。こちらは後ほど実装するときに渡すので、Cursor を使って Markdown 形式で作ってもらうことにします。

バックエンドの設計についてこれまで決まっていることを整理します。

  • アプリ全体を Tauri で構成し、バックエンドは Rust で書くこと
  • Second Best のルール
    • Rust クレートのドキュメントから抜粋する
  • プレイヤーとAIとの対戦形式にすること
  • バックエンドとフロントエンドの連携は Pull+Push のハイブリッドで行う
    • プレイヤーが操作したときのみ invoke() で Rust の関数を呼ぶ (Pull 型)
    • AIのターンが終わったら emit() で通知し、フロントで反映 (Push 型)

空の作業用フォルダを作成し、Cursor を立ち上げます。secondbest クレートの README.md のうち、ゲームのルールの部分を抜粋し、rules.md として保存しておきます。その上で Agent に以下のように命令します。

Second Best というボードゲームがあり、そのゲームで遊べるアプリを開発しようと思っています。具体的には以下のような仕様です。

  • アプリ全体を Tauri で構成し、バックエンドは Rust で書く
  • Second Best のルールは @rules.md の通り
  • プレイヤーとAIとの対戦形式にする
  • バックエンドとフロントエンドの連携は Pull+Push のハイブリッドで行う

- プレイヤーが操作したときのみ invoke() で Rust の関数を呼ぶ (Pull 型)
- AIのターンが終わったら emit() で通知し、フロントで反映 (Push 型)

以上の条件の下で、バックエンドのAPIの案を作成し、backend_api.md として出力してください。内部実装を与える必要はなく、それぞれのシグネチャと役割を簡潔に並べるようにしてください。

@rules.md のところでは、rules.md へのリンクを設定しておきます。ちょうど最近 Claude-4 Sonnet が公開されたので、それで投げてみました。返答は以下のとおりです。


▼バックエンドAPI案をクリックで開く
全体的には問題なさそうですが、いくつか修正が必要なポイントがあります。

  • skip_second_best() は不要。合法な手を実行できたらセカンドベスト宣言は失効するため。
  • AI によるセカンドベスト宣言を表現できていないので、表現してほしい。

これを Cursor に追加注文してみましょう。

以下の点を修正してください。

  • skip_second_best() は不要。合法な手を実行できたらセカンドベスト宣言は失効するため。
  • AI によるセカンドベスト宣言を表現できていないので、表現してほしい。

すると以下のように修正されました。


▼バックエンドAPI修正案をクリックで開く
これでひとまず大丈夫そうですね。もしあとでダメそうなことが分かったら、そのときに修正することにします。

第二回まとめ

今回は長めになっちゃいましたね。ゲームの方向性がかなり具体的になってきて、イメージが明確になってきました。そろそろAIにお願いして形のあるものを作っていけそうな予感がします。

次回はいよいよ Tauri のプロジェクトを作って、少しずつ実装に入っていきたいなと思っています。

ではまた。

続き↓
smooth-pudding.hatenablog.com




以上の内容はhttps://smooth-pudding.hatenablog.com/entry/2025/05/24/205105より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14