【生成AI自分教材化シリーズ】ChatGPTで爆速でスマホアプリを開発する5【オープニング学習画面の開発編】
こんにちは、IT博士のきたたくです。
今日のブログでは、ChatGPTを活用したアプリ開発について詳しくお話しします。
特に、アプリ開発に悩む方々のために、Unityを用いたアプリ開発に焦点を当てます。
この情報は、個人でアプリを開発し、収益化を目指す方にとって非常に有益です。
ぜひ最後までお読みいただき、アプリ開発の参考にしてください。

本記事の信頼性
- スマホアプリ開発会社を創業&売却
- 個人開発アプリで新着有料ランキング4位を獲得
- これまでに40以上のアプリを開発
本記事ではついにチェス盤のオープニング学習画面の作成です。
以下の動画のシーンを作成します。
仕様の詳細が決まっていないため、ChatGPTと話しながら仕様を決めます。

あなたはプロのUnityエンジニアです。
以下のシーンの仕様の詳細を決めるためにわたしに質問をして、最後に仕様の詳細をまとめて出力してください。
・前のシーンで選択されたチェスのオープニングの棋譜をテキストファイルから読み込みます
・プレイヤーとCPUがそれぞれオープニングをなぞる手を指すことができます
・プレイヤーが一手指すごとに、解説テキストが表示されます。
・ゲームが始まると、プレイヤーが先手の場合、プレイヤーが動かすべき駒の背景に色がつきます
・プレイヤーが動かすべき駒をタッチすると、その駒の移動先の背景に色がつきます
・プレイヤーが正しい位置に駒を動かすと、CPUが次の手を打ちます
・プレイヤーが後手の場合、CPUが最初に手を打ちます

了解しました。では、シーンの詳細仕様を決定するためにいくつか質問させてください。
質問:
- 前のシーンでの選択方法:
- 前のシーンでチェスのオープニングを選択する際のインターフェースはどのようにしますか?
- 選択されたオープニングはどのようにデータとして次のシーンに渡されますか?
- 棋譜の形式:
- テキストファイルの形式はどのようにしますか?例として、PGN形式(Portable Game Notation)を使用しますか?
- 解説テキストは棋譜と同じファイルに含まれますか、それとも別ファイルにしますか?
- プレイヤーとCPUのインタラクション:
- プレイヤーが駒を動かす際の操作方法はどのようにしますか?ドラッグ&ドロップ、クリック&クリック、その他?
- CPUの手はどのように決定されますか?予め決められた手をそのまま実行するのか、ランダム性や簡単なAIロジックを導入しますか?
- 駒のハイライト:
- プレイヤーが動かすべき駒とその移動先のハイライトはどのような色やエフェクトにしますか?
- ハイライトの表示時間やエフェクトの種類(点滅、色変更など)はどうしますか?
- 解説テキストの表示:
- 解説テキストの表示位置やスタイルはどのようにしますか?
- 解説テキストはプレイヤーが手を指すごとに表示されるのか、常に表示され続けるのか、どちらが好みですか?
- エラー処理:
- プレイヤーが誤った手を指した場合の処理はどのようにしますか?
- 誤った手を指した場合のフィードバックはどのようにしますか?
- その他の機能:
- 他に追加したい機能や要件はありますか?(例:チュートリアル、音声ガイド、手のアニメーションなど)
これらの質問に答えていただければ、仕様の詳細をまとめて出力いたします。
以下のように回答をChatGPTにおくります。

