【Arduino自動化18】ローカルレイド自動配布【デリバードレイドでマックスこうせき】

ますたーです。こんにちは。

前回の更新から1ヶ月が経ち、5月になりました。業務繁忙で、文字通り「忙殺」される毎日でした。

 

さて、今回は、前々回の記事(第17回)のコメント欄でリクエストをいただいた、「レイドを自動でローカル配布するプログラム」を紹介します。

Arduino自動化記事も今回で第18回。これからもよろしくお願いいたします。

 

なお、Arduino Leonardo自動化の導入・機材構成については導入記事を参考にしてください。

導入記事:【Arduino自動化01】Arduino開発環境の導入

※本ブログに初めてお越しの方は「本ブログについて」もぜひ、ご覧ください。

 

概要

ローカル通信(YY通信)でのレイドバトル配布を自動で繰り返し行います。待機時間の変更・バトル時のA連打時間も変更可能です。

f:id:tangential_star:20210503200445g:plain

レイド募集→みんなで挑戦→30秒待機→レイド開始→リセット…を自動で繰り返す
(上記画像は「レイド開始まで30秒」「開始後リセットまで9秒待機」で設定)

2021年9月20日追記:「ひとりで挑戦」に対応したプログラムを公開しました。合わせてご参考ください
【Arduino自動化19】ねがいのかたまりで自動レイドバトル周回【完全放置で「けいけんアメ」「ヨロイこうせき」】

2021年10月10日追記:Switch2台(レイド配布+レイド周回)に対応したプログラムも公開しました。
【Arduino自動化20】Switch2台で「完全」自動!レイドバトル自動周回【デリバード・色違いレイドなど】

 

もくじです。

今回は、レイド配布について一般論など余談を交えて記載しています。

基本的にローカル通信でのレイド配布に焦点を当て、中でもデリバードレイドに焦点を当てて執筆しています。例のごとく長めに丁寧に書きました。もし「説明なぞいらぬ!プログラムだけ寄越せ!」という方は、どうぞ⇒読み飛ばす

 

レイド周回とは

いつものごとくまずは余談から入ります。今回の目的まで読み飛ばしOKです。

用語の説明になりますが、「レイド周回」とは、友人や仲間で集まって、レイド募集側・参加側に分かれて参加側が高効率に報酬を稼ぐという行為を言います。

より具体的には、レイド募集側のプレイヤーは目的のレイドを出現させてセーブし、YY通信でメンバー募集し参加したら挑戦してまもなく切断を繰り返します。参加側のプレイヤーは、募集されているレイドに参加して最後までクリアし、レイドポケモンの捕獲や報酬の受け取りを繰り返します。

ヌケニンハピナスタブンネデリバードなど、レイド報酬が高効率なマックスレイドバトルを周回したり、乱数調整(Arduino自動化05)で出現させた任意の色違いレイドを周回して色違いポケモンを何匹も捕獲したりなど、目的のレイドを1度作りさえすれば、他のロムで何度も挑戦して量産できるのがポイントです。

f:id:tangential_star:20201123161659g:plain
f:id:tangential_star:20210501190713g:plain
レイド周回すれば、色違いのポケモンや希少なアイテムを量産できる

レイド周回の募集側を「レイド配布」と呼ぶ

上記のように、友人や仲間で一緒に遊べる人はともかく、現実には時間や場所の制約でなかなか難しかったり、そもそもそんな仲間がいない人もいます。

その場合、2台以上のSwitchを持っているユーザーならば、上記の募集側・参加側を自作自演することで高効率のレイドに挑戦し続けることができます。特に同一レイドには3人まで参加側を募ることができるため、1度に3台(つまり、主催者とは他の3人)までは高報酬の恩恵を得ることができます。この募集側、つまりは高報酬のレイドを配布している主催者(通信ホスト)あるいはこの行為を「レイド配布」と俗に呼びます。

