リアルタイム盤面解析から行動提案 実装編まとめ(推論まで到達)
本記事は、以下の記事の**続編(実装編)**です。
ここでは、
プレイ動画 → 学習データ → 学習 → 推論(Top-k 提案)
までを 実際に動く形で構築した内容をまとめます。
※ 特定ゲームや IP に依存しないよう、用語は一般化しています。
本記事で到達したゴール
- 行動ラベリング(人手)
- dataset.jsonl の自動生成
- 盤面画像 + 数値特徴量(手札 / リソース)の構築
- CNN による action / grid の模倣学習
- Top-k 行動提案の推論 + 盤面 overlay 可視化
👉 「学習して、それっぽい“次の一手候補”が出る」状態まで到達
全体パイプライン(再掲)
動画(画面録画 / 配信動画)
↓
人手ラベリング(click / action)
↓
events.jsonl
↓
build_dataset.py
↓
dataset.jsonl + state_frames/
↓
CNN 学習(train_policy.py)
↓
推論(predict_policy.py)
↓
Top-k 行動提案 + overlay
1. 行動ラベリング(label_events.py)
最初の正解データは 人間がプレイした行動ログです。
python tools/label_events.py \
--video example_play_xxx.mp4 \
--out example_play_xxx.jsonl
- クリック位置(x,y)
- 行動ID(action_0〜action_9 など)
- 時刻 t
を 1 行 1 JSON で保存します。
board only フィルタ
UI 上で「盤面外クリック(手札選択など)」が混ざるため、
ROI(盤面 y 範囲)で board only に絞ります。
y1, y2 = 70, 712
if y1 <= y <= y2:
keep
2. dataset.jsonl の生成
python tools/build_dataset.py \
--video example_play_xxx.mp4 \
--events example_play_xxx_boardonly.jsonl \
--out-dir out/dataset_xxx
生成物:
out/
dataset.jsonl
state_frames/
dataset.jsonl の中身(抜粋)
{
"action_id": "action_5",
"grid_id": 38,
"state_path": "state_frames/000123.png",
"hand_available": [1,1,1,1],
"hand_card_ids": [-1,-1,-1,-1],
"resource": 3,
"resource_frac": 0.34
}
- 盤面画像:256×256
- 手札特徴:4スロット(未知なら -1)
- リソース量:画像処理で推定(不安定時は -1)
3. リソースゲージ推定(画像処理ベース)
OCR は使わず、ゲージの塗り割合を画像処理で推定します。
手順:
- ROI 切り出し(特定解像度は pixel 固定)
- HSV で特定色域の画素を抽出
- 横方向の充填率 → 0..1 に正規化
- 不安定時は -1(安全側)
inspect 用ツール:
python tools/inspect_resource.py \
--video example_play_xxx.mp4 \
--out-dir out/inspect_resource
overlay で ROI を目視確認しながら調整できます。
4. 学習(train_policy.py)
python tools/train_policy.py \
--data-dir out/dataset_xxx \
--out-dir out/train_runs/run1 \
--epochs 20 \
--batch-size 16 \
--gw 6 --gh 9
モデル構成
-
入力:盤面画像(single frame)+ 数値特徴
-
出力:
- action head(どの行動か)
- grid head(どこに置くか)
学習結果の例
- val_card_top3 ≒ 0.6〜0.7
- val_grid_top3 ≒ 0.6〜0.7
👉 Top-k 提案用途としては十分「兆しあり」
※ two-frame / diff は データ不足で逆効果だったため一旦見送り
5. 推論(predict_policy.py)
python tools/predict_policy.py \
--checkpoint out/train_runs/run1/checkpoints/best.pt \
--data-dir out/dataset_xxx \
--idx 0 \
--topk 5 \
--render-overlay \
--overlay-out out/predict/sample.png
推論ログ例
resource=3 resource_frac=0.34
01 action_id=action_4 grid_id=27 score=0.11
02 action_id=action_7 grid_id=29 score=0.09
...
overlay 可視化
- Top-1 の grid を盤面に描画
- 座標系のズレ確認に非常に有効
6. 手札が未知な場合の「安全側」挙動
dataset 初期段階では、
hand_card_ids = [-1, -1, -1, -1]
が普通に起きます。
この場合:
- hand mask は自動的にスキップ
- Top-k 提案は継続
-
slot_index = -1(実行不可だが提案は出す)
👉 自動操作を行わないため、提案用途としては問題なし
ここまでで出来たこと
- 「次に何を・どこに置くか」を Top-k で提案できる
- 盤面 overlay で人間が確認できる
- 欠損があっても落ちない(安全側)
👉 研究用 PoC として一段落
次のステップ(予告)
優先度順:
-
手札スロット認識(slot → card_id)
- inspect_hand.py
- 推論で slot_index が埋まる
-
リソース量を使ったルール制約
-
データ増量後の two-frame / diff 再挑戦
まとめ
- 小さく作り、実動画で確認し、数値で判断
- 失敗(two-frame)も含めて「正しい実験」
- まずは 提案が出るところまでを最短で作る
同じように「ゲームプレイ × 学習」を扱う方の参考になれば幸いです。