前のシーンでの選択方法:
Q前のシーンでチェスのオープニングを選択する際のインターフェースはどのようにしますか?
A オープニングのリストがあり、そこからユーザーが選択します。
Q選択されたオープニングはどのようにデータとして次のシーンに渡されますか?
A string型のオープニング名のデータをSceneManager.sceneLoadedでわたします
棋譜の形式:
Qテキストファイルの形式はどのようにしますか?例として、PGN形式(Portable Game Notation)を使用しますか?
A .txt
Q解説テキストは棋譜と同じファイルに含まれますか、それとも別ファイルにしますか?
A 別ファイル
プレイヤーとCPUのインタラクション:
Q.プレイヤーが駒を動かす際の操作方法はどのようにしますか?ドラッグ&ドロップ、クリック&クリック、その他?
A.クリック&クリック(スマホ想定のためタッチ&タッチ)
Q.CPUの手はどのように決定されますか?予め決められた手をそのまま実行するのか、ランダム性や簡単なAIロジックを導入しますか?
A.予め決められた手をそのまま実行
駒のハイライト:
Q.プレイヤーが動かすべき駒とその移動先のハイライトはどのような色やエフェクトにしますか?
A.
動かすべき駒の置いてあるマスが黄色
移動先は、マスの中心にグレーの円で表現
移動後の、移動元はマスが黄色
Qハイライトの表示時間やエフェクトの種類(点滅、色変更など)はどうしますか?
A.
表示時間は設定せず常に動かすべき駒の置いてあるマスが黄色。
ユーザーが動かすべき駒をタッチすると、移動先のマスの中心にグレーの円で表現
ユーザーがグレーの円をタッチすると駒が移動する。
駒の移動元と移動先のマスが黄色になる。
解説テキストの表示:
Q解説テキストの表示位置やスタイルはどのようにしますか?
A画面の下に表示。画面の一番下はメニューが表示されている。画面の一番上は定跡名とプレイヤーの指ししてる色(白先手・黒後手)が表示
Q解説テキストはプレイヤーが手を指すごとに表示されるのか、常に表示され続けるのか、どちらが好みですか?
A.常に表示されており、プレイヤーが手を指すごとに更新される
エラー処理:
Qプレイヤーが誤った手を指した場合の処理はどのようにしますか?
A.不正解メソッドを呼び、誤ったことのフィードバックを返す
Q誤った手を指した場合のフィードバックはどのようにしますか?
間違いであることを示す音を鳴らす、画面の一番上に不正解と表示する、解説テキストの内容を「色のついた駒を操作しよう」に更新する。
その他の機能:
Q.他に追加したい機能や要件はありますか?(例:チュートリアル、音声ガイド、手のアニメーションなど)
A.駒が移動する際はアニメーションで移動させる
A.常にユーザー側の盤面を画面の下にする
A.ユーザーとCPUが取った駒はそれぞれ盤の上下のスペースに並べる

シーンの仕様詳細
以下の質問と回答を基に、シーンの仕様詳細をまとめました。
1. 前のシーンでの選択方法
- オープニング選択インターフェース: 前のシーンでは、ユーザーがチェスのオープニングをリストから選択します。
- データの渡し方: 選択されたオープニングは
string型のオープニング名として、SceneManager.sceneLoadedを使用して次のシーンに渡されます。
2. 棋譜の形式
- テキストファイルの形式:
.txtファイルを使用します。 - 解説テキスト: 棋譜と解説テキストは別ファイルにします。
3. プレイヤーとCPUのインタラクション
- 操作方法: プレイヤーはクリック&クリック(スマホではタッチ&タッチ)で駒を動かします。
- CPUの手: 予め決められた手をそのまま実行します。
4. 駒のハイライト
- 駒のハイライト色:
- 動かすべき駒の置いてあるマスは黄色。
- 移動先はマスの中心にグレーの円。
- 移動後、移動元のマスは黄色。
- 表示時間とエフェクト:
- ハイライトは常に表示され、動かすべき駒をタッチすると、移動先のマスにグレーの円が表示。
- ユーザーがグレーの円をタッチすると駒が移動し、駒の移動元と移動先のマスが黄色に変わる。
5. 解説テキストの表示
- 表示位置とスタイル: 画面の下に解説テキストを表示し、画面の一番下にはメニューが表示される。画面の一番上には定跡名とプレイヤーの指し手(白先手・黒後手)が表示される。
- 表示タイミング: 解説テキストは常に表示され、プレイヤーが手を指すごとに更新される。
6. エラー処理
- 誤った手の処理: プレイヤーが誤った手を指した場合、不正解メソッドを呼び、フィードバックを返す。
- フィードバック方法: 間違いであることを示す音を鳴らし、画面の一番上に「不正解」と表示し、解説テキストの内容を「色のついた駒を操作しよう」に更新する。
7. その他の機能
- 駒の移動アニメーション: 駒が移動する際はアニメーションで移動させる。
- 盤面の表示方向: 常にユーザー側の盤面を画面の下にする。
- 取った駒の表示: ユーザーとCPUが取った駒はそれぞれ盤の上下のスペースに並べる。
まとめ
これらの仕様に基づき、シーンを構築します。以下に詳細な実装手順を示します。
仕様が固まってきました。