必ずしもローカル通信に限定されることはなく、有志の方々がオンラインで上記のような高報酬レイドバトルや、色違いレイドのおすそ分けとして募集を呼びかける場合もあり、これも「レイド配布」と呼ばれています(狭義には、オンラインでのレイド募集に限定してレイド配布と呼びます)。ちなみに、レイド配布の手順は下記の通りです。

【レイド配布のやり方(募集側)】

  1. 目的の巣穴を出してセーブ
  2. オンラインで募集する場合は、YY通信からインターネット接続
  3. 巣穴で『みんなで挑戦』から募集を募る
  4. 挑戦が始まり、レイドバトルが始まったらHome画面に戻りリセット
  5. 以降、手順3~4を繰り返し

この「レイド配布」のよくある身近な例としては、チャンネル登録者数を増やして収益化をしたいYouTube投稿者が、募集側としてレイド配布を行う代わりにチャンネル登録と高評価を促しつつ、その様子をYouTube他で生配信するという使い方でしょうか。YouTubeニコニコ動画ほか、配信動画共有サイトで「レイド配布」と検索するとたくさん出てきます。

なお、レイド配布自体は特に問題は無いと考えますが、その使われ方・是非についてはここでは言及しません。各人が良識の範囲内で遊んでいただければ幸いです。

 

ローカルでレイド配布をしたい(今回の目的)

さて、ローカル通信でのレイド配布に話を戻します。

私を含め、Switchを2台持っているユーザーからすれば、片方でレイド配布を、もう片方で周回してひたすら攻略…としていきたいのですが、いかんせん、2台のSwitchを同時に操作するのはめんどくさいのです。言わずもがな、3台・4台のSwitch所有者であればなおのことでしょう。ほかにも、募集側・参加側の両方を操作すると、別の作業をする時間・余裕が意外と無く、ガッツリと周回作業に時間を取られることになります(つまり、勉強や仕事の合間に周回する、みたいなことができません)。

f:id:tangential_star:20210504140008g:plain

Switch2台(募集側・参加側)の両方を操作をしなければならず、とても大変

 

そこで、今回の自動化記事では、募集側(レイド配布側)の作業を完全自動にするプログラムを紹介します。

基本的にローカル環境であれば、誰かが「準備完了」を押さなくて予定時間内にレイドが開始できないといったトラブルも未然に防げる上、レイド中に回線切断、あるいはそれに付随したバグや障害が万が一発生しても自己責任のもと実行できます。

なお、オンライン(YY通信インターネット接続)でのレイド配布については私の環境では動作確認・検証ができないため、そういった意味でもまずはローカル通信でのレイド配布を実装していきます。

 

デリバードレイドの報酬は「マックスこうせき」含め最高効率!?

続いて今回の主な目的たる「デリバードレイド」の紹介です。

嘘か真か、一説にはデリバード」のマックスレイドバトルの報酬は、数あるレイド報酬の中で最高効率とも言われています。特筆すべきは、「マックスこうせき」「ドリームボール」の存在でしょう。有志の検証によれば、マックスこうせきが2個確定ドリームボールが1~3%金の王冠が1~5%でドロップするようです。

さらに、デリバードレイドは★3-4レイドなら1ターン攻略が可能。筆者の実測値でもわずか1周あたり1分35秒と、高速周回が可能です。なお、周回を目的とする場合、★5レイドでは最短でも2ターンかかるため、時間効率を考えると★4レイドを周回するのが効率的です。

f:id:tangential_star:20210501190713g:plain
f:id:tangential_star:20210504144905p:plain
デリバードレイドは「マックスこうせき」が【2個】確定で手に入る
1周あたり1分35秒。単純計算でダイマックスアドベンチャーと同等以上の効率になる
f:id:tangential_star:20210504230301g:plain
f:id:tangential_star:20210504230350p:plain
デリバードレイドでは「ドリームボール」が低確率(★4レイドで2%)で手に入る
マックスこうせき・けいけんアメ・ふしぎなアメなどを含めると実に好報酬

