0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

リアルタイム盤面解析から行動提案 実装編まとめ(推論まで到達)

Posted at

リアルタイム盤面解析から行動提案 実装編まとめ(推論まで到達)

本記事は、以下の記事の**続編(実装編)**です。

ここでは、

プレイ動画 → 学習データ → 学習 → 推論(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 は使わず、ゲージの塗り割合を画像処理で推定します。

手順:

  1. ROI 切り出し(特定解像度は pixel 固定)
  2. HSV で特定色域の画素を抽出
  3. 横方向の充填率 → 0..1 に正規化
  4. 不安定時は -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 として一段落


次のステップ(予告)

優先度順:

  1. 手札スロット認識(slot → card_id)

    • inspect_hand.py
    • 推論で slot_index が埋まる
  2. リソース量を使ったルール制約

  3. データ増量後の two-frame / diff 再挑戦


まとめ

  • 小さく作り、実動画で確認し、数値で判断
  • 失敗(two-frame)も含めて「正しい実験」
  • まずは 提案が出るところまでを最短で作る

同じように「ゲームプレイ × 学習」を扱う方の参考になれば幸いです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?