画像認識(Poke-Controller)を使った「学園最強大会」自動化(DLC対応)

「ポケットモンスター スカーレット・バイオレット(SV)」エンディング後の「学園最強大会(バトルスクールウォーズ)」での「手持ち6匹で自動周回する方法」についての記事です。
(DLC後編クリア以前は)1匹で勝てる(「ハイパーボイス」夢ニンフィア等を持っている)なら「マイコン/マクロコンを使ってAAABB繰り返し入力」で十分ですが、
Lv不足で安定して勝てない場合や、将来「ハッピータイム」が解禁された場合に有用になるかと思います。

【追記2023/02/28】
SVのDLC早期購入者特典(〜10/31)で「ハッピータイム」ヒスイゾロアーク配布
https://www.pokemon.co.jp/ex/sv_dlc/ja/lineup/230228_03/
「ハッピータイム(賞金2倍)」が解禁されたので連打して「ひんし」になったら交代する本プログラムの仕組みが活かせるようになりました。
ドーブルを早く「ひんし」にしたいのでなるべく耐久の低いLv62@スカーフが理想な為)

【追記2023/12/31=DLCキタカミ後編解禁後】
SVのDLC後編配信で野生ドーブルが解禁されたので特性〔イリュージョン〕のエフェクトを出さずに使えるようになりました。
ドーブルを使う場合、早く「ひんし」になって欲しいので『きあいのタスキ』ではなく『こだわりスカーフ』で最速Lv62を使うのが理想です。
(強化キハダ先生の先発「ねこだまし」「マッハパンチ」カポエラーLv80には「ハッピータイム」させてもらえませんが…総合的にはこれが良いはず…。)

しかし、同時にDLC後編クリアすると学園最強大会のトレーナーが強化され、ネモのジャラランガが〔ぼうおん〕で「ハイパーボイス」を無効化する為、夢ニンフィア単独周回が不可能になってしまいました
賞金も少し増えましたが、単独周回可能なのは「れいとうビーム」ホワイトキュレム@『こだわりメガネ』と『おまもりこばん』を持たせられず大幅に効率が落ちてしまいました。
ですが、この自動化であれば戦闘役に「ムーンフォース」を覚えたポケモン(ハバタクカミ等)を増やすだけで対応できるので問題なく、以前より有用になりました。

自動戦闘の課題

SVではストーリー中の「かちぬきモード」が廃止され「いれかえモード」固定なので手持ちが2匹以上だと「入れ替えますか?」と聞かれます。
その為、A連射コントローラーでは(聞かれずに済む)手持ち1匹での周回しかできません。
前述のマクロコンであれば「AAABB」繰り返しにすれば、この問題は解決し控えのレベル上げができますが、戦闘に使えるのは1匹だけです。
そこで画像認識を使い、『自動で挑戦し、交代キャンセルしながら戦い、「ひんし」になった場合は次のポケモンに交代するプログラム』を作成しました。

用意するポケモン(DLCキタカミ後編解禁後)

ドーブルLv62(S252、他0)「ハッピータイム」@『こだわりスカーフ』
ニンフィアLv100(C252、S実数値201、他防御)「ハイパーボイス」@『おまもりこばん』
ハバタクカミ/ニンフィアLv100(C252、S実数値201、他防御)「ムーンフォース」@『こだわりメガネ』
ニンフィアLv100(C252、S実数値201、他防御)「ハイパーボイス」@『こだわりメガネ』
※技を一つにしないとゲンガーの〔のろわれボディ〕で技が選べなくなりストップする。
他2匹はレベルを上げたいポケモンで埋める。

プログラムの内容

画面に「学園最強大会」の吹き出しがあればA数回連打して挑戦(自動挑戦)。
画面に「ポケモン/バック/にげる」のコマンドがあればA数回連打で技を出す(自動戦闘)。
画面に「ひんし(交代画面)」の文字があれば「下、A、A」と入力し交代(自動交代)。
どれも無ければ「B」入力(メッセージ送り、進化キャンセル)。

以上を繰り返します。
【注意】レベル上げに使う場合、Bで進化キャンセルしてしまうので、タイミングを見てドックから外す/進化させてから使う/Lv100に「ふしぎなアメ」を使う方法で進化させるなどで対応してください。

判定用画像(参考)

判定用画像

※交代画面判定は「たたかえない」でも良いかもしれないです。

参考動画

youtu.be

プログラム

Microsoft OneDrive
プログラムは「C:\PokeCon\Poke-Controller-Modified\SerialController\Commands\PythonCommands」へ、
画像は「C:\PokeCon\Poke-Controller-Modified\SerialController\Template」へそれぞれ入れてください(出力設定デフォルトの画像なので各自作り直した方が良いです)。

以下ソースコード
from Commands.PythonCommandBase import PythonCommand, ImageProcPythonCommand
from Commands.Keys import KeyPress, Button, Direction, Stick, Hat

class AutoShinyCelebi(ImageProcPythonCommand):
NAME = '自動スクールウォーズ(自動交代,進化なし'

def __init__(self,cam):
super().__init__(cam)

def do(self):
print("-------------------------------")
print("SV自動「学園最強大会」周回【日本語版】")
print("Developed by えらー")
print("先頭「ハッピータイム」ドーブル、2~3匹目ニンフィア、後ろ3匹のレベル上げ可能")
print("オート進化キャンセル")
self.wait(0.5)
count = 1
print("Start")

while True:
#大会エントリー
if (self.isContainTemplate('SV_BSW.png', threshold=0.8, use_gray=True, show_value=False)):
self.wait(0.1)
print("エントリー")
self.press(Button.A, 0.5, 6.0) #Aを押してテキスト送り
self.press(Button.A, 0.5, 0.5) #Aを押してテキスト送り
self.press(Button.A, 0.5, 0.5) #Aを押してテキスト送り
self.press(Button.A, 0.5, 0.5) #Aを押してテキスト送り
self.press(Button.A, 0.5, 0.5) #Aを押してテキスト送り
self.press(Button.A, 0.5, 0.5) #Aを押してテキスト送り
self.press(Button.A, 0.5, 0.5) #Aを押してテキスト送り
self.press(Button.A, 0.5, 0.5) #Aを押してテキスト送り
self.press(Button.A, 0.5, 0.5) #Aを押してテキスト送り
else:
self.press(Button.B, 0.3, 0.3)

#わざ選択
if (self.isContainTemplate('SV_Battle.png', threshold=0.8, use_gray=True, show_value=False)):
self.wait(0.1)
#print("たたかう")
self.press(Button.A, 0.5, 0.5) #Aを押してテキスト送り
self.press(Button.A, 0.5, 0.5) #Aを押してテキスト送り
else:
self.press(Button.B, 0.3, 0.3)

#ポケモン交代
if (self.isContainTemplate('SV_hinsi.png', threshold=0.8, use_gray=True, show_value=False)):
self.wait(0.1)
#print("交代")
self.press(Hat.BTM, 0.1, 0.1) #ポケモン選択
self.press(Button.A, 0.5, 0.5) #Aを押してテキスト送り
self.press(Button.A, 0.5, 0.5) #Aを押してテキスト送り
else:
self.press(Button.B, 0.3, 0.3)