まずはデリバードレイドの1ターン攻略要員を育てよう

前述の通り、星3-4レイドであれば、デリバードのレイドバトルは1ターンでの攻略が可能です。募集側・周回側で手持ち1匹ずつ、少なくとも2匹を周回用に固定してNPCポケモンに依存しない、安定した周回を目指しましょう。

そのためには、下記条件を満たすポケモン・わざを準備する必要があります。

  • デリバードよりも先行して攻撃できるポケモン2匹(レベル100が望ましい)
  • NPCの特性など(コータスの『ひでり』等)で威力が半減しない『わざ』
  • 初撃要員のほうが、追撃要員よりも素早い(あるいは確実に先制が取れる)
  • 初動の1撃で確実にバリアを展開させるまで持っていける高火力
  • 追撃でバリア展開状態から確1で持っていける高火力

これらの条件に合うポケモンは複数検証報告されていますが、ここでは、参考までに筆者の使用ポケモンを紹介します。検証するのが面倒な方はご参考ください。

なお、より多くのプレイヤーに向けてレイド配布をするために、ホスト側がレイド開始直後にリセット(通信切断)することがありますが、その場合には、あらかじめ上記のわざ以外は忘れさせておきましょう。ランダム選択されたときに確実にそのわざが使用できないと、参加側の周回効率が大きく落ちるためです。

初撃オススメ:Cぶっぱレジエレキ「エレキボール」

レジエレキはS種族値200というトンデモ性能で、デオキシススピードフォルムすら抜き去る圧倒的な素早さの持ち主。そのユニークな特性「トランジスタ」により、でんきタイプのわざであれば実数値1.5倍の火力を出せるため、初撃に使うにはもってこいです。

でんきタイプなので、デリバードには抜群を取れる上、ひでり・あめふらし等の天候による威力増減も無く非常に安定した初動要員として重宝します。わざは命中安定&高火力な「エレキボール」一択でしょう。

なお、バリアを張る既定値までHPを削るだけで良いので、十分なレベル差・素早さがあれば、初撃に関しては過剰な火力は不要です。妥協して、例えばテッカニンなどでも十分に削ることができます。

f:id:tangential_star:20210504164042g:plain
f:id:tangential_star:20210504164006j:plain
初撃オススメはCぶっぱレジエレキによる圧倒的素早さからのエレキボール

追撃オススメ:ASぶっぱ夢ルガルガン@こだわりハチマキ「ストーンエッジ

続いて、追撃要員の紹介です。こちらは、こうげき努力値に極振りし、こだわりハチマキを持たせたルガルガンストーンエッジがオススメです。夢特性であれば「ノーガード」になるため命中不安なエッジを確定で当てることができます。また、いわタイプなので、デリバード(こおり・ひこう)の4倍弱点を突くことができることもポイントです。無論、天候による威力増減の影響も受けません。

なお、追撃要員は、デリバード「ふしぎなバリア」込みで確1に持っていくだけの圧倒的火力が必要です。きちんと確1で持っていけることを検証しておきましょう。

ちなみに、ふしぎなバリアは攻撃ダメージを1/10に軽減するため、抜群を突くか、過剰な火力を叩き込まないと確1で持っていけません。無論、NPCが攻撃してくれること前提であればやや火力不足でも1ターン周回は可能ですが、安定効率を高めるには必須でしょう(コスモパワーをやたら使いたがるソルロックとかいますからね)。

f:id:tangential_star:20210504164026g:plain
f:id:tangential_star:20210504164011p:plain
追撃オススメはASぶっぱルガルガン夢特性:ノーガード)のストーンエッジ

これらのポケモンを準備したら、配信側・参加側の2プレイヤーがそれぞれ1匹ずつを持つように手持ちの先頭にあらかじめ加えておきましょう

どちらのプレイヤーがどちらのポケモンを使っても構いませんが、少なくともホスト側のプレイヤーの覚えているわざは1つにしておきましょう。

 