実装手順
ステップ1: 前のシーンでの選択
- オープニングリストの作成:
- 前のシーンにチェスのオープニングリストを作成。
- リストから選択されたオープニングを
string型で保存。
- シーン遷移の設定:
- 選択されたオープニング名を
SceneManager.sceneLoadedで次のシーンに渡す。
- 選択されたオープニング名を
ステップ2: 棋譜の読み込み
- 棋譜と解説テキストの読み込み:
TextAssetを使用して、テキストファイルから棋譜と解説テキストを読み込むスクリプトを作成。
ステップ3: インタラクションの設定
- 駒の操作方法の設定:
- プレイヤーが駒をタッチ&タッチで動かせるようにする。
- 駒のハイライト表示と移動先の表示を設定。
- CPUの手の設定:
- 予め決められた手を実行するスクリプトを作成。
ステップ4: ハイライトの設定
- 駒のハイライト:
- プレイヤーが動かすべき駒のマスを黄色でハイライト。
- 移動先のマスをグレーの円で表示。
- 表示とエフェクト:
- ハイライトの表示を常に行い、駒の移動に合わせてハイライトを更新。
ステップ5: 解説テキストの表示
- 解説テキストの配置:
- 画面の下に解説テキストを表示。
- 定跡名とプレイヤーの指し手情報を画面の一番上に表示。
- 更新ロジック:
- プレイヤーが手を指すごとに解説テキストを更新。
ステップ6: エラー処理
- 誤った手のフィードバック:
- 不正解メソッドを作成し、音と画面表示でフィードバック。
ステップ7: その他の機能
- 駒の移動アニメーション:
- 駒の移動アニメーションを実装。
- 盤面の表示方向:
- 盤面を常にユーザー側が下になるように表示。
- 取った駒の表示:
- 取った駒を盤の上下に表示。
実装手順をおこなっていきます。
前のシーンでのオープニング選択
- オープニングリストの作成:
- 前のシーンにチェスのオープニングリストを作成。
- リストから選択されたオープニングを
string型で保存。
- シーン遷移の設定:
- 選択されたオープニング名を
SceneManager.sceneLoadedで次のシーンに渡す。
- 選択されたオープニング名を
仮でオープニングの「Queen’s gambit」を指定するプログラムを以下のように書きました。
ファイルは以前作成した[SceneController]です。

上記プログラムではGameManagerが存在しないとエラーが出るため、GameManagerファイルを作成します。
仮で、string型のopening変数のみを持ったGameManagerクラスを以下のように作成します。
盤面の作成
棋譜の読み込みを実装する前に、盤面を作成します。
まずChessに必要となる盤面と駒の2D画像を用意します。
ChatGPTにチェスの盤面を出力させたところ、以下のような惜しい画像がでてきました。

ここでは時短のためにUnityのAssetStoreを活用します。
無料の2D/3D ChessPackを利用します。
3Dで作ってもいいのですが、実際に自分がチェスゲームをする際は毎回2D表示にして使います。
3Dは見づらいからです。そのため今回は2Dで作成します。

[Add to My Assets]をクリックします。

[Open in Unity]をクリックします。

[Download]をクリックします。

[Import]をクリックします。

[Import]をクリックします。
HomeSceneを複製してOpeningSceneを作成します。
不要なテキストとボタンを削除します。

[image]を追加して、先ほどダウンロードした盤の画像を設定します。

これだけだとさみしいため、解説キャラを配置してみます。
猫を探したところ、チェスっぽい猫を発見!

早速配置します。シーンビューには写っています。Gameビューには写っていません。

[Canvas]の[Render Mode]を[Screen Space-Camera]に変更します。
[Render Camera]に[Main Camera]をドラッグ&ドロップで設定します。

Gameビューでも猫が表示されました。

盤にA~Hの横の列と1~8の縦の列をテキストで追加します。

