はじめに
日本語プログラミング言語Mindのバージョン9でAI仕様駆動開発(っぽいこと)を行ってみます。本記事はその第4ステップで、AI仕様駆動開発の後工程のキモ?とも言えるAI修正・ビルド・実行・再修正ワークフローの自動化をGUIアプリでやってみたという内容です。
使用AI
Microsoft Copilot
Windows11アプリケーションのMicrosoft Copilot。昨年末から日本語プログラミング言語あおい Aoi(Re:Mind)の原型を作成してもらった生成AI123。モードは「無料プラン」。
GitHub Copilot
GitHub CopilotのPro+版。あおい実装4と検証の主担当。スーパバイザとしてMicrosoft Copilotを使いGitHub CopilotのCodeAgent推論量を最小化するプロンプトをCopilotで生成しGitHub CopilotのCodeAgentで実行という工法?を採用しています。
本記事のステップ
ステップ2にてGitHub CopilotがMindの言語仕様に準じて修正・ビルド・再修正ワークフローを廻して、コンパイルエラーがなくせるところまで自律的に動かせました。
ステップ3でアプリ仕様について調整しましたので、本ステップではアプリ仕様に到達するまで修正・ビルド・実行・再修正ワークフローを廻してみます。
ステップ2ではGUIアプリの実行と状態判定は人間が行っていましたが、本ステップではAIがGUIアプリを実行して状態を判定してソースコードの修正に入るという点がポイントです。
ただし、仕様実現の可否には画面の動きの総合的な判定が必要になりますので、そこは人間系が行い、AIが自律的に不具合修正するのは実行時にアプリが落ちてしまうとか実行時の致命的エラー改修にとどまります。
Microsoft Copilotとの事前準備
本ステップではだいたいこれでいけるだろうと考えていたのでとくにありません。
GitHub Copilot
ステップ3の仕様調整はその後もいろいろ調整が続いて、現在の修正方針mdは下記のv4となっております。
docs\firework修正方針v4.md
9. 完了条件
-
canvas_color_control.srcがSJIS/CP932で保存され、コンパイルできる。 - canvas作成、消去、円、楕円、塗り色、線色、描画、移動の単語がTcl/Tk canvasの確認済みAPIだけで構成されている。
-
FireworkTextEffectを除くC#の通常花火の状態、粒子範囲、6色、30ms周期をMind版へ反映する。 - 爆発粒子を白色固定残光で覆わず、半径1〜3のカラー粒子が不規則な方向・速度で拡散する。
- 画面端の座標クランプによる粒子集中、整数速度の丸めによる規則的な多角形状が目視で残らない。
- ビルド後に
firework.infが生成されない。 - 文字花火、未確認のARGB、Bitmap画素取得、未確認の後置構文を追加していない。
- 追加検証の結果と実行時のGUI状態を別途記録する。
ここにむかった改修の途中でWindowsフォームが実行中(実行開始の描画初期段階で)予期せず閉じてしまうという不具合が発生してしまいます。
当初はGUIアプリの実行と落ちる段階をダイアログ挿入でユーザーが介在することで判定していたのですが、ここでGitHub Copilotが重要な提案をしてきます。
応答レスポンス
状況から、単に次回予約を止めるだけでは十分でない可能性があります。診断1〜10の複数のモーダルダイアログが同じ非同期イベント処理内で実行されているので、ダイアログ自体がイベントスタックを乱している仮説が強まりました。イベント内のモーダル表示をなくし、代わりに後から読める診断記録へ切り替えられるか、Mindのファイル出力仕様を確認します。
ファイル出力マニュアルで、開いたログファイルへ文字列を書き込み、改行を付ける標準APIが使えることを確認しました。これなら非同期イベント内でモーダルダイアログを開かずに段階を記録できます。必要なオープン/書き込み/クローズの正確な構文を確認してから置き換えます。
これならGUIアプリでも自分で起動して、ログを見て結果を判定して不具合箇所を段階的に特定して修正できますねというやりとりになって、GitHub Copilotが起動を試みてくれたりしていたのですが(起動自体は以前からやってくれていたのですが)起動したMind由来のWindowフォームに出力した文字を見ると、ランタイムが未発見というよく見るエラーが確認されました。
これはGitHub Copilotが起動したときの状態で、わたしは環境設定PATHを実行したターミナルから起動していますので、これが起きないことは自明として認識していました。GitHub Copilotが起動するときは都度内部ターミナルのインスタンスを使うので、結局下記のようにVSCodeのtasks.jsonを修正しました。
tasks.json
GitHub Copilotが最終的に修正した状態。GitHub Copilotの処理中に私がVSCodeで他のファイルを開いたりしていて、すると実行対象が変わってしまうのでGitHub Copilotにそれはやめてほしいと注意されながら、runタスクのターゲットファイルはリテラル書きとなりました。call C:\Mind9\usemind.batをアプリの起動毎に実行してもらうというのがポイントです。またターミナルをコマンドプロンプトで起動するよう設定しています。
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "call C:\\Mind9\\usemind.bat && mind ${fileBasenameNoExtension} guilib",
"group": "build",
"options": {
"shell": {
"executable": "C:\\Windows\\System32\\cmd.exe",
"args": ["/d", "/c"]
}
},
"problemMatcher": []
},
{
"label": "run",
"type": "shell",
"command": "call C:\\Mind9\\usemind.bat && firework",
"group": "test",
"options": {
"shell": {
"executable": "C:\\Windows\\System32\\cmd.exe",
"args": ["/d", "/c"]
}
},
"problemMatcher": []
}
]
}
お題のソースコード(AIによるデバッグ診断ログ追記状態)
GitHub Copilotがデバッグ診断ログの出力を追加した状態のソースコードです。それがなくても既にだいぶ長大なソースコードをMind9コンパイラがエラーなしで完走する状態となっています。
firework.src AIによるデバッグ診断ログ追記状態
"snowdrops\\randomtcl.src"を コンパイル。
"canvas_color_control.src"を コンパイル。
キャンバスは ID。
キャンバス幅は 定数 1200。
キャンバス高は 定数 600。
粒子数は 定数 204。
主粒子数は 定数 180。
外周粒子数は 定数 24。
花火の数は 定数 4。
粒子型は 型紙
円IDは 図形ID
X座標は 変数
Y座標は 変数
X速度は 変数
Y速度は 変数
粒子半径は 変数
寿命は 変数
使用中は 変数
粒子色番号は 変数
粒子本体は 円IDと X座標と Y座標と X速度と Y速度と 粒子半径と 寿命と 使用中と 粒子色番号
粒子列は 粒子数の 粒子本体
全体は 花火の数の 粒子列。
花火型は 型紙
花火Xは 変数
花火Yは 変数
花火目標Yは 変数
花火上昇速度は 変数
花火主粒子数は 変数
花火半径は 変数
花火活動中は 変数
花火爆発済みは 変数
花火寿命は 変数
花火本体は 花火Xと 花火Yと 花火目標Yと 花火上昇速度と 花火主粒子数と 花火半径と 花火活動中と 花火爆発済みと 花火寿命
全体は 花火の数の 花火本体。
花火粒子群は 構造体 粒子型。
花火群は 構造体 花火型。
花火番号は 変数。
粒子番号は 変数。
花火中心円IDは 図形ID。
残光円IDは 図形ID。
速度は 変数。
方向は 変数。
色番号は 変数。
フレーム数は 変数。
診断花火番号は 変数。
診断段階は 変数。
診断ログは ファイル。
診断ログ有効は 変数。
診断を記録するとは (文字列 → ・)
記録文は 文字列
記録文に 入れる
診断ログ有効が 1に 等しい ならば
"firework_diagnostic.log"で 診断ログを 新規オープンする
エラー?
ならば 0を 診断ログ有効に 入れ
さもなければ
記録文を 診断ログに 一行書き込み
診断ログを クローズする
エラー?
ならば 0を 診断ログ有効に 入れ
つぎに
つぎに
つぎに。
粒子を初期化するとは
粒子数で 回数指定し
粒子番号に 回数を 入れ
花火群の 花火X(花火番号)を 花火粒子群の X座標(花火番号,粒子番号)に 入れ
花火群の 花火Y(花火番号)を 花火粒子群の Y座標(花火番号,粒子番号)に 入れ
0を 花火粒子群の X速度(花火番号,粒子番号)に 入れ
0を 花火粒子群の Y速度(花火番号,粒子番号)に 入れ
3を 花火粒子群の 粒子半径(花火番号,粒子番号)に 入れ
0を 花火粒子群の 寿命(花火番号,粒子番号)に 入れ
0を 花火粒子群の 使用中(花火番号,粒子番号)に 入れ
1を 花火粒子群の 粒子色番号(花火番号,粒子番号)に 入れ
繰り返す。
花火を作るとは
乱数値は 小数変数
範囲指定の疑似乱数2(100,1100)を 乱数値に 入れ
乱数値を 整数化し 花火群の 花火X(花火番号)に 入れ
600を 花火群の 花火Y(花火番号)に 入れ
範囲指定の疑似乱数2(100,300)を 乱数値に 入れ
乱数値を 整数化し 花火群の 花火目標Y(花火番号)に 入れ
範囲指定の疑似乱数2(8,13)を 乱数値に 入れ
乱数値を 整数化し 花火群の 花火上昇速度(花火番号)に 入れ
範囲指定の疑似乱数(120,180)を 乱数値に 入れ
乱数値を 整数化し 花火群の 花火主粒子数(花火番号)に 入れ
範囲指定の疑似乱数2(70,110)を 乱数値に 入れ
乱数値を 整数化し 花火群の 花火半径(花火番号)に 入れ
1を 花火群の 花火活動中(花火番号)に 入れ
0を 花火群の 花火爆発済み(花火番号)に 入れ
0を 花火群の 花火寿命(花火番号)に 入れ
粒子を初期化する。
花火を爆発させるとは
乱数値は 小数変数
角度は 小数変数
速度小数は 小数変数
X速度小数は 小数変数
Y速度小数は 小数変数
揺らぎは 小数変数
主粒子数現在は 変数
速度層は 変数
外周番号は 変数
外周距離は 変数
外周速度は 変数
外周最大半径は 変数
1を 花火群の 花火爆発済み(花火番号)に 入れ
24を 花火群の 花火寿命(花火番号)に 入れ
診断花火番号が 0に 等しい ならば
花火番号を 診断花火番号に 入れ
"DIAG_01_EXPLOSION_BEGIN"を 診断を記録する
つぎに
花火群の 花火主粒子数(花火番号)を 主粒子数現在に 入れ
花火群の 花火主粒子数(花火番号)で 回数指定し
粒子番号に 回数を 入れ
[角度 := PI * 2.0 * 粒子番号 / 主粒子数現在]をつみ
範囲指定の疑似乱数(0,3)を 揺らぎに 入れ
[揺らぎ := 揺らぎ - 1.0]をつみ
[角度 := 角度 + 揺らぎ / 12.0]をつみ
粒子番号を 3で 割った余りを 速度層に 入れ
速度層が 0に 等しい ならば
範囲指定の疑似乱数(2,5)を 速度小数に 入れ
つぎに
速度層が 1に 等しい ならば
範囲指定の疑似乱数(4,8)を 速度小数に 入れ
つぎに
速度層が 2に 等しい ならば
範囲指定の疑似乱数(7,12)を 速度小数に 入れ
つぎに
cos(角度)を X速度小数に 入れ
sin(角度)を Y速度小数に 入れ
[X速度小数 := X速度小数 * 速度小数]をつみ
[Y速度小数 := Y速度小数 * 速度小数]をつみ
X速度小数を 整数化し 花火粒子群の X速度(花火番号,粒子番号)に 入れ
Y速度小数を 整数化し 花火粒子群の Y速度(花火番号,粒子番号)に 入れ
範囲指定の疑似乱数(1,4)を 乱数値に 入れ
乱数値を 整数化し 花火粒子群の 粒子半径(花火番号,粒子番号)に 入れ
範囲指定の疑似乱数(1,7)を 色番号に 入れ
色番号を 花火粒子群の 粒子色番号(花火番号,粒子番号)に 入れ
花火群の 花火X(花火番号)を 花火粒子群の X座標(花火番号,粒子番号)に 入れ
花火群の 花火Y(花火番号)を 花火粒子群の Y座標(花火番号,粒子番号)に 入れ
範囲指定の疑似乱数2(18,28)を 乱数値に 入れ
乱数値を 整数化し 花火粒子群の 寿命(花火番号,粒子番号)に 入れ
1を 花火粒子群の 使用中(花火番号,粒子番号)に 入れ
繰り返す
花火番号が 診断花火番号に 等しい ならば
"DIAG_02_MAIN_PARTICLES_DONE"を 診断を記録する
つぎに
花火群の 花火主粒子数(花火番号)を 粒子番号に 入れ
外周粒子数で 回数指定し
外周番号に 回数を 入れ
花火群の 花火主粒子数(花火番号)に 外周番号を 加え 粒子番号に 入れ
[角度 := PI * 2.0 * 外周番号 / 外周粒子数]をつみ
範囲指定の疑似乱数(0,3)を 揺らぎに 入れ
[揺らぎ := 揺らぎ - 1.0]をつみ
[角度 := 角度 + 揺らぎ / 12.0]をつみ
花火群の 花火半径(花火番号)を 外周最大半径に 入れ
[外周最大半径 := 外周最大半径 / 2]をつみ
範囲指定の疑似乱数(20,外周最大半径)を 外周距離に 入れ
範囲指定の疑似乱数2(6,10)を 外周速度に 入れ
外周距離に 外周速度を 加え 速度に 入れ
cos(角度)を X速度小数に 入れ
sin(角度)を Y速度小数に 入れ
[X速度小数 := X速度小数 * 速度]をつみ
[Y速度小数 := Y速度小数 * 速度]をつみ
X速度小数を 整数化し 花火粒子群の X速度(花火番号,粒子番号)に 入れ
Y速度小数を 整数化し 花火粒子群の Y速度(花火番号,粒子番号)に 入れ
花火群の 花火X(花火番号)を 花火粒子群の X座標(花火番号,粒子番号)に 入れ
花火群の 花火Y(花火番号)を 花火粒子群の Y座標(花火番号,粒子番号)に 入れ
範囲指定の疑似乱数2(16,26)を 乱数値に 入れ
乱数値を 整数化し 花火粒子群の 寿命(花火番号,粒子番号)に 入れ
範囲指定の疑似乱数(1,3)を 乱数値に 入れ
乱数値を 整数化し 花火粒子群の 粒子半径(花火番号,粒子番号)に 入れ
範囲指定の疑似乱数(1,7)を 色番号に 入れ
色番号を 花火粒子群の 粒子色番号(花火番号,粒子番号)に 入れ
1を 花火粒子群の 使用中(花火番号,粒子番号)に 入れ
繰り返す
花火番号が 診断花火番号に 等しい ならば
"DIAG_03_OUTER_PARTICLES_DONE"を 診断を記録する
つぎに。
花火群を初期化するとは
花火の数で 回数指定し
花火番号に 回数を 入れ
花火を作る
繰り返す。
花火を更新するとは
Xは 変数
Yは 変数
花火群の 花火活動中(花火番号)が 0に 等しい
ならば 終わる つぎに
花火群の 花火爆発済み(花火番号)が 0に 等しい
ならば
花火群の 花火Y(花火番号)から 花火群の 花火上昇速度(花火番号)を 引き 花火群の 花火Y(花火番号)に 入れ
花火群の 花火Y(花火番号)が 花火群の 花火目標Y(花火番号) 以下
ならば
花火群の 花火目標Y(花火番号)を 花火群の 花火Y(花火番号)に 入れ
花火を爆発させる
つぎに
つぎに
花火群の 花火爆発済み(花火番号)が 1に 等しい
ならば
花火群の 花火寿命(花火番号)が 24に 等しい
ならば
花火番号が 診断花火番号に 等しい ならば
"DIAG_04_PARTICLE_UPDATE_BEGIN"を 診断を記録する
つぎに
つぎに
粒子数で 回数指定し
粒子番号に 回数を 入れ
花火粒子群の 使用中(花火番号,粒子番号)が 1に 等しい ならば
花火粒子群の X座標(花火番号,粒子番号)に 花火粒子群の X速度(花火番号,粒子番号)を 加え Xに 入れ
Xを 花火粒子群の X座標(花火番号,粒子番号)に 入れ
花火粒子群の Y座標(花火番号,粒子番号)に 花火粒子群の Y速度(花火番号,粒子番号)を 加え Yに 入れ
Yを 花火粒子群の Y座標(花火番号,粒子番号)に 入れ
花火粒子群の Y速度(花火番号,粒子番号)を 一つ増加し
花火粒子群の 寿命(花火番号,粒子番号)から 1を 引き 花火粒子群の 寿命(花火番号,粒子番号)に 入れ
花火粒子群の 寿命(花火番号,粒子番号)が 16 以下
ならば 2を 花火粒子群の 粒子半径(花火番号,粒子番号)に 入れ
つぎに
花火粒子群の 寿命(花火番号,粒子番号)が 8 以下
ならば 1を 花火粒子群の 粒子半径(花火番号,粒子番号)に 入れ
つぎに
花火粒子群の 寿命(花火番号,粒子番号)が 0 以下
ならば 0を 花火粒子群の 使用中(花火番号,粒子番号)に 入れ
つぎに
つぎに
繰り返す
花火群の 花火寿命(花火番号)が 24に 等しい
ならば
花火番号が 診断花火番号に 等しい ならば
"DIAG_05_PARTICLE_UPDATE_DONE"を 診断を記録する
つぎに
つぎに
花火群の 花火寿命(花火番号)から 1を 引き 花火群の 花火寿命(花火番号)に 入れ
花火群の 花火寿命(花火番号)が 0 以下
ならば 0を 花火群の 花火活動中(花火番号)に 入れ
つぎに
つぎに
。
花火群を更新するとは
花火の数で 回数指定し
花火番号に 回数を 入れ
花火群の 花火活動中(花火番号)が 1に 等しい
ならば 花火を更新する
つぎに
花火番号が 診断花火番号に 等しい ならば
花火群の 花火爆発済み(花火番号)が 1に 等しい ならば
診断段階が 0に 等しい ならば
"STACK_AFTER_FIRST_EXPLOSION_UPDATE"を 診断を記録する
「最初の爆発を含む花火更新直後」で このメッセージでスタック検査し
"STACK_FIRST_EXPLOSION_UPDATE_OK"を 診断を記録する
つぎに
つぎに
つぎに
花火群の 花火活動中(花火番号)が 0に 等しい
ならば 花火を作る
つぎに
繰り返す。
花火を描くとは
描画Xは 変数
描画Yは 変数
描画範囲内は 変数
粒子区分は 変数
花火番号が 診断花火番号に 等しい ならば
診断段階が 0に 等しい ならば
"STACK_DRAW_ENTRY"を 診断を記録する
「診断対象花火描画の入口」で このメッセージでスタック検査し
"STACK_DRAW_ENTRY_OK"を 診断を記録する
つぎに
つぎに
花火群の 花火活動中(花火番号)が 1に 等しい
ならば
花火群の 花火爆発済み(花火番号)が 0に 等しい
ならば
キャンバスと 花火群の 花火X(花火番号)と 花火群の 花火Y(花火番号)と 6で 円のIDを取得し 花火中心円IDに 入れ
白色で 花火中心円IDに 満たす色を設定し
花火中心円IDを 描画する
さもなければ
粒子数で 回数指定し
粒子番号に 回数を 入れ
花火粒子群の 使用中(花火番号,粒子番号)が 1に 等しい ならば
花火番号が 診断花火番号に 等しい ならば
診断段階が 0に 等しい ならば
粒子番号を 8で 割った余りを 粒子区分に 入れ
粒子区分が 0に 等しい ならば
粒子番号を 文字列変換し
"PARTICLE_BATCH_"と 変換文字列を 合成し 診断を記録する
「粒子区分の描画前」で このメッセージでスタック検査し
"STACK_PARTICLE_BATCH_OK"を 診断を記録する
つぎに
つぎに
つぎに
花火粒子群の X座標(花火番号,粒子番号)を 描画Xに 入れ
花火粒子群の Y座標(花火番号,粒子番号)を 描画Yに 入れ
0を 描画範囲内に 入れ
描画Xが 0以上 ならば
描画Yが 0以上 ならば
描画Xが キャンバス幅より 小さい ならば
描画Yが キャンバス高より 小さい ならば
1を 描画範囲内に 入れ
つぎに
つぎに
つぎに
つぎに
描画範囲内が 1に 等しい ならば
キャンバスと 描画Xと 描画Yと 花火粒子群の 粒子半径(花火番号,粒子番号)で 円のIDを取得し 花火粒子群の 円ID(花火番号,粒子番号)に 入れ
花火番号が 診断花火番号に 等しい ならば
粒子番号が 1に 等しい ならば
診断段階が 0に 等しい ならば
"STACK_AFTER_FIRST_CIRCLE_ID"を 診断を記録する
「最初の粒子の円ID取得後」で このメッセージでスタック検査し
"STACK_FIRST_CIRCLE_ID_OK"を 診断を記録する
つぎに
つぎに
つぎに
花火粒子群の 粒子色番号(花火番号,粒子番号)が 1に 等しい ならば
花火橙色を 花火粒子群の 円ID(花火番号,粒子番号)に 満たす色を設定し
つぎに
花火粒子群の 粒子色番号(花火番号,粒子番号)が 2に 等しい ならば
花火深紅色を 花火粒子群の 円ID(花火番号,粒子番号)に 満たす色を設定し
つぎに
花火粒子群の 粒子色番号(花火番号,粒子番号)が 3に 等しい ならば
花火金色を 花火粒子群の 円ID(花火番号,粒子番号)に 満たす色を設定し
つぎに
花火粒子群の 粒子色番号(花火番号,粒子番号)が 4に 等しい ならば
花火空色を 花火粒子群の 円ID(花火番号,粒子番号)に 満たす色を設定し
つぎに
花火粒子群の 粒子色番号(花火番号,粒子番号)が 5に 等しい ならば
花火黄緑色を 花火粒子群の 円ID(花火番号,粒子番号)に 満たす色を設定し
つぎに
花火粒子群の 粒子色番号(花火番号,粒子番号)が 6に 等しい ならば
花火紫紅色を 花火粒子群の 円ID(花火番号,粒子番号)に 満たす色を設定し
つぎに
花火番号が 診断花火番号に 等しい ならば
粒子番号が 1に 等しい ならば
診断段階が 0に 等しい ならば
"STACK_BEFORE_FIRST_PARTICLE_DRAW"を 診断を記録する
「最初の粒子の色設定後」で このメッセージでスタック検査し
"STACK_FIRST_PARTICLE_COLOR_OK"を 診断を記録する
つぎに
つぎに
つぎに
花火粒子群の 円ID(花火番号,粒子番号)を 描画する
花火番号が 診断花火番号に 等しい ならば
粒子番号が 2以上 ならば
粒子番号が 8以下 ならば
診断段階が 0に 等しい ならば
粒子番号を 文字列変換し
"STACK_AFTER_PARTICLE_"と 変換文字列を 合成し 診断を記録する
「粒子描画後」で このメッセージでスタック検査し
"STACK_PARTICLE_STEP_OK"を 診断を記録する
つぎに
つぎに
つぎに
つぎに
花火番号が 診断花火番号に 等しい ならば
粒子番号が 1に 等しい ならば
診断段階が 0に 等しい ならば
"STACK_AFTER_FIRST_PARTICLE_DRAW"を 診断を記録する
「最初の粒子を描画した直後」で このメッセージでスタック検査し
"STACK_FIRST_PARTICLE_DRAW_OK"を 診断を記録する
つぎに
つぎに
つぎに
つぎに
つぎに
繰り返す
花火番号が 診断花火番号に 等しい ならば
診断段階が 0に 等しい ならば
"STACK_PARTICLE_LOOP_DONE"を 診断を記録する
「診断対象花火の粒子描画ループ末尾」で このメッセージでスタック検査し
"STACK_PARTICLE_LOOP_OK"を 診断を記録する
つぎに
つぎに
つぎに
つぎに
花火番号が 診断花火番号に 等しい ならば
"STACK_DRAW_WORD_RETURN"を 診断を記録する
「花火を描く処理語の末尾」で このメッセージでスタック検査し
"STACK_DRAW_WORD_RETURN_OK"を 診断を記録する
つぎに
。
花火を再描画するとは
キャンバスを キャンバスをクリアし
花火群を更新する
花火の数で 回数指定し
花火番号に 回数を 入れ
花火群の 花火寿命(花火番号)が 23に 等しい
ならば
花火番号が 診断花火番号に 等しい ならば
"DIAG_06_TARGET_DRAW_BEGIN"を 診断を記録する
つぎに
つぎに
花火を描く
花火番号が 診断花火番号に 等しい ならば
診断段階が 0に 等しい ならば
"STACK_AFTER_TARGET_DRAW"を 診断を記録する
「診断対象花火の描画直後」で このメッセージでスタック検査し
"STACK_TARGET_DRAW_OK"を 診断を記録する
診断段階が 8に 等しい ならば
"STACK_AFTER_DRAW_LOOP"を 診断を記録する
「花火描画ループの直後」で このメッセージでスタック検査し
"STACK_DRAW_LOOP_OK"を 診断を記録する
つぎに
つぎに
つぎに
花火群の 花火寿命(花火番号)が 23に 等しい
ならば
花火番号が 診断花火番号に 等しい ならば
"DIAG_07_TARGET_DRAW_DONE"を 診断を記録する
7を 診断段階に 入れ
つぎに
つぎに
繰り返す
診断段階が 7に 等しい ならば
"DIAG_08_ALL_FIREWORKS_DRAW_DONE"を 診断を記録する
8を 診断段階に 入れ
つぎに
診断段階が 8に 等しい ならば
"STACK_AFTER_DRAW_LOOP"を 診断を記録する
「花火描画ループの直後」で このメッセージでスタック検査し
"STACK_DRAW_LOOP_OK"を 診断を記録する
つぎに
。
遅延後の花火処理とは 仮定義。
次の花火処理を予約とは
30ミリと 遅延後の花火処理の 実行情報と 空列で 遅延実行を予約
診断段階が 10に 等しい ならば
"STACK_DELAY_RESERVATION_RETURNED"を 診断を記録する
「遅延予約から復帰した直後」で このメッセージでスタック検査し
"STACK_DELAY_RESERVATION_OK"を 診断を記録する
つぎに
診断段階が 13に 等しい ならば
"STACK_DELAY_RESERVATION_RETURNED"を 診断を記録する
「2回目の遅延予約から復帰した直後」で このメッセージでスタック検査し
"STACK_DELAY_RESERVATION_OK"を 診断を記録する
つぎに
診断段階が 16に 等しい ならば
"STACK_DELAY_RESERVATION_RETURNED"を 診断を記録する
「3回目の遅延予約から復帰した直後」で このメッセージでスタック検査し
"STACK_DELAY_RESERVATION_OK"を 診断を記録する
つぎに。
遅延後の花火処理とは 本定義 (引数1、引数2、・・、引数個数 → ・)
イベント引数を捨て
診断段階が 0に 等しい ならば
"STACK_FIRST_EVENT_ENTRY"を 診断を記録する
「初回遅延イベント入口で引数を捨てた直後」で このメッセージでスタック検査し
"STACK_FIRST_EVENT_ENTRY_OK"を 診断を記録する
つぎに
診断段階が 10に 等しい ならば
"STACK_EVENT_ARGS_DISCARDED"を 診断を記録する
「遅延イベント入口で引数を捨てた直後」で このメッセージでスタック検査し
"STACK_EVENT_ENTRY_OK"を 診断を記録する
つぎに
診断段階が 13に 等しい ならば
"STACK_EVENT_ARGS_DISCARDED"を 診断を記録する
「2回目の遅延イベント入口で引数を捨てた直後」で このメッセージでスタック検査し
"STACK_EVENT_ENTRY_OK"を 診断を記録する
つぎに
診断段階が 16に 等しい ならば
"STACK_EVENT_ARGS_DISCARDED"を 診断を記録する
「3回目の遅延イベント入口で引数を捨てた直後」で このメッセージでスタック検査し
"STACK_EVENT_ENTRY_OK"を 診断を記録する
つぎに
診断段階が 10に 等しい ならば
"DIAG_11_FIRST_EVENT_BEGIN"を 診断を記録する
11を 診断段階に 入れ
つぎに
診断段階が 13に 等しい ならば
"DIAG_14_SECOND_EVENT_BEGIN"を 診断を記録する
14を 診断段階に 入れ
つぎに
診断段階が 16に 等しい ならば
"DIAG_17_THIRD_EVENT_BEGIN"を 診断を記録する
17を 診断段階に 入れ
つぎに
花火を再描画する
診断段階が 8に 等しい ならば
"STACK_FIRST_REDRAW_RETURN"を 診断を記録する
「初回再描画から復帰した直後」で このメッセージでスタック検査し
"STACK_FIRST_REDRAW_RETURN_OK"を 診断を記録する
つぎに
診断段階が 11に 等しい ならば
"STACK_REDRAW_RETURNED"を 診断を記録する
「最初の再描画から復帰した直後」で このメッセージでスタック検査し
"STACK_REDRAW_RETURN_OK"を 診断を記録する
つぎに
診断段階が 14に 等しい ならば
"STACK_REDRAW_RETURNED"を 診断を記録する
「2回目の再描画から復帰した直後」で このメッセージでスタック検査し
"STACK_REDRAW_RETURN_OK"を 診断を記録する
つぎに
診断段階が 17に 等しい ならば
"STACK_REDRAW_RETURNED"を 診断を記録する
「3回目の再描画から復帰した直後」で このメッセージでスタック検査し
"STACK_REDRAW_RETURN_OK"を 診断を記録する
つぎに
診断段階が 8に 等しい ならば
"DIAG_09_REDRAW_RETURNED"を 診断を記録する
9を 診断段階に 入れ
つぎに
診断段階が 9に 等しい ならば
"DIAG_10_BEFORE_NEXT_DELAY"を 診断を記録する
10を 診断段階に 入れ
つぎに
診断段階が 11に 等しい ならば
"DIAG_12_FIRST_FRAME_DONE"を 診断を記録する
12を 診断段階に 入れ
つぎに
診断段階が 12に 等しい ならば
"DIAG_13_BEFORE_SECOND_DELAY"を 診断を記録する
13を 診断段階に 入れ
つぎに
診断段階が 14に 等しい ならば
"DIAG_15_SECOND_FRAME_DONE"を 診断を記録する
15を 診断段階に 入れ
つぎに
診断段階が 15に 等しい ならば
"DIAG_16_BEFORE_THIRD_DELAY"を 診断を記録する
16を 診断段階に 入れ
つぎに
診断段階が 17に 等しい ならば
"DIAG_18_THIRD_FRAME_DONE"を 診断を記録する
18を 診断段階に 入れ
つぎに
診断段階が 10に 等しい ならば
"STACK_BEFORE_DELAY_RESERVATION"を 診断を記録する
「初回遅延予約の直前」で このメッセージでスタック検査し
"STACK_BEFORE_DELAY_RESERVATION_OK"を 診断を記録する
つぎに
診断段階が 13に 等しい ならば
"STACK_BEFORE_DELAY_RESERVATION"を 診断を記録する
「2回目の遅延予約の直前」で このメッセージでスタック検査し
"STACK_BEFORE_DELAY_RESERVATION_OK"を 診断を記録する
つぎに
診断段階が 16に 等しい ならば
"STACK_BEFORE_DELAY_RESERVATION"を 診断を記録する
「3回目の遅延予約の直前」で このメッセージでスタック検査し
"STACK_BEFORE_DELAY_RESERVATION_OK"を 診断を記録する
つぎに
次の花火処理を予約すること
。
メインとは
0を 診断花火番号に 入れ
0を 診断段階に 入れ
1を 診断ログ有効に 入れ
"APP_READY"を 診断を記録する
メインウィンドウと キャンバス幅と キャンバス高と 黒色で
キャンバスを立て キャンバスに 入れ
花火群を初期化する
花火を再描画する
"INITIALIZATION_COMPLETE"を 診断を記録する
次の花火処理を予約する。
メインウィンドウクローズ処理とは 本定義 (・ → ・)
"NORMAL_SHUTDOWN"を 診断を記録する
実行終りすること。
診断ログ
下記のような診断ログで終了時の最終値を記録します。下記は現在の異常終了の状態。
firework_diagnostic.log
PARTICLE_BATCH_8
正常終了時は下記のコードによりNORMAL_SHUTDOWNを記録するとなっています。
メインウィンドウクローズ処理とは 本定義 (・ → ・)
"NORMAL_SHUTDOWN"を 診断を記録する
実行終りすること。
この「メインウィンドウクローズ処理とは 本定義」とかはGitHub Copilotがいろいろ調べて設定したコードです。これでコンパイルは正常通過していることが前提なのですが、なかなかすごいものを感じます。
現在の状態 -未解決-
この状態でかなりの長時間作業を繰り返していましたが、ひさしぶりにGitHub CopilotがContinue to iterate?の問い合わせを出してきました。
Copilot has been working on this problem for a while. It can continue to iterate, or you can send a new message to refine your prompt. Configure max requests.
GitHub Copilot Pro+のクレジットはこの時点で40%程度でしたが、いったん続行した後しばらくして中断としています。
おわりに
いかがでしたでしょうか?本件ターゲット仕様の難度が高いのでなかなか実行時不具合を解消できていませんが、GUIアプリでもAIが自律的に改修とリビルド、実行時診断ができる環境の例ができたのはよかったような気がします。同じことをしようとしている方々の参考になれば幸いです。