事前準備1.カンムリ神殿の巣穴でレア柱を建てる

デリバードは、冠の雪原の様々な場所のレア柱(紫の太い光柱)で稀に出現しますが、アクセスのしやすさを考えると一番のオススメは「カンムリ神殿」の巣穴です。巣穴の周りには野生ポケモンもおらず、そらとぶタクシーから徒歩3秒の好立地です。

そらとぶタクシーでカンムリ神殿に降り立ったら、左手に進み、「ねがいのかたまり」を投げ入れてレアな柱(紫色の光柱)を建てましょう。

後は、デリバードの★4レイドがでるまで日付変更を繰り返してください。妥協する場合はデリバードの★3レイドでもOKです。

f:id:tangential_star:20210504173750g:plain
f:id:tangential_star:20210504173019g:plain
カンムリ神殿の巣穴のレア柱で「デリバード★4」レイドを出現させよう

目当てのレイドを出現させたら、巣穴の目の前でセーブしてください。目安として、Aをクリックしたら巣穴に話しかけられる状態です。

f:id:tangential_star:20210504194801p:plain

Aを押したら巣穴のレイド募集画面に入れる状態でレポートを書いておこう

 

事前準備2.プログラムの書き換え

おまたせしました。遂にプログラムの書き換えです。

ソースコード全文は後述しますが、必要に応じて2つの値(WAIT_TIMEとBATTLE_TIME)を修正してください。

なお、基本的に今回のプログラムはローカル配布を想定していますので、レイドパスコードの設定は実装しておりません。

書き換える値はWAIT_TIMEとBATTLE_TIMEの2箇所

#define WAIT_TIME (30)   // 「みんなで挑戦!」を押してから何秒待ち続けるか?
#define BATTLE_TIME (9)  // 挑戦後、何秒間レイドバトルを継続するか?(その間はA連打をします)

これらの値は、それぞれホスト側(募集側=レイド配布側)の待機時間を表します。具体的には、WAIT_TIMEは「みんなで挑戦」を押してから他のプレイヤーを何秒間待ち続けるかを、BATTLE_TIMEは「挑戦する」を押してから実際のレイド画面にかけて、何秒間A連打を続けるかの設定をそれぞれ表します。

BATTLE_TIMEの時間中は、A連打を続けるプログラムにしていますが、これによってレイドバトルを中断することなく、たたかう→1番目のわざを選んで進めてくれる、というわけです。そのポケモンを倒すまでの時間を計測して値を入れておくと、一人でローカル通信を行う分には重宝します。

一応、初期値としてはWAIT_TIMEを(30)、BATTLE_TIMEは(9)に設定しています。もし、レイド配布の際にレイドポケモンの姿をひと目見てからリセットしたい場合は(16)程度にしておくと良いと思います。また、レイド開始直後にリセットせずに、戦闘も行わせたい場合にはBATTLE_TIMEを十分に長い秒数で指定すると良いと思います、

星4デリバードレイドでのBATTLE_TIMEのオススメ設定は(55)

まずは結論から。前述のオススメポケモン2体で星4デリバードレイドを周回する場合には、BATTLE_TIMEを(55)に設定するのがオススメです。

以下説明ですので、本項は読み飛ばし可です。→読み飛ばす

レイドバトル開始直後にすぐさまリセットし、次のレイドを開いて募集するオンラインでのレイド配布とは異なり、ローカル通信でのレイド配布では通信切断のタイミングをバトル終了後~報酬画面前に調整するのが一般的です。これは、レイドを開催するまでのスパンを短くして、より多くの不特定多数のプレイヤーにレイド配布を行うという目的の「オンラインでのレイド配布」とは異なり、ローカル通信環境では高々3人までが固定周回を行うことに由来します。

