Python初心者がツムツムを自動化してみた

動作中の動画

なぜPythonなのか

恥ずかしながら今まで噂に聞くことの多いPythonに触れたことがなかったため、この機会に使えるようになっておこうと思ったのが動機です。

なぜツムツムなのか

ツムツム以外の他のゲームの自動化でもよかったのですが、ツムツムには他のゲームにない特徴があり、自動化するにあたってある程度の難易度があるため挑戦してみました。画像認識も、Pythonでの開発も初めてなので、腕試し目的です。

ツムツムの他のゲームにない特徴点

ツムツムには他のゲームにない特徴があります。
ざっくり言うとリアルタイム性とツムが回転・移動する点です。
自動化にあたって、この点に必ず悩まされます。

他のパズルゲームでは基本的に回転動作はなく、テンプレートマッチングによる検出のみで物体の認識が可能であり自動化は比較的に楽です。
しかしツムツムは移動と回転が組み合わさって非常に認識が難しいです。

開発環境

今回の開発にあたって使用した環境を載せておきます。
・Python 3.7.2
・Opencv 4.0.1
・anaconda3
・Nox Player 6.2.7.1

開発の流れ

本当はソースコードをそのまま載せたり、配布したりしたいのですが、
流石に色々と問題がありそうなので、最低限処理に必要なものを記載していきます。
質問があれば答えたりするかもしれないです。

ツムの認識

まずは、ツムを認識しなければ話になりません。
認識手法としては以下のものを試しました。

1.輪郭検出からの最小外接円算出
2.watershedアルゴリズムによる物体の切り離し
3.ハフ変換による円検出
4.ディープラーニングによる物体認識

現在、最終的には「3.ハフ変換による円検出」でツムを認識しています。
認識精度は「4.ディープラーニングによる物体認識」が一番よかったですが、新しいツムを引くたびに学習データを作るのがめんどくさかったので…。

ツムの判定

ツムの認識ができたとしても、最終的にツムをなぞる必要があるので、それがどのツムなのか判定できなければ意味がありません。
今回はわかりやすく色で判定を行いました。

色判定は、ハフ変換で検出した円の中心点からnピクセルの範囲をクロップし、画素情報の平均化を行った結果をその円の色としています。
そのままでは精度が悪いので平均化した画素情報は1の位を切り捨てています。

ツムのグループ化

グループ化は最終的になぞる経路の道しるべとなるものを設定する工程です。
ツムの判定で取得した色情報から、ある程度の閾値でグループ化します。

経路探索

グループ化が完了したら、経路探索用の処理を実装します。
今回はとりあえず動くものが作りたかったので、経路を探索する再帰関数を作成しています。
…非常に効率が悪いです。
経路探索の際は、距離の閾値と角度の閾値を設けると綺麗な経路が出来上がると思います。取得した経路はイメージに出力すると分かりやすいですね。

実際のゲーム画面で確認

実際のゲーム画面を取り込みます。
今回はNox Playerでツムツムをプレイし、 PILを使用してデスクトップキャプチャーを作成し、確認を行いました。
Python初心者のためここで型変換エラーに悩まされましたが、1つずつトラブルシューティングすれば動くようになります。

なぞる処理、スキル押下処理

PyAutoGUIを使用しています。
使い勝手がいいので特に詰まることもないです。
1点あげるとしたらデフォルトで処理に待機時間が設定されているので、高速でマウス操作を行いたい場合、「pyautogui.PAUSE = 待機時間」を設定しなおす必要があります。
私は0.03を指定しています。

その他追加した方がいい機能

ここまでの説明でツムツム自動化について最低限必要なものは簡単に説明が終わりました。
ツムツムにさらに特化させるべく、私は以下の機能を実装しています。

・マイツム優先処理
・ スキル連打、ボムキャンセル機能などのテクニック部分
・もう少しでフィーバーが終わる場合に、スキル発動を待つ機能
・ ハート自動送受信機能

どれも画像認識処理の組み合わせで実装できます。
しかしながら画像認識なので、100%動作するとは限らないところがポイントですね。

最後に

とりあえず形になってよかったです。
画像認識や物体認識など、これまで手を出していない分野に手を出してみるのは刺激になって楽しいですね。
これからも色々なことに手を出してみたいと思います。