ますたーです。こんにちは。
今回の記事は、Arduino で乱数調整の一部 手順と高速消費を自動化する方法 についてです。乱数調整の流れにそって説明します。今回の目標は、色違いのパッチルドン(乱数レイド産)を捕まえることです。
Arduino Leonardoでの自動化環境の導入については、導入記事 を参考にしてください。
※本ブログに初めてお越しの方は「本ブログについて 」もぜひ、ご覧ください。
【!】本記事では乱数調整の内容を扱います。
概要
本記事では、レイド乱数調整で必要な2つの作業をArduino で自動化します。 ・1つ目:「初期シード」を推定するための2Vポケモン 探し(3日進める作業) ・2つ目:「ランクマバグ※ 」状態での乱数消費(日付を進める作業) ※便宜上「ランクマバグ」と表記しますが、当ブログではランクマッチを使用しません。通信切断・初手降参の推奨もしません。
2020/12/5追記:NintendoSwitch Ver.11.0アップデート対応済です。 2021/9/20追記:NintendoSwitch Ver.13.0アップデート対応済です。 2022/10/23追記:NintendoSwitch Ver.15.0アップデート対応済です。
2021/3/28追記:補足記事を執筆しました。Arduino を使う具体的なタイミングについてもう少し詳しく知りたい、という方向けの記事です。合わせてご参考ください。
補足記事:【Arduino自動化05ex】乱数調整レイドでのArduino Leonardoの使い方
「シード特定用の3日後レイド厳選」と「高速乱数消費」をArduino で自動化(左:リセットして3日日付を進める 右:ランクマバグ状態で日付変更)
なお、本記事では乱数調整ツールは、さびたコイル氏の「1-StarSeedSearch 」を使います。記事のメインは、Arduino Leonardoによる一部手順の自動化になりますが、乱数調整の忘備録も兼ねた構成で書きますので、Arduino を持っていない人も乱数を始めたばかりorこれから始めるよっていう人にも読めるよう書いているつもり です。(丸2日間かけてできるだけ丁寧に書きました。是非とも参考にしてください)
「いや、ソースコード と使い方だけ寄越せ」って方はどうぞ→ソースコードと使い方
目次です(もりだくさん!)。
作ったきっかけ
前回の記事では、色違いパッチルドンを、自動カセキ受け取りで厳選する方法 について紹介しました。今回は、どうしても色パッチルドンの「ボール厳選」がしたくて、DLC でレイドバトルが解禁されたパッチルドンの色乱数に挑戦しました。結論、紆余曲折ありましたが成功しました。
待ちに待った色パッチルドンのお出まし!かわいいいいい!!!
剣盾レイドの乱数調整では、手動だとめちゃくちゃ大変な部分が2つあります。中でもArduino の価値が活きたのは、「何百日~何千日も日付を進める手順(乱数消費)」 だと思います。こちらは流石に手作業では骨が折れる…というか、ミスの温床なのでArduino で自動化しようというわけです。また、最初の厳選作業(3日日付を進めてツール指定の★3レイドが出るまでひたすらやり直す作業 )も地味に大変で、運が悪いと何度も挑戦することになります。ゆえに、こちらも自動化しました。
大前提
本記事では「乱数調整」の手順に沿った構成で書き下します。乱数調整の紹介をメインとする記事ではありませんので原理やツールの使い方、導入手順などの紹介は最小限に留めます。ソースコード と使い方だけ必要な方は適宜読み飛ばしてください。
⇒ 「ソースコードと使い方」まで読み飛ばす
ただし、Arduino の自動化は、あくまでも乱数調整の手順を簡略化するだけですので、全く予備知識がない状態で自動化を試みるのはリスクがあります。一度でも良いので、手動で乱数調整を試みてから、Arduino プログラムを使って自動化してみることを筆者としてはおすすめ いたします。
なお、乱数調整は改造・セーブデータの改竄とは違い、正規仕様の範囲内 で出現するポケモン の性別や個体値 、色違いの別を操作するものです。本稿で乱数調整の是非は問いませんが、本件ご理解の上、閲覧・活用くださいませ。
色パッチルドン探しの手順
パッチルドンの色違いを捕まえるまでは大きく4ステップあります。かなり長丁場ですが、オシャボ入り色違いパッチルドンのために頑張りましょう!
準備 (パッチルドンが出る巣穴にねがいのかたまりを投げ入れる)
乱数調整 (乱数ツールで、色違いが出るまでの日数を計算)
乱数消費 (計算日数-3日だけ日にちをひたすら進める)
捕獲 (手動で3日進めてパッチルドンを捕まえる)
なお、手順上に「@自動化可能」と書いているものは、Arduino Leonardoでの自動化プログラムを提供しています。適宜ご活用ください。ソースコード は後述します 。
1.準備パート
【色パッチルドン探しの手順】
1.準備 (イマココ) → 2.乱数調整 → 3.乱数消費 → 4.捕獲 (1-1. 乱数調整ツールを準備 1-2.目的の巣穴で柱を建てる)
1-1.乱数調整ツール(PC)を準備
まずは、乱数調整ツールをPCにダウンロードします。本稿では、さびたコイル氏がGPL3.0ライセンスで提供する「1-StarSeedSearch 」を使います。自身のPC環境に合ったものをダウンロード・解凍してください。筆者はWindows10(64bit)です。
起動したら、自身のバージョン・目的の巣穴に合わせて選択します。目的の巣穴の情報は、yakkun氏が運営するポケモン 攻略サイト 「ポケモン徹底攻略 」で検索して拾ってください。パッチルドンの場合は「雪中渓谷 G」「レア」でOKです。
1-StarSeedSearchをダウンロード&ZIP解凍し、OneStar.exeを起動
起動したら、パッチルドンの巣穴の場所(雪中渓谷G・レア)をプルダウン入力
1-2.目的の巣穴で柱を建てる
ツールへの入力を済ませたら、該当の巣穴に「ねがいのかたまり」を投げ入れて光の柱を立てます。パッチルドンの巣穴の場合は、入り口から登っていくよりも、カンムリ神殿から道なりに下ったほうがスムーズに到着できます。
「ねがいのかたまり」を投げ入れたら、念の為セーブをしておきます 。
なお、パッチルドンは紫の柱からし か出現しませんので、注意しましょう。
パッチルドンは雪中渓谷にいる。お気に入りのボールを準備しておこう。
パッチルドンの巣穴へはカンムリ神殿から下っていくとスムーズに着く
2.乱数調整パート
【色パッチルドン探しの手順】
1.準備 → 2.乱数調整(イマココ) → 3.乱数消費 → 4.捕獲 (2-1. 現在シードの特定 2-2.消費数の特定)
2-1.現在シードの特定
ここからは乱数調整の要となる、「初期シード値」の推定を行います。推定と言っても我々ではなくツールが計算してくれますのでご安心を。ただし、かなり運の要素が絡むため、この部分だけで下手すると1日が終わります。
2-1-1.3日後のオムスター 探し @自動化可能
まずは、3回日付を進めた上 で、自然発生Vを除いて2Vのポケモン (難しければ3Vのポケモン )を捕まえます。具体的なターゲットはツールに表示されます。
パッチルドンの巣穴では、3回日付を進めて「★3 オムスター 」のレイドが出るまで粘ります※ 。出なかったらセーブせずに リセットしてもう一度繰り返しこの手順を行ってください。自動化プログラム(ソースコードは後述) は、このリセットを含めて対応しています。
※妥協する場合は3V個体が出るレイド「★3 パッチルドン」「★3 プテラ 」でも可能です。ただし、ここで妥協すると、今後の作業でかなりのマシンスペックが必要となるのでPCスペックに余裕が無い場合はお控えください。また、成功率が下がるという報告もあります(筆者は未検証)。
「みんなで挑戦!」から日付変更を3度繰り返し、★3オムスター が出ればOK
おそらくここが一番の鬼門(究極の運ゲ)。沼にハマると時にはまともに色違い厳選したほうが楽なのでは?と思うほどの苦行です(決して乱数は「楽」ではない) 。
手順2-1-1で見つけたオムスター を捕まえます。その性格・個性・個体値 (わからなければLv100にしたステータスから計算)をツール入力、「個体値 チェック」ボタンを押してください。あまり出ませんが「 OK」が出たら、セーブせずにリセット して手順2-1-3 に進んでください。第1関門にして最大の鬼門をクリアです(ちなみに2Vレイドで「OK」が出る確率は1/3です。運が良ければすぐにクリアできます)。
「NG」が出てもセーブせずにリセット し、その後、改めて「みんなで挑戦」で日付を1日進めてからセーブ します。そして、手順2-1-1に戻ってください 。
オムスター を捕まえて性格や能力値をチェック。Lv100にするとわかりやすい
能力を入れて「個体値 チェック」。OKが出る確率は3割程度なので根気強くやろう
2-1-3.指示に従い、3日後の個体を探す @自動化可能
第1関門突破、おめでとうございます。喜び勇んでセーブしないよう 、くれぐれも注意してくださいね(リセットして同じ柱から続きをやります)。
続いて、同じく3日後の個体 を探します。ツールの「OK! Next ->」の後に「3V」「4V」「3V or 4V」など、次のターゲットの指示が記載されているので、それに従います。自動化プログラム(ソースコードは後述) をそのまま使えます。
例えば、今回の巣穴であればターゲットはそれぞれ
「Next -> 3V」なら、★3 パッチルドン、★3 プテラ
「Next -> 4V」なら、★3 パッチラゴン、★3 パッチルドン、★4 パッチラゴン
「Next -> 3V or 4V」なら、上記いずれも可能(3Vの方をおすすめ)
…となります。手順2-1-1と同様に、ターゲットを見つけて捕まえます。捕まえたら、個体値 をツールに入力して、セーブせずにリセット して次へ進んでください。
なお、Vの数が指定と異なる場合、計算ミスでなければ初期シード推定が不可能になる場合があります。セーブせずにリセットし、その後、改めて「みんなで挑戦」で日付を1日進めてからセーブしてから手順2-1-1に戻るか、続けるか選んでください。
指示に従って次のターゲットを決める。複数選べる場合はVが少ないほうがおすすめ
ターゲットを捕まえて個体値 を確認。Lv100にするとわかりやすい
個体値 を入力したら次へ。この時点でVの数が指定通りかを確認しておく
2-1-4.極力Vの少ない4日後の個体を探す @自動化可能
今までの手順と同様に、今度は 「4日後」 のポケモン を捕まえます。指定は特に無いので、好きなポケモン を選んでください。なお、Vの数が少ないほうがマシンスペックを食わずに済むので、もし心許ないPCを利用している方は極力Vが少ないものを選びましょう。また、精度の問題から、複数の初期シード候補が見つかることを防ぐためにも、Vの数は少ないほうがおすすめ※ です。
※Vの数は、自然発生「ではない」Vの数です。ゆえに、2Vのポケモン を捕まえて3 V以上でないことを確認するのが最も確実ですが、ミスを防ぐためにあえて5Vのポケモン を選び、6Vじゃ無いことを確認するのも有効です
捕まえたら手順2-1-3同様、個体値 をツールに入力してください。そして、入力が終わったら、セーブせずにリセット してください。自動化プログラム(ソースコードは後述) は、対応箇所を「3」から「4」に書き換えることで利用できます。
最後のステップでは「4日後」のポケモン を捕まえる。肝心なので間違えないように注意!
2-2.消費数の特定
ここまでお疲れさまでした。これで、3つの項目すべてが埋まったことだと思います。あとは、意気揚々と「検索開始」を押すだけです。計算時間がかなりかかります。マシンスペックにもよりますが、 「1つ見つけたら終了」にチェックを入れた状態なら、NVIDIA 製GPU グラボを積んだPCであれば10秒もかからずに検索可能です。普通に計算すると10分くらいかかるそうです。
なお、ここもマシンスペックとの相談ですが、運に自信がない人は右下の「1つ見つけたら終了」のチェックボックス は外しておいてください 。推定された初期シードが複数候補が見つかっていた場合に、それに気づけず、その後の作業がすべて無駄になってしまう恐れがあるからです。
「検索開始」を押す前に確認しておく。グラボ設定は該当者のみでOK
2-2-1.推定初期シードの検証(シード特定作業を兼ねる)
「計算開始」を押してからし ばらくすると、推定リスト(推定された初期Seedに基づいた消費数と個体値 ・色違いの有無)がテキストファイルで出てきます。この際、複数の初期シード(ツール上ではDen Seed)が候補になった場合、その旨を表すダイアログも出てきますので、見逃さないように注意しましょう。
このseeds.txtの行をまるまるコピーし、「1-StarSeedSearch」の「リスト出力」タブのDen Seedに入れてリスト出力すると、レイドの内容と推定されたSeed条件で、それぞれ出てくる能力の羅列が出てきます。なお、複数候補がでてきた場合、これらはツールに渡した情報(3日後・4日後のポケモン の個体値 や性格など)はすべて共通して満たしています。
ゆえに、複数の初期シード候補が出てきた場合は、6日目(5日後)以降でVの数が少ないレイドで比較検証することで、正しい初期シードを絞り込むことができます 。
推定された初期シードが複数見つかった場合、「seeds.txt」ができているので確認
候補ごとの結果と実際の結果で比較すれば正しいシードが特定できる
日付を(5回以上)回して オムスター が出ればラッキー。捕まえてリストと比較しよう
2-2-2 .色違いが何日先に出現するかを調べる
次に、「色違いのみ」にチェックを入れて、「リスト出力」を押してください。もし、結果が何も出てこなければ適宜「最大消費数」を増やして出力してください。消費数とは、要するに次の手順で進める必要のある日数のことです。
なお、手順2-2-1で必ず「初期シードが正しいこと」を確認した上で以降の手順を進めてください。この特定が曖昧のままだと、これからの作業はすべて水の泡になります。
「色違いのみ」にチェックを入れると、何日後に色違いレイドが出現するかが分かる
一応、今回の私の例で言うと、Seed=0x 3DC5C8246ECEC24C で、19046日後に星エフェクトの色違いレイドになることがわかります。
3.乱数消費パート
【色パッチルドン探しの手順】
1.準備 → 2.乱数調整 → 3.乱数消費 (イマココ) → 4. 捕獲 (3-1. ランクマバグ状態に移行 3-2. 乱数消費する)
3-1.ランクマバグ状態に移行
ここからは手順2-2-2で確認した「目標個体までの日数」を目指して、日付をひたすらすすめていきます。なお、目標までの消費数(日付を回す回数)が100日程度であれば、手動で変更することをおすすめします。
まず、効率よく日付を進めるために、ランクマッチやYY通信のカジュアルバトルで機内モード に変更した際に日付変更ペナルティが解除されるバグ(通称:ランクマバグ)を活用します。まずは、巣穴の前からポケモンセンター に移動してください 。
そして、ランクマバグ状態に下記手順で移行します。なお、この方法が使えない人は、素直にランクマッチで1戦してください(Nintendo Onlineへの加入が必要です)。
ポケモンセンター の中に入る
YY通信で「通信対戦」を行う(ローカル通信)
もう一台のSwitch・剣盾を使ってその通信対戦に応じる
戦闘が始まったらHomeボタン長押し→「機内モード 」をONに変更する
エラーが発生するのでそれを閉じて、「にげる」選択
ポケモンセンター に戻ってくる(移行完了)
この状態で、一度Home画面に戻り、日付を1日進めて、ゲーム画面に戻ってください。一瞬だけ画面全体がチラッと暗転していれば、正常にランクマバグ状態に移行できています。
ランクマバグ状態に入る前に、まずはブラッシータウンのポケセン に入ろう
YY通信でローカル対戦を募る。バトルが始まったらHomeボタン長押しで機内モード に
エラーが出たら「にげる」で対戦終了。この状態で時刻変更すると一瞬画面が暗転する
3-2.乱数消費する @自動化可能
手順3-1でランクマバグ状態になると、日付変更のペナルティが発生しなくなります。さらに「設定で日付を変更してゲーム画面に戻った瞬間」ではなく「日付を変更した瞬間」にゲーム中でも日付変更が反映されるようになります。つまり、設定画面の中で日付を変更し、「OK」を押すたびにゲーム中の日付も同じ回数だけ進んでいることになります。したがって、Home画面などを介する必要がなくなるため、日付変更が1日あたり約2秒という驚きの速さで実現可能になります(ソースコードは後述 )。
この状態で、手順2-2-2で確認した「目標個体までの日数」までひたすら進めていくのですが、実際に進めるのは「目標の日数-3日間」となることに注意してください 。原理は割愛しますが、例えば目標の日数が「19046日後」なら、この手順で消費するのは19046-3=「19043日」となります。
ゲーム画面に戻る必要はない。ひたすら日付を進めていこう
目安までに、自動化プログラム(ソースコードは後述 )で日付を1ヶ月進めるのに実測値で42秒かかりました。ざっくりアバウトで5000日分を2時間くらいで消費 できます。もしかしたら、消費上限数はこの値を参考に決めても良いかもしれません。
消費する日数と、実際にかかる時間(Arduino Leonardo用プログラム利用時)
消費する日数
自動化プログラムで かかる時間(推定)
備考
1日
約1.4秒
30日
42秒(実測値)
※31日分日付変更
100日
約140秒(2分20秒)
200日
約280秒(4分40秒)
この辺から手動だとツライ
300日
約420秒(7分)
365日
約511秒(8分31秒)
720日
約1022秒(約17分)
経験上、手動の限界
1000日
約1400秒(23分20秒)
2000日
約2800秒(46分40秒)
2500日
約3500秒(58分20秒)
約1時間
5000日
約7000秒(116分40秒)
約2時間
10000日
約14000秒(3時間54分)
約4時間
15000日
約21000秒(350分)
約6時間
20000日
約28000秒(700分)
約8時間
4.捕獲パート
【色パッチルドン探しの手順】
1.準備 → 2.乱数調整 → 3.乱数消費 → 4.捕獲(イマココ) (4-1. 残りの消費数確認 4-2. 3日後のパッチルドン探し 4-3. 捕獲!)
4-1.残りの消費数を確かめる
目的消費数の概ね10日くらい前まで消費が終わったら、まずは巣穴の前に戻り、セーブします (無論、最初から自信があれば目的消費数の3日前でも問題ありません)。
そして、巣穴に出ているポケモン を捕まえます。捕まえたら、個体値 を計算してください。レイドの情報をもとに乱数調整ツールでリストを出力し、その個体値 と性格の組み合わせがどこにいるかを確認してください。これが、「目的の消費数-3」に重なれば準備完了です。なお、現在位置を調べるためにポケモン を捕まえたら、必ずセーブせずにリセットしてください 。
現在位置が、「目的消費数-3」に届いていない場合は、巣穴の「みんなで挑戦」から日付を1日ずつ進めてください。ちょうど「目的消費数-3」の位置にいる場合はセーブして次の手順に 進んでください。
巣穴に戻って出ているポケモン を捕まえる。レイド★の数確認も忘れずに
捕まえたら個体値 チェックだ。性格・能力値・特性・性別なども忘れずチェック
リスト出力し、現在の個体がどのくらい離れているかを確認しよう
現在位置が「目的の消費数-3」になるまでズレを計算して進めていこう
4-2.3日後のパッチルドンを探そう!
ここまで長らくお疲れさまでした。あとは、パッチルドンを探すだけです。
感の良い方・ここまで読んでくれた方はお気づきかと思いますが、巣穴のレイドバトルは2日後まで出現するポケモン が決定しており、3日後以降はランダムになっています。ゆえに、現在位置が「目的消費数-3」のタイミングでセーブしたわけです。
では、3回日付を進めて「★3 パッチルドン」「★4 パッチルドン」「★5 パッチルドン」のレイドが出るまで粘りましょう。出なかったらセーブせずに リセットしてもう一度この手順を行ってください。出たら、セーブして次の手順に進みます。
この流れは、手順2-1-1と完全に同様ですね。一応、2-1-1で使った自動化プログラム(ソースコードは後述) でも同じことができるのですが、最後くらいは自力でやったほうが、喜びがひとしおだと思います。
3日進めてパッチルドンが来たら終了だ。忘れずにセーブしておこう
ちなみに、パッチルドンが出たらセーブするのが本来の流れなのですが、代わりに「キャンプ」を開くのも有効です。万が一、日付を多く進めてしまった場合の保険になります(キャンプであればセーブしないためリセットでやり直しができます)。ここでは詳細は割愛しますが、興味のある方は「キャンプバックアップ」で調べてみてください。Switchと剣盾を2組持っている場合には、ひたすらサブロム側で色違い手に入れ続けることもできます。
4-3.パッチルドンの捕獲
本当にここまでお疲れさまでした。あとは、お好きなボールを使ってパッチルドンを捕まえるだけです。
パッチルドンはキョダイマ ックス個体が無いので、「一人で挑戦」の場合にはどのボールを投げても捕獲率は100%になるはずですが、本当に捕まるか心配な人や「みんなで挑戦」で色違いレイドを配布する場合には、挑戦前に必ずセーブをしておきましょう。
待ちに待った色パッチルドン。好きなボールを投げよう!
色パッチルドンは全体的にグレーの色合い。レイドで大きくなってもかわいい
読み飛ばしてここまで来た方に向けて一応説明をしておくと、今回は2つのソースコード を作成しています。それぞれ使い方も合わせて載せますのでご参考ください。
1つ目→「3日後の巣穴厳選 」 2つ目→「高速乱数消費 」
このプログラムは、「リセット」⇒「ゲーム起動」⇒「巣穴から『みんなで挑戦』を押して日付進める」をTIME_WARP _DAYS回繰り返す ⇒「TIME_WARP _DAYS日分日付を戻す」という一連の流れを自動化してくれます。基本的に厳選1回目・2回目は「3」、3回目は「4」になる かと思います。適宜数字を調整して活用ください。
#define TIME_WARP_DAYS ( 3 )
なお、現在の日時から起算してTIME_WARP _DAYS日進めて月をまたぐ場合には日付がズレてしまいます (例えば、2月27日や12月30日などから3日進めたら月をまたぐためNG)。現在の日時を調整するか、この値を+1するなどで対応してください。
使い方のイメージとしては、
プログラムをArduino に書き込む
「ねがいのかたまり」を入れて柱を建てる
セーブする
Arduino を差し込む
動作が止まるまで放置
目的のレイドか確認。違った場合はArduino を挿し直す(4に戻る)
となります。挿し直すだけで、リセット含めて3日後のレイドの内容確認まで放置ができるので、繰り返しの際には重宝します。
自動で日付が進み、募集画面で待機してくれる。目的のレイドでなかったら挿し直そう
もし、このリセットが冗長だと感じる場合には、PROTO_AUTO_GAME_QUITをfalseにしてください。その場合は「みんなで挑戦」の手前でArduino を挿してください。
ではプログラムのソースコード です。
2020/12/5追記:NintendoSwitch Ver.11.0アップデート対応済(変更点はこちら )
2021/9/20追記:NintendoSwitch Ver.13.0アップデート対応済(詳細はこちら )
2022/10/23追記:NintendoSwitch Ver.15.0アップデート対応済 ※Switch Liteをご利用の方は「#define SWITCH_VER (15) 」を「#define SWITCH_VER (12) 」に書き換えてご利用ください。
#include <SwitchControlLibrary.h>
#define HOLDTIME ( 95 )
#define INTERVAL ( 105 )
#define TIME_WARP_DAYS ( 3 )
#define FIRST_DAY_WATT_EARNING ( false )
#define PROTO_AUTO_GAME_QUIT ( true )
#define SWITCH_VER ( 15 )
int current_days;
void PushHome (int delay_time_ms);
void PushA (int delay_time_ms);
void PushB (int delay_time_ms);
void PushX (int delay_time_ms);
void PushR (int delay_time_ms);
void PushL (int delay_time_ms);
void PushRL (int delay_time_ms);
void move_for (char * Direction);
void move_for (char * Direction, int delay_time_ms);
void move_for (char * Direction, int hold_time_ms, int delay_time_ms);
void setup () {
PushRL (300 );
PushRL (300 );
PushRL (300 );
PushRL (300 );
PushRL (300 );
delay (1000 );
if (PROTO_AUTO_GAME_QUIT){
PushHome (1000 );
PushX (500 );
PushA (3000 );
PushA (1000 );
PushA (18500 );
PushA (10000 );
}
current_days = 0 ;
if (FIRST_DAY_WATT_EARNING){
PushA (500 );
PushB (500 );
}
}
void loop () {
PushA (1500 );
if (current_days >= TIME_WARP_DAYS ){
PushA (4000 );
PushHome (1000 );
move_for ("down" );move_for ("right" );move_for ("right" );move_for ("right" );move_for ("right" );move_for ("right" );
PushA (1500 );
move_for ("down" , 1500 , (int )INTERVAL/4 );move_for ("right" );
#if (SWITCH_VER >= 15 )
move_for ("down" , (int )750 , (int )INTERVAL);
#elif (SWITCH_VER >= 13 )
move_for ("down" , (int )780 , (int )INTERVAL/2 );
#else
for (int i=0 ; i<4 ; i++){
move_for ("down" , (int )HOLDTIME/2 , (int )INTERVAL/2 );
}
#endif
PushA (500 );
move_for ("down" );
move_for ("down" );
PushA (500 );
move_for ("right" );
move_for ("right" );
for (int i=0 ;i<TIME_WARP_DAYS;i++) move_for ("down" );
PushA (INTERVAL);
PushA (INTERVAL);
PushA (INTERVAL);
PushA (INTERVAL);
PushHome (2000 );
PushA (1000 );
PushB (500 );
PushA (1000 );
PushA (4500 );
PushA (4000 );
for (;;)delay (1000 );
}
PushA (4000 );
PushHome (1000 );
move_for ("down" );
move_for ("right" );
move_for ("right" );
move_for ("right" );
move_for ("right" );
move_for ("right" );
PushA (1500 );
move_for ("down" , 1500 , (int )INTERVAL/4 );
move_for ("right" );
#if (SWITCH_VER >= 15 )
move_for ("down" , (int )750 , (int )INTERVAL);
#elif (SWITCH_VER >= 13 )
move_for ("down" , (int )780 , (int )INTERVAL/2 );
#else
for (int i=0 ; i<4 ; i++){
move_for ("down" , (int )HOLDTIME/2 , (int )INTERVAL/2 );
}
#endif
PushA (500 );
move_for ("down" );
move_for ("down" );
PushA (500 );
move_for ("right" );
move_for ("right" );
move_for ("up" );
PushA (INTERVAL);
PushA (INTERVAL);
PushA (INTERVAL);
PushA (INTERVAL);
PushHome (2000 );
PushA (1000 );
PushB (750 );
PushA (1000 );
PushA (4500 );
PushA (500 );
PushB (1500 );
current_days++;
}
void PushHome (int delay_time_ms){
SwitchControlLibrary ().PressButtonHome ();
delay (210 );
SwitchControlLibrary ().ReleaseButtonHome ();
delay (delay_time_ms);
return ;
}
void PushA (int delay_time_ms){
SwitchControlLibrary ().PressButtonA ();
delay (HOLDTIME);
SwitchControlLibrary ().ReleaseButtonA ();
delay (delay_time_ms);
return ;
}
void PushB (int delay_time_ms){
SwitchControlLibrary ().PressButtonB ();
delay (HOLDTIME);
SwitchControlLibrary ().ReleaseButtonB ();
delay (delay_time_ms);
return ;
}
void PushX (int delay_time_ms){
SwitchControlLibrary ().PressButtonX ();
delay (HOLDTIME);
SwitchControlLibrary ().ReleaseButtonX ();
delay (delay_time_ms);
return ;
}
void PushR (int delay_time_ms){
SwitchControlLibrary ().PressButtonR ();
delay (HOLDTIME);
SwitchControlLibrary ().ReleaseButtonR ();
delay (delay_time_ms);
return ;
}
void PushL (int delay_time_ms){
SwitchControlLibrary ().PressButtonL ();
delay (HOLDTIME);
SwitchControlLibrary ().ReleaseButtonL ();
delay (delay_time_ms);
return ;
}
void PushRL (int delay_time_ms){
SwitchControlLibrary ().PressButtonR ();
SwitchControlLibrary ().PressButtonL ();
delay (HOLDTIME);
SwitchControlLibrary ().ReleaseButtonR ();
SwitchControlLibrary ().ReleaseButtonL ();
delay (delay_time_ms);
return ;
}
void move_for (char * Direction){
switch (Direction[0 ]){
case 'r' :
case 'R' :
SwitchControlLibrary ().MoveHat (2 );
delay (HOLDTIME);
SwitchControlLibrary ().MoveHat (8 );
delay (INTERVAL);
break ;
case 'l' :
case 'L' :
SwitchControlLibrary ().MoveHat (6 );
delay (HOLDTIME);
SwitchControlLibrary ().MoveHat (8 );
delay (INTERVAL);
break ;
case 'u' :
case 'U' :
SwitchControlLibrary ().MoveHat (0 );
delay (HOLDTIME);
SwitchControlLibrary ().MoveHat (8 );
delay (INTERVAL);
break ;
case 'd' :
case 'D' :
SwitchControlLibrary ().MoveHat (4 );
delay (HOLDTIME);
SwitchControlLibrary ().MoveHat (8 );
delay (INTERVAL);
break ;
default :
break ;
}
}
void move_for (char * Direction, int delay_time){
switch (Direction[0 ]){
case 'r' :
case 'R' :
SwitchControlLibrary ().MoveHat (2 );
delay (HOLDTIME);
SwitchControlLibrary ().MoveHat (8 );
delay (delay_time);
break ;
case 'l' :
case 'L' :
SwitchControlLibrary ().MoveHat (6 );
delay (HOLDTIME);
SwitchControlLibrary ().MoveHat (8 );
delay (delay_time);
break ;
case 'u' :
case 'U' :
SwitchControlLibrary ().MoveHat (0 );
delay (HOLDTIME);
SwitchControlLibrary ().MoveHat (8 );
delay (delay_time);
break ;
case 'd' :
case 'D' :
SwitchControlLibrary ().MoveHat (4 );
delay (HOLDTIME);
SwitchControlLibrary ().MoveHat (8 );
delay (delay_time);
break ;
default :
break ;
}
}
void move_for (char * Direction, int hold_time_ms, int delay_time_ms){
switch (Direction[0 ]){
case 'r' :
case 'R' :
SwitchControlLibrary ().MoveHat (2 );
delay (hold_time_ms);
SwitchControlLibrary ().MoveHat (8 );
delay (delay_time_ms);
break ;
case 'l' :
case 'L' :
SwitchControlLibrary ().MoveHat (6 );
delay (hold_time_ms);
SwitchControlLibrary ().MoveHat (8 );
delay (delay_time_ms);
break ;
case 'u' :
case 'U' :
SwitchControlLibrary ().MoveHat (0 );
delay (hold_time_ms);
SwitchControlLibrary ().MoveHat (8 );
delay (delay_time_ms);
break ;
case 'd' :
case 'D' :
SwitchControlLibrary ().MoveHat (4 );
delay (hold_time_ms);
SwitchControlLibrary ().MoveHat (8 );
delay (delay_time_ms);
break ;
default :
break ;
}
}
このプログラムは、ランクマバグ状態で日付を自動で進めるプログラムです。あらかじめSHOHISUを「(目的消費数-3)」に書き換え てから使ってください。
プログラムを横着したので、31日まである月(1月・3月・5月・7月・8月・10月・12月)で使ってください 。また、消費数を31で割って月繰り上がり(31日→1日)のズレ吸収を行っている単純なプログラムなので、もしかしたら消費数がズレているかもしれません。なので、実際は、「目的消費数-10」くらいで設定しておき、あとは手動で検証しながら進めることをおすすめします。
#define SHOHISU ( 19046 - 3 )
2021/1/26追記: このSHOHISUの上限は「32767」となります。もし、32768以上の乱数消費が必要な場合、2回に分けて自動化をするなどで工夫してください。
使い方としては、
プログラムを書き換え、Arduino に書き込んでおく
ポケモンセンター に入る
ランクマバグ状態にする
Homeボタンを押し、設定→本体→日付と時刻→現在の日付と時刻から、何も変更せずに「OK」を押しておく【重要】
Arduino を差し込んで放置
になります。注意としては、上記4にも書いている通り、一度日付変更画面に入り、OKを押しておいてください(カーソルの位置が変わるからです)。もし、この4の手順すら面倒だと感じる方はFIRST_TIMEを(true)にしてください。
時刻設定で「OK」を押しておくと、カーソルが「OK」から始まるので高速に消費ができる
特に難しいところも無いと思います。
プログラムのソースコード です。
2020/12/5追記:こちらはNintendoSwitch Ver.11.0アップデートの影響はありません 2021/9/20追記:こちらはNintendoSwitch Ver.13.0アップデートの影響はありません
#include <SwitchControlLibrary.h>
#define HOLDTIME ( 40 )
#define INTERVAL ( 105 )
#define FIRST_TIME ( false )
#define SHOHISU ( 19046 - 3 )
int maxlooptime;
int currentlooptime;
void PushHome(int delay_time_ms);
void PushA(int delay_time_ms);
void PushB(int delay_time_ms);
void PushR(int delay_time_ms);
void PushL(int delay_time_ms);
void move_for(char * Direction);
void move_for(char * Direction, int delay_time_ms);
void move_for(char * Direction, int hold_time_ms, int delay_time_ms);
void Debug(void );
void setup() {
if (FIRST_TIME){
PushR(100 );
PushL(100 );
PushR(100 );
PushL(100 );
PushR(100 );
PushL(100 );
delay(10000 );
}else {
PushR(100 );
PushL(100 );
PushR(100 );
PushL(100 );
PushR(100 );
PushL(100 );
PushR(100 );
PushL(100 );
delay(3000 );
}
currentlooptime = 0 ;
maxlooptime = (int )( (double )SHOHISU + (double )SHOHISU/31.0 );
if (FIRST_TIME){
PushA(3000 );
PushA(250 );
PushA(250 );
move_for("up" );
PushA(250 );
PushA(250 );
PushA(250 );
PushA(250 );
currentlooptime++;
}
delay(1000 );
}
void loop() {
if (currentlooptime >= maxlooptime ){
PushHome(1000 );
for (;;)delay(1000 );
}
PushA(INTERVAL);
delay(20 );
move_for("left" );
move_for("left" );
move_for("left" );
move_for("up" );
PushA(INTERVAL);
PushA(INTERVAL);
PushA(INTERVAL);
PushA(INTERVAL);
currentlooptime++;
delay(20 );
}
void PushHome(int delay_time_ms){
SwitchControlLibrary().PressButtonHome();
delay(210 );
SwitchControlLibrary().ReleaseButtonHome();
delay(delay_time_ms);
return ;
}
void PushA(int delay_time_ms){
SwitchControlLibrary().PressButtonA();
delay(HOLDTIME);
SwitchControlLibrary().ReleaseButtonA();
delay(delay_time_ms);
return ;
}
void PushB(int delay_time_ms){
SwitchControlLibrary().PressButtonB();
delay(HOLDTIME);
SwitchControlLibrary().ReleaseButtonB();
delay(delay_time_ms);
return ;
}
void PushR(int delay_time_ms){
SwitchControlLibrary().PressButtonR();
delay(HOLDTIME);
SwitchControlLibrary().ReleaseButtonR();
delay(delay_time_ms);
return ;
}
void PushL(int delay_time_ms){
SwitchControlLibrary().PressButtonL();
delay(HOLDTIME);
SwitchControlLibrary().ReleaseButtonL();
delay(delay_time_ms);
return ;
}void move_for(char * Direction){
switch (Direction[0 ]){
case 'r' :
case 'R' :
SwitchControlLibrary().MoveHat(2 );
delay(HOLDTIME);
SwitchControlLibrary().MoveHat(8 );
delay(INTERVAL);
break ;
case 'l' :
case 'L' :
SwitchControlLibrary().MoveHat(6 );
delay(HOLDTIME);
SwitchControlLibrary().MoveHat(8 );
delay(INTERVAL);
break ;
case 'u' :
case 'U' :
SwitchControlLibrary().MoveHat(0 );
delay(HOLDTIME);
SwitchControlLibrary().MoveHat(8 );
delay(INTERVAL);
break ;
case 'd' :
case 'D' :
SwitchControlLibrary().MoveHat(4 );
delay(HOLDTIME);
SwitchControlLibrary().MoveHat(8 );
delay(INTERVAL);
break ;
default :
break ;
}
}
void move_for(char * Direction, int delay_time){
switch (Direction[0 ]){
case 'r' :
case 'R' :
SwitchControlLibrary().MoveHat(2 );
delay(HOLDTIME);
SwitchControlLibrary().MoveHat(8 );
delay(delay_time);
break ;
case 'l' :
case 'L' :
SwitchControlLibrary().MoveHat(6 );
delay(HOLDTIME);
SwitchControlLibrary().MoveHat(8 );
delay(delay_time);
break ;
case 'u' :
case 'U' :
SwitchControlLibrary().MoveHat(0 );
delay(HOLDTIME);
SwitchControlLibrary().MoveHat(8 );
delay(delay_time);
break ;
case 'd' :
case 'D' :
SwitchControlLibrary().MoveHat(4 );
delay(HOLDTIME);
SwitchControlLibrary().MoveHat(8 );
delay(delay_time);
break ;
default :
break ;
}
}
void move_for(char * Direction, int hold_time_ms, int delay_time_ms){
switch (Direction[0 ]){
case 'r' :
case 'R' :
SwitchControlLibrary().MoveHat(2 );
delay(hold_time_ms);
SwitchControlLibrary().MoveHat(8 );
delay(delay_time_ms);
break ;
case 'l' :
case 'L' :
SwitchControlLibrary().MoveHat(6 );
delay(hold_time_ms);
SwitchControlLibrary().MoveHat(8 );
delay(delay_time_ms);
break ;
case 'u' :
case 'U' :
SwitchControlLibrary().MoveHat(0 );
delay(hold_time_ms);
SwitchControlLibrary().MoveHat(8 );
delay(delay_time_ms);
break ;
case 'd' :
case 'D' :
SwitchControlLibrary().MoveHat(4 );
delay(hold_time_ms);
SwitchControlLibrary().MoveHat(8 );
delay(delay_time_ms);
break ;
default :
break ;
}
}
void Debug(){
PushHome(1000 );
PushHome(1000 );
return ;
}
あとがき
今回は、乱数調整をベースにArduino を活用して、色パッチルドンを見つける記事を書きました。前回の記事 では、パッチルドンをウカッツから自動で受け取って色違いを厳選する方法を紹介しましたが、やっぱりレイド産はボール厳選ができる ことが何よりも強みですね。
ただし、モンスターボール 以外で捕まえると自ずとレイド産とバレてしまうという点は注意が必要です。レイド産のパッチルドンは必ず夢特性 になるので「ゆきかき」で意表を突くことが難しくなり、「ちくでん」ではないことを自ら告白することになります。
とはいえ、タマゴ未発見のオシャボ入りというだけでその価値は天井知らずですから、そんなのは些細な問題に過ぎないかもしれませんね。私も今回、サファリボールで捕まえましたし。
ところで、乱数を今まで知らなかった人にとっては、かなり「大変」だと思ったのではないでしょうか。また、乱数を知っている人も、文章にするとかなり長くなると感じたのではないでしょうか。どちらが楽かという議論ではなく、乱数調整は厳選と同じく手間暇がかかる作業です。その点、Arduino であれば、乱数・厳選を問わず簡略化や効率化ができるという点あるいは可能性にも気づいていただけたのではないかと思います。
これを読んでArduino のユーザーが増えたり、コミュニティが活性になったりを期待しています。また、プログラミングや組み込み系への興味、はたまたゲームへの興味などが増えるとより嬉しいですね。
パッチルドンかわいい(余談)
さて。突然ですが、こちらを御覧ください。
パッチルドンは歩くのが苦手なのだ
キャンプではよちよち歩いてくる。戦闘では可憐に登場するぞ
執筆中ずっと思ってたんですけど、パッチルドンって本当にかわいらしいですよね 。
いや、コイツめちゃくちゃかわいくないですか??
何がって、たぶんチャームポイントは鼻水だと思うんですよ。上のgif画像でも分かると思いますが、念の為0.5倍速と0.16倍速を準備しましたので、下記にて御覧ください(あと、捕まえたボール「サファリボール」のエフェクトもご確認ください)。
はなみずに着目!かわいいぞ!!(左:0.5倍速/右:0.16倍速)
いやぁ。良いんじゃないでしょうか…。
てなわけで今回はこのへんで。
ではではc⌒っ.ω.)っ
補足記事(Arduino の使い方・使うタイミングについての詳しい解説はこちら):
【Arduino自動化05ex】乱数調整レイドでのArduino Leonardoの使い方
前記事:
【Arduino自動化04】パッチルドン自動受け取り(中国語・英語対応)
次記事:
【Arduino自動化06】完全放置「マックスこうせき」集め【ダイマックスアドベンチャー】
導入記事:
【Arduino自動化01】Arduino開発環境の導入