次に盤面のそれぞれをタッチできるようにボタンを配置します。
一個一個ボタンの位置を調整するのは大変なため、空のGameObjectを作成します。
その空のGameObjectに[GridLayoutGroup]と[Content Size Filltter]をアタッチします。
空のGameObjectの大きさを盤面の大きさに合わせて、ボタンを子オブジェクトとして追加します。
後はマスの数である64個のボタンを複製して作成します。
ちなみにSceneビューで[T]が多くて見づらい場合は、以下の画像の右上のギズモアイコンで消せます。
ギズモアイコンの横のメニューをクリックすると、細かい表示・非表示の調整も可能です。

マス目のサイズは[GridLayoutGroup]の[Cell Size]で調整します。

マスにa8~h1まで名前を変更します。

テキストを消して、ボタンの色を透明にします。
透明にするには、ボタンの[image]の[RGBA]をすべて0にします。

ステップ2: 棋譜の読み込み
チェスの棋譜を読み込む機能を作成します。
まず、チェスの棋譜の形式を理解する必要があります。以下が正式なチェスの棋譜の書き方です。
| 棋譜 | 意味 |
| K | キング |
| Q | クイーン |
| R | ルーク |
| B | ビショップ |
| N | ナイト |
| 無し | ポーン |
| 駒の名前+移動先のマス | 駒の移動 |
| 駒の名前+x+移動先のマス | ポーン以外の駒で相手の駒をとった場合 |
| 移動元の列+移動先のマス | ポーンで相手の駒を取った場合 |
| 0-0 | キングサイド キャスリング |
| 0-0-0 | クイーンサイド キャスリング |
| e.p. | アンパッサン |
| 「移動先のマス」+「=」+「プロモーション(昇格)する駒名」 | プロモーション |
| 「駒の名前 + 移動先のマス」+「+」 | チェック |
| 「駒の名前 + 移動先のマス」+「#」 | チェックメイト |
| 「駒の名前」+「移動前のマスの列名」+「移動先のマス」 | 複数の同じ種類の同じ行の駒が、そのマスに移動できる場合 |
| 「駒の名前」+「移動前のマスの行名(数字)」+「移動先のマス」 | 複数の同じ種類の同じ列の駒が、そのマスに移動できる場合 |
| 1-0 | 白が勝った場合 |
| 0-1 | 黒が勝った場合 |
| 1/2-1/2 | 引き分けの場合 |
この棋譜を読み込んで盤面を再現できるのが理想ですが、正式な棋譜では駒の移動元が明記されていません。
そのため、仮想的に盤面を動かし、駒の移動元を推測する必要があります。
これは、完全な棋譜再現アプリにおいては実装する価値があります。
しかし、今回はチェスのオープニングを学ぶアプリであり、再現するのは序盤の数手に限られます。
したがって、正式な棋譜の形式をそのまま使用する必要はありません。
今回のプロジェクトに適した簡略化した棋譜のルールを作成します。
具体的には、以下の形式です。
[移動前のマス]>[移動後のマス],[移動前のマス]>[移動後のマス]
これだけで、必要な情報が得られます。実際には、そのマスにどの駒があるかを把握する必要もありません。
AIでプログラムを自動化する技術が進んでいるとはいえ、簡単にできる部分は簡単に済ませましょう。
簡易棋譜の例として、最も一般的なオープニングである「イタリアンゲーム」だと以下になります。
e2>e4,e7>e5,g1>f3,b8>c6,f1>c4
ただし、この棋譜だと2つの駒が動くキャスリングやアンパッサンは表現できません。
そのため、キャッスリングは通常の棋譜と同じく、0-0もしくは0-0-0で表現します。
アンパッサンがでてくるオープニングは少ないため無視します。
棋譜読み込みプログラム
プログラムは以下になります。
原型はChatGPTに作らせて、その後に修正しました。
プログラムを解読する場合は、ChatGPTに一行ずつ解説してもらうとわかりやすいです。
まだまだChatGPTだけでは解決できない部分もありますね。
例えば以下の部分は[yield return null;]を入れないとうまく動きません。
しかしChatGPTの生成ではでてきませんでした。
yield return new WaitUntil(() => !isPlayerTurn); // プレイヤーの入力を待つ
yield return null;プログラムがうまく動かない場合はChatGPTだけで解決しようとするのではなく、ドキュメントの参照やブログ記事、コミュニティへの相談と柔軟に対応しましょう。