オンラインのレイド配布に参加した際、あるいは、通信レイド中に回線切断が起こった場合に、1分ほど入力を受け付けない時間(通信待機中…となったり、何のダイアログも出ないままバトルの進行が止まったりなど)が発生することがあります。これは、ポケモン剣盾でバトル進行の同期を取るために、通信のタイムアウト設定がなされているからです。つまり、レイドバトル中は、ホスト(募集側)がゲームをリセットすると、当該レイドに参加中のプレイヤーが最大1分間そのホストの応答を待つ挙動をするのです。この仕様はローカルレイドでも同様なので、レイド開始直後にゲームリセットを行うとそのまま1分間待たされることになります。一方で、レイド終了の撃破演出の後はこの同期(通信待機)がなくなるため、任意のタイミングでリセットが可能です。

そのため、ローカル通信でレイド周回をする際には、募集側もレイドポケモンを倒すまで一緒に操作して、ポケモンを撃破した演出が出てから(=捕獲画面になってから)リセット→次のレイドを立ち上げる、という流れで進めることが一般的です。そこで、今回のプログラムもこれに倣い、あらかじめプログラムにはA連打を仕込んでおき、レイドバトルもA連打で自動化する、という構成に仕上げてあります。

ここで、星4デリバードの撃破にかかる時間は上記2匹を利用した場合、おおよそ45秒です。さらにNPCが「ひでり(コータス)」「ぎょぐん(ヨワシ)」「いかく(ハリーセン)」「プレッシャー(マニューラ)」などの戦闘開始時に発動する特性を使ったり、「てだすけ(イーブイ)」「このゆびとまれ(ピッピ)」「ふいうち(マラカッチ)」などの先制技を使ったりすると、45秒に加えてこれらの時間分待機時間が増えることになります。おおよそ特性演出は5秒程度ですので、45秒+5秒+5秒程度の時間があれば良いことになります。

f:id:tangential_star:20210504204955g:plain

「いかく」「ひでり」を持つポケモンNPCから同時に選出されることが稀にある。
この際、バトルにかかった時間(開始~撃破演出まで)は55秒だった

手動検証中、ハリーセンコータスの2匹が出現したことがありました。この時のバトル終了までの時間(挑戦開始~撃破演出まで)の実測値は55秒でしたので、前述の数字(仮説)は概ね正しいと言えるでしょう。ゆえに、BATTLE_TIMEは(55)程度で設定しておけば良いことになります。

なお、それぞれのモーションが長めになる、ヨワシの「ぎょぐん」+イーブイの「てだすけ」に加え、「ストーンエッジ」が急所に当たると、55秒を若干超えるようなので、心配な方は(60)秒くらいにしておくと良いかもしれません。逆に長すぎると周回効率が下がるばかりか、レイド終了後そのまま巣穴に「ねがいのかたまり」を投げ入れてセーブしてしまうため、注意しましょう。

 

ソースコード

前述の通り、ソースコード冒頭のWAIT_TIMEとBATTLE_TIMEの値を各自で必要に応じて修正してください。上記にはケーススタディとしてデリバードでのレイドを中心に、設定数値の紹介などをしております。合わせてご参考ください。

WAIT_TIMEは他のプレイヤー参加を待つ時間、BATTLE_TIMEは、レイドバトルの進行(戦闘)にかかる時間(いずれも単位は「秒」)です。

/* 
 *  固定レイドYY通信(ローカル)配布
 *  目的のレイドが出現した巣穴の目の前でセーブしておくこと。
 *  あとは、Arduinoを挿すだけで自動でレイド募集→挑戦→リセットを繰り返します。
 *  
 *  (c) 2021 ますたーの忘備録
 *  https://tangential-star.hatenablog.jp/
*/

#include <SwitchControlLibrary.h>

#define HOLDTIME (95) // 1回のキー入力の長押し時間[ms]

