ポケモンSVにおける孵化厳選自動化

# はじめに
こんにちは、鈴鹿高専 Advent Calendar 2022 13日目担当のMarcyです。

https://qiita.com/advent-calendar/2022/snct

この記事はポケモンSVの孵化厳選をRaspberry PiからBluetooth接続して自動化してやろうという内容です。

# 孵化厳選ってなんや
アドカレに投稿するということで、孵化厳選について全然知らない人もいると思うので軽く説明します。

ポケモンにはそれぞれ体力(H)攻撃(A)防御(B)特攻(C)特防(D)素早さ(S)の6つのパラメータが存在するのですが、これらの数値はポケモンが生まれた時点で確定しています。

これらの数値(個体値)をできるだけ優秀なものにするために行うのが孵化厳選です。

最新作では、この生まれたときに確定している数値(個体値)を後から最大にするアイテムも存在し、そのアイテムも簡単に手に入るのでポケモンを育成するのに必ず必要な作業かといわれるとそうではないです。~~(自動化ってロマンあるじゃん)~~

また、前作までは預け屋というところにポケモンを預けると卵が産まれる仕様だったのですが、今作からピクニックをすることで卵が産まれるという仕様に変更されました。

# 制作物
今回作ったプログラムは以下の偉大なプログラムによって成り立っています。

私のプログラムはこの派生形みたいなものです。
- https://github.com/mart1nro/joycontrol
- https://github.com/Almtr/joycontrol-pluginloader

リポジトリは以下です。(あまり綺麗なプログラムではないですが)

https://github.com/MAAAARCY/auto-pokemon-sv/tree/master

# 必要なもの
### 実機
- Raspberry Pi ModelB 4GB
    - ラズパイにこだわる必要は正直ないです
- Switch
### ゲーム内アイテム
- バナナ×大量
- バター×大量
- ピーナッツバター×大量

# ラズパイとSwitchのBluetooth接続について

https://ponkichi.blog/rapsberry-switch-01/

この記事を参考に行いました。あとjoycontrolのREADMEも参考にしました。

### ちょっと補足
基本的な手順は上の記事の通りで大丈夫ですが、一個だけ詰まったところがあるので補足

https://github.com/Poohl/joycontrol/issues/17

ここに書かれているように、joycontrolで使われるライブラリのhidのバージョンが異なるとAttributeErrorが出ます。

# 使い方
ラズパイとSwitchをbluetooth接続できるようにしたらリポジトリをクローンして以下のコマンドを実行します。二つの作業はどちらもエリアゼロの入り口手前で行います。

**現状ゲーム内のラグ等によりサンドイッチの制作部分の動作が怪しいので、もし上手く制作されなくてタマゴパワーLv.2が発動しなかった場合はプログラムの実行を中断しリセットしてください。**

### HatchEggs.py
#### 概要
5分間孵化作業を行うプログラムです。5分にした理由は、孵化に必要な歩数が多いポケモンで５個孵化するのに必要な時間が4分半だったからです。

1. 手持ちの先頭に孵化要員(特性ほのおのからだ等)を置いて卵を5個持つ
![IMG_7987.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589004/62fb4c90-2d30-50bb-e48b-002d10e14674.jpeg)

2. **ライド状態を解除して**以下のコマンドを実行(XX:XX:XX:XX:XX:XXはSwitchのMACアドレス)
```shell
cd ~/AutoPokemonSV/
sudo joycontrol-pluginloader -r XX:XX:XX:XX:XX:XX hatch-eggs/HatchEggs.py
```
### GenerateEggs.py
#### 概要
ピクニックを開始し、スーパーピーナッツバターサンドを制作してバスケットに入れられた卵を30分間回収し続けるプログラムです。

1. メニューのカーソルをバックに合わせ、以下の写真の位置でレポート
![IMG_7984.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589004/121b8ac2-3c01-909e-f812-fa8cc75796b3.jpeg)

2. **メニューを閉じて**以下のコマンドを実行 
```shell
cd ~/AutoPokemonSV/
sudo joycontrol-pluginloader -r XX:XX:XX:XX:XX:XX generate-eggs/GenerateEggs.py
```

# SVでの孵化厳選の最適化
今作は孵化厳選をどこでも出来るので、どこで孵化するのが最適なのか考える必要があります(~~「そんなの面倒だから銀の王冠使え」とか言ってはいけない~~)。
手動で厳選するなら正直どこでもいいんですけど自動化するとなると**以下の条件**が必要になります。
- ポケモンor人がいない場所
    - 自動で操作する際にポケモンにエンカウントしたりすると非常に面倒なので
- 傾斜のゆるやかな場所
    - 傾斜が急だとピクニックを始められないので
- 建物などの障害物が少ない
    - 自動操作をしやすくするため

今のところこれらの条件をある程度満たす場所が、**エリアゼロの入り口手前**だと思った(最適解ではない)ので今回はそちらで孵化作業を行うようにしています。

# 今後について
今の状態でも孵化厳選を行うことはできますが卵を集める作業と孵化する作業が完全に分離しているので「卵収集→孵化作業」と**自動的に遷移**できるようにしたいです。

また、OCRを使って**個体値チェック**も行えるようにする予定です。本当は今回の記事にそれも盛り込むつもりだったのですが、Switchの映像を取り込むキャプボで不都合が起きて間に合いませんでした。

機能を追加したらリポジトリのREADMEと記事に追記したいと思います。

# 最後に
一応動作するという感じなので、あまり安定性には期待しないでください（**これから改善に努めます**）。

あとこのプログラムを走らせてる時に何回かエリアゼロ手前付近でもポケモンに何回かエンカウントしたので、孵化作業を自動化する上では最適解ではないなと感じました。（やっぱり預け屋ほしい...）

ここ孵化作業するのにオススメだよ！みたいな場所があれば教えて下さい。

ポケモンSVは歴代の作品の中でもストーリーがよくできててめちゃくちゃ面白いので是非遊んでみてください。そしてみんなもランクマッチの沼にハマりましょう。以上です。

↓どうでも良いけどメークルじゃなくてメェークルなんですね
![IMG_7986.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589004/86d23c33-a145-0a0b-0e31-ce9b9f69251a.jpeg)