#define WAIT_TIME (30)   // 「みんなで挑戦!」を押してから何秒待ち続けるか?
#define BATTLE_TIME (9)  // 挑戦後、何秒間レイドバトルを継続するか?(その間はA連打をします)
// レイドを開始するまでなら(9)秒でOKです。
// 登場ポケモンの姿を見たい場合(色違い確認など)は(16)秒くらいで設定ください。
// なお、このBATTLE_TIME中は、ずっとA連打をしてくれます。
// レイドバトル中も自動操作させたい場合は(16)以上の数字を入力してもOKです。
//   ※使うわざを先頭にしておく必要があります
// ただし、レイド終了の如何に関わらずひたすらA連打をし続けるため、この設定が適切で無い場合、
// 巣穴に新たな願いのかたまりを投げ入れてしまうので注意してください。
// デリバードレイドの場合の目安は(55)です(ひでり+いかくエフェクト込みでデリバード1ターン撃破までの秒数)。
// 56秒であれば、NPCの上記特性の発動無しでも、ポケモン捕獲エフェクトで中にリセットされるため大丈夫だと思います
// 心配な方は(60)くらいにしておくと良いかと思います。各人で調整ください。

void PushRL(int delay_time_ms);
int PushKey(char* keyname, int holdtime, int delaytime);
void NextDayInCheatMode(void);

void setup() {
  // コントローラーとして認識されるためにRLを7回ほどカチャカチャする
  for(int i=0;i<7;i++)PushRL(300);
  delay(1000);
}


void loop() {
  unsigned long int current_time=0;
  unsigned long int start_time=0;
  unsigned long int temp_time=0;

  // 巣穴の前で乱数したい個体を出してセーブした状態。
  
  PushKey("A", HOLDTIME, 1500); // 募集画面に入る

  PushKey("A", HOLDTIME, 2500); // みんなで 挑戦!(→通信待機中 しばらくお待ち下さい)
  PushKey("UP", HOLDTIME, 300); //
  PushKey("A", HOLDTIME, 500); // 準備完了!
  PushKey("A", HOLDTIME, 500); // バトルを 開始する
  PushKey("A", HOLDTIME, 500); // 参加人数が足りません! ▼ (→サポートの トレーナーが 参加しますが よろしいですか?)
  delay(1000UL*WAIT_TIME); // WAIT_TIME秒待機する
  PushKey("A", HOLDTIME, 300); // →はい

  // 挑戦画面~レイドバトル(誰かが「準備完了」を押しそこねていた場合のケアも兼ねてA連打)
  for( start_time=millis(), current_time=start_time ; current_time - start_time < (unsigned long)BATTLE_TIME*1000UL ; current_time=millis() ){
    if( current_time - start_time < (unsigned long)(BATTLE_TIME-3)*1000UL )PushKey("A", HOLDTIME, 300); // ひたすらA連打
  }

  // リセットして次の挑戦
  PushKey("Home", HOLDTIME, 1000); // ゲーム終了のためのHomeボタン
  PushKey("X", HOLDTIME, 500);     // 終了Xを押す→終了しますか?画面
  PushKey("A", HOLDTIME, 3000);    // はい→終了しています・・・
  PushKey("A", HOLDTIME, 1000);    // ゲームタイトルクリック→ユーザを選んでください画面(複数ユーザいる場合)
  PushKey("A", HOLDTIME, 18500);   // A押してから起動までおおよそ16秒(最短目安。環境に合わせて設定すること)
  PushKey("A", HOLDTIME, 10000);   // タイトル画面からフィールド遷移までおおよそ10秒(環境に合わせて設定すること)

}

void PushRL(int delay_time_ms){
  SwitchControlLibrary().PressButtonR();
  SwitchControlLibrary().PressButtonL();
  delay(HOLDTIME);
  SwitchControlLibrary().ReleaseButtonR();
  SwitchControlLibrary().ReleaseButtonL();
  delay(delay_time_ms);
  return;
}
int PushKey(char* keyname, int holdtime, int delaytime){
  // ホームボタン・方向キーはRight, Left, Up, Down, Homeなど2文字以上で入力。
  // その他ボタン入力は1文字(A,B,X,Y,R,L,+,-)ZR・ZLにも対応
  // 同時押しは非対応
  
  if(strlen(keyname)==1){
    switch(keyname[0]){
      case 'A': case 'a': // A
        SwitchControlLibrary().PressButtonA(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonA(); delay(delaytime);
      break;
      case 'B': case 'b': // B
        SwitchControlLibrary().PressButtonB(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonB(); delay(delaytime);
      break;
      case 'X': case 'x': // X
        SwitchControlLibrary().PressButtonX(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonX(); delay(delaytime);
      break;
      case 'Y': case 'y': // Y
        SwitchControlLibrary().PressButtonY(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonY(); delay(delaytime);
      break;
      case 'L': case 'l': // L
        SwitchControlLibrary().PressButtonL(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonL(); delay(delaytime);
      break;
      case 'R': case 'r': // R
        SwitchControlLibrary().PressButtonR(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonR(); delay(delaytime);
      break;
      case 'H': case 'h': // Home
        SwitchControlLibrary().PressButtonHome(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonHome(); delay(delaytime);
      break;
      case '+': case 'p': case 'P': // Plus
        SwitchControlLibrary().PressButtonPlus(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonPlus(); delay(delaytime);
      break;
      case '-': case 'm': case 'M': // Minus
        SwitchControlLibrary().PressButtonMinus(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonMinus(); delay(delaytime);
      break;
      default:
      break;
    }
  }else if(strlen(keyname)>=2){
    switch(keyname[0]){
      case 'z': case 'Z': // ZR/ZL
        if(keyname[1]=='R'||keyname[1]=='r'){
          SwitchControlLibrary().PressButtonZR(); delay(holdtime);
          if(holdtime>0)SwitchControlLibrary().ReleaseButtonZR(); delay(delaytime);
        }
        if(keyname[1]=='L'||keyname[1]=='l'){
          SwitchControlLibrary().PressButtonZL(); delay(holdtime);
          if(holdtime>0)SwitchControlLibrary().ReleaseButtonZL(); delay(delaytime);
        }
      break;
      case 'r': case 'R': // right
        SwitchControlLibrary().MoveHat(2); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().MoveHat(8); delay(delaytime);
      break;
      case 'l': case 'L': // left
        SwitchControlLibrary().MoveHat(6); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().MoveHat(8); delay(delaytime);
      break;
      case 'u': case 'U': // up
        SwitchControlLibrary().MoveHat(0); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().MoveHat(8); delay(delaytime);
      break;
      case 'd': case 'D': // down
        SwitchControlLibrary().MoveHat(4); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().MoveHat(8); delay(delaytime);
      break;
      case 'H': case 'h': // Home
        SwitchControlLibrary().PressButtonHome(); delay(holdtime);
        if(holdtime>0)SwitchControlLibrary().ReleaseButtonHome(); delay(delaytime);
      default:
      break;  
    }
  }else{
    return -1;
  }
  return strlen(keyname);
}
void NextDayInCheatMode(){
  // ★日付変更
  // Homeボタンを押して設定の画面へ移動
  PushKey("Home", HOLDTIME, 1000);

  // Home画面で「設定」を選ぶ
  PushKey("down", HOLDTIME, 105);
  PushKey("right", HOLDTIME, 105);
  PushKey("right", HOLDTIME, 105);
  PushKey("right", HOLDTIME, 105);
  PushKey("right", HOLDTIME, 105);
  PushKey("right", HOLDTIME, 105);
  PushKey("A", HOLDTIME, 1500);

  // 設定画面で「日付と時刻」を開く
  PushKey("down", 1500, 105); // 1.5秒「↓」長押し
  PushKey("right", HOLDTIME, 105); 

  for(int i=0; i<4; i++){
    PushKey("down", HOLDTIME, 55);
  }
  PushKey("A", HOLDTIME, 500);

  // 時間設定(現在の日付と時刻を選ぶ)
  PushKey("down", HOLDTIME, 105);
  PushKey("down", HOLDTIME, 105);
  PushKey("A", HOLDTIME, 500);

  // 時刻設定(日付の部分のみ回していく
  // 時間の変更
  PushKey("right", HOLDTIME, 105);
  PushKey("right", HOLDTIME, 105);
  PushKey("up",    HOLDTIME, 105);
  PushKey("A", HOLDTIME, 105);
  PushKey("A", HOLDTIME, 105);
  PushKey("A", HOLDTIME, 105);
  PushKey("A", HOLDTIME, 105);
  PushKey("Home", HOLDTIME, 2000);
  PushKey("A", HOLDTIME, 1000);
  return;
}

 

このプログラムでレイド周回の作業負荷が半減!

今回のプログラムを使うことで、従来、募集側と参加側を1人2役でやっていたレイド周回作業の手間が文字通り半減しました

それだけでなく、コントローラーを持ち替える手間が減り、操作手順をそれぞれで考える必要がなくなり、体感負荷は半分以下になりました

f:id:tangential_star:20210504232424p:plain
f:id:tangential_star:20210504232540p:plain
常に2台を操作しなければならなかった周回作業が、1台のSwitch操作で完結
まさに劇的なビフォーアフターと言える

実際、プログラムを稼働させつつ、もう片方のSwitchをPCのキーボード前に置いてレイド周回を行いながら、なんと1時間以上にもわたり、無理なくこの記事の執筆作業を続けることができました。

f:id:tangential_star:20210504223406g:plain

レイド周回の募集側を完全自動化したことで、作業しながらでもレイド周回が可能に!
※殆どの時間、キーボードから手を離さなずに済んでいることがわかる(41倍速再生)

上記のGIF画像をご覧いただければ一目瞭然ですが、レイド周回から文字通り手が離せなかった従来とは違い、ほとんどの時間をキーボード作業ほかに充てることができています如実に、単純作業を代替させるにはArduinoは適任であると感じられる結果だったと考えます。

 

あとがき

気づけば5月になっていました。前回更新が3月28日でしたから、まるまる1ヶ月以上、更新できずでした。実際、3月~4月は年度末・年度初めによるものか業務繁忙で、あっという間に過ぎてしまいました。

ブログの更新はおろか、ゲームで遊ぶ時間もほぼ無く、かなり大変な2ヶ月でしたが、そんな中、本ブログに定期的に足を運んでいただいている方や、温かいコメントを残していただける方もいらして、やはり私のモチベーションにも繋がりますし、心の支えにもなっています。

また、このコロナ禍で在宅勤務が増え、仕事とプライベートの境が非常に曖昧になりつつある昨今ですが、このように趣味のポケモンが心の安寧・支えになっていることに改めて気付かされます。

今回のブログ更新のきっかけの一つは、やはり、前々回の記事(第17回)のコメント欄でリクエストをいただいたことにほかなりません。自分の中でも「いつか作りたい」「いつか更新したい」と思っていた内容ではあったものの、やはり明確に「ブログ記事が役に立っている」ことがわかると実装・執筆の意欲も段違いに上がりました。そういう意味でも、コメントをいただけると嬉しく思います。

 

もし、皆様にとって、本ブログがご参考・お役立ていただけているようであれば筆者としては嬉しく思いますし、その旨をコメントでご報告いただけるとさらに嬉しく思います

引き続き、本ブログをどうぞよろしくお願いいたします。

 

ではではc⌒っ.ω.)っ

 

前記事:【Arduino自動化05ex】乱数調整レイドでのArduino Leonardoの使い方

関連記事:【Arduino自動化19】ねがいのかたまりで自動レイドバトル周回【完全放置で「けいけんアメ」「ヨロイこうせき」】

関連記事:【Arduino自動化20】Switch2台で「完全」自動!レイドバトル自動周回【デリバード・色違いレイドなど】

導入記事:【Arduino自動化01】Arduino開発環境の導入

Arduino自動化記事一覧は こちら