【マイコン】ポケモン剣盾のボックスに眠っているタマゴを孵化していくコード!

ポケモン剣盾のボックスに、眠ったままになっているタマゴはありませんか?

タマゴは孵化しないと逃せないので邪魔ですよね… しかし、自動化に慣れてしまうと孵化しそこねたタマゴを割っていくのもめんどうなものです。

そんな悩みを解決するべく、ボックスのタマゴを片っ端から孵化していくコードを作成しました!

この記事をご覧になる前に

マイコンをまだ導入していない方は、以下の記事を参考に導入してみてください。このブログでは、Arduino Leonardoというマイコンを使っているため、異なる種類のものではうまく動かない可能性があります。

関連記事

マイコンと呼ばれるものをご存知でしょうか? Switchに接続するだけで様々な作業を "自動" で行ってくれるというものです。 導入すれば作業が楽になるだけでなく、寝てる間に色々稼ぐこともできちゃう便利なアイテムなわけですね! […]

マイコンを使って
ポケモン剣盾
自動化しよう!
【導入編】

※2021年2月11日追記:当ブログで使用するライブラリが「NintendoSwitchControlLibrary」へと変わりました。旧ライブラリのコードも残しておきますが、基本的には新しいライブラリをダウンロードして新しいコードを使ってください。

ダウンロードして解凍したら、『Arduino』フォルダの中にある『libraries』フォルダの中にコピーすればOKです。(展開を終えたら展開元のzipファイルは削除してしまって構いません。)

コード利用における注意点!

今回のコードはボックスに空きの列(縦)があると、そこでループが止まってしまいます。

誤ってポケモンを逃してしまったり、不用意にレポートを書いてしまうような致命的な不具合はありませんが、快適に利用するためにはコードを使用する前にある程度タマゴを固めておくのが望ましいでしょう。

タマゴ、もしくは、ポケモンが各列に1匹でも存在していれば問題なく動作するようになっています。

ソースコード

実際に書いたコードはこちらになります。

旧ライブラリ(NintendoSwitchControll)を使用している方はこちらをクリック
/**
* 育て屋から卵を回収→孵化→ボックスに預けるを繰り返すスケッチ
* ボックスに空きがある限り、ポケモンを孵化し続ける
*
* 初期条件は以下の通り
* 1.ハシノマはらっぱにいること
* 2.自転車に乗っていること
* 3.手持ちが1体のみのこと
* 4.Xボタンを押したときに「タウンマップ」が左上、「ポケモン」がその右にあること
* 5.ボックスが空のこと
* 6.オフライン状態であること
* 7.無線のコントローラーが接続されていないこと
* 8.「設定」から「話の速さ」を「速い」に、「手持ち/ボックス」を「自動で送る」に、「ニックネーム登録」を「しない」にしておくこと
*/

// ライブラリを読み込むためのコード
#include <auto_command_util.h>

// 孵化サイクル20のポケモンが、孵化するまでにかかる最大時間
const int TIME_TO_HATCHING_SEC = 69;

// 空飛ぶタクシーでハシノマはらっぱに移動する関数
void moveToInitialPlayerPosition(){
    pushButton(Button::A, 2000);
    pushButton(Button::A, 450, 2);
    delay(2200); // 天候によって読み込み時間がやや異なる(最も重かった砂嵐でも1900で安定していたが、柱の本数や服装などの環境による差異がある可能性も考慮して少し余裕を持たせた)
}

// 初期位置(ハシノマはらっぱ)からぐるぐる走り回る関数
void runAround() {
    for(int egg_num=0; egg_num<6; egg_num++){
        tiltJoystick(100, 0, 0, 0, 500);
        // delayの秒数がintの最大値を越えないように30秒ごとに実行する
        for(int i=0; i<TIME_TO_HATCHING_SEC/30; i++){
            tiltJoystick(100, 100, -100, -100, 30000);
        }
        tiltJoystick(100, 100, -100, -100, (TIME_TO_HATCHING_SEC%30)*1000);
        waitEggHatching();
        pushButton(Button::X, 500);
        moveToInitialPlayerPosition();
    }
}

// ボックスを開く関数
void openBox() {
    pushButton(Button::X, 500);
    pushHatButton(Hat::RIGHT, 25);
    pushButton(Button::A, 1250);
    pushButton(Button::R, 1500);
}

// ボックスを閉じる関数
void closeBox() {
    pushButton(Button::B, 25); // ボックスが空でなかった場合でも、ボックスを閉じてループを実行し続けさせるのに必要な記述
    pushButton(Button::B, 1500);
    pushButton(Button::B, 1250);
    pushHatButton(Hat::LEFT, 25);
}

// タマゴが孵化するのを待つ関数
void waitEggHatching() {
    pushButton(Button::B, 450, 38); // 余裕があるように思えるが、色違いのエフェクトを考慮するとこれ以上は厳しい
}

// タマゴをボックスから引き取る関数
void adoptedEggs(int box_line) {
    // 孵化させるタマゴを範囲選択
    pushButton(Button::A, 25);
    pushHatButton(Hat::DOWN, 50, 4);
    pushButton(Button::A, 25);
    // 手持ちに加える
    pushHatButton(Hat::LEFT, 100, box_line+1);
    pushHatButton(Hat::DOWN, 25);
    pushButton(Button::A, 25);
}

// タマゴを孵化→ボックスのタマゴと入れ替えを繰り返す関数
void withdrawEggs(int box_line) {
    // 空飛ぶタクシーでハシノマはらっぱに移動する
    moveToInitialPlayerPosition();
    // 手持ちのタマゴを全て孵化させる
    runAround();
    // ボックスを開く
    openBox();
    // 手持ちの孵化したポケモンを範囲選択
    pushHatButton(Hat::LEFT, 25);
    pushHatButton(Hat::DOWN, 25);
    pushButton(Button::Y, 25);
    pushButton(Button::Y, 25);
    pushButton(Button::A, 25);
    pushHatButton(Hat::DOWN, 50, 4);
    pushButton(Button::A, 25);
    // ボックスに預ける
    pushHatButton(Hat::RIGHT, 100, box_line);
    pushHatButton(Hat::UP, 25);
    pushButton(Button::A, 25);
    // ボックスがいっぱいになったら、次のボックスに移動させる
    if(box_line==6){
        pushHatButton(Hat::UP, 25);
        pushHatButton(Hat::RIGHT, 25);
        // 新しいボックスの1列目のタマゴを引き取る
        pushHatButton(Hat::DOWN, 25);
        pushHatButton(Hat::RIGHT, 100, 2);
        adoptedEggs(0);
    } else {
        // タマゴをボックスから引き取る
        pushHatButton(Hat::RIGHT, 25);
        adoptedEggs(box_line);
    }
    // ボックスを閉じる
    closeBox();
}

// マイコンのセット時に1度だけ行われる処理
void setup(){
    // Switchがマイコンを認識するまでは信号を受け付けないため、適当な処理をさせておく
    pushButton(Button::B, 500, 5);

    // マイコンを認識したら、メニューの左上にカーソルを持っていく
    pushButton(Button::X, 600);
    pushHatButtonContinuous(Hat::LEFT_UP, 750);

    // ボックスを開く
    pushHatButton(Hat::RIGHT, 25);
    pushButton(Button::A, 1250);
    pushButton(Button::R, 1500);

    // 孵化させるタマゴを手持ちに加える
    pushButton(Button::Y, 25);
    pushButton(Button::Y, 25);
    adoptedEggs(0);

    // ボックスを閉じる
    closeBox();
}

// ここに記述した内容がループされ続ける
void loop(){
    for(int box_line=1; box_line<7; box_line++) {
        withdrawEggs(box_line);
    }
}
/**
 * ボックスに眠っているタマゴを順に孵化していくスケッチ
 *
 * 初期条件は以下の通り
 * 1.ハシノマはらっぱにいること
 * 2.自転車に乗っていること
 * 3.手持ちが1体のみのこと
 * 4.Xボタンを押したときに「タウンマップ」が左上、「ポケモン」がその右にあること
 * 5.ボックスが空のこと
 * 6.オフライン状態であること
 * 7.無線のコントローラーが接続されていないこと
 * 8.「設定」から「話の速さ」を「速い」に、「手持ち/ボックス」を「自動で送る」に、「ニックネーム登録」を「しない」にしておくこと
 * 9.ちょいらくモードが「しない」であること
 * 10.まるいおまもりを所持していること
 */

// ライブラリを読み込むためのコード
#include <NintendoSwitchControlLibrary.h>

// 孵化サイクル20のポケモンが、孵化するまでにかかる最大時間
const int TIME_TO_HATCHING_SEC = 69;

// 空飛ぶタクシーでハシノマはらっぱに移動する関数
void moveToInitialPlayerPosition() {
    pushButton(Button::A, 2000);
    pushButton(Button::A, 450, 2);
    delay(2200);  // 天候によって読み込み時間がやや異なる(最も重かった砂嵐でも1900で安定していたが、柱の本数や服装などの環境による差異がある可能性も考慮して少し余裕を持たせた)
}

// 初期位置(ハシノマはらっぱ)からぐるぐる走り回る関数
void runAround() {
    for (int egg_num = 0; egg_num < 6; egg_num++) {
        tiltLeftStick(Stick::MAX, Stick::NEUTRAL, 500);
        // delayの秒数がintの最大値を越えないように30秒ごとに実行する
        for (int i = 0; i < TIME_TO_HATCHING_SEC / 30; i++) {
            tiltLeftAndRightStick(Stick::MAX, Stick::MAX, Stick::MIN, Stick::MIN, 30000);
        }
        tiltLeftAndRightStick(Stick::MAX, Stick::MAX, Stick::MIN, Stick::MIN, (TIME_TO_HATCHING_SEC % 30) * 1000);
        waitEggHatching();
        pushButton(Button::X, 500);
        moveToInitialPlayerPosition();
    }
}

// ボックスを開く関数
void openBox() {
    pushButton(Button::X, 500);
    pushHat(Hat::RIGHT, 25);
    pushButton(Button::A, 1250);
    pushButton(Button::R, 1500);
}

// ボックスを閉じる関数
void closeBox() {
    pushButton(Button::B, 25);  // ボックスが空でなかった場合でも、ボックスを閉じてループを実行し続けさせるのに必要な記述
    pushButton(Button::B, 1500);
    pushButton(Button::B, 1250);
    pushHat(Hat::LEFT, 25);
}

// タマゴが孵化するのを待つ関数
void waitEggHatching() {
    pushButton(Button::B, 450, 38);  // 余裕があるように思えるが、色違いのエフェクトを考慮するとこれ以上は厳しい
}

// タマゴをボックスから引き取る関数
void adoptedEggs(int box_line) {
    // 孵化させるタマゴを範囲選択
    pushButton(Button::A, 25);
    pushHat(Hat::DOWN, 50, 4);
    pushButton(Button::A, 25);
    // 手持ちに加える
    pushHat(Hat::LEFT, 100, box_line + 1);
    pushHat(Hat::DOWN, 25);
    pushButton(Button::A, 25);
}

// タマゴを孵化→ボックスのタマゴと入れ替えを繰り返す関数
void withdrawEggs(int box_line) {
    // 空飛ぶタクシーでハシノマはらっぱに移動する
    moveToInitialPlayerPosition();
    // 手持ちのタマゴを全て孵化させる
    runAround();
    // ボックスを開く
    openBox();
    // 手持ちの孵化したポケモンを範囲選択
    pushHat(Hat::LEFT, 25);
    pushHat(Hat::DOWN, 25);
    pushButton(Button::Y, 25);
    pushButton(Button::Y, 25);
    pushButton(Button::A, 25);
    pushHat(Hat::DOWN, 50, 4);
    pushButton(Button::A, 25);
    // ボックスに預ける
    pushHat(Hat::RIGHT, 100, box_line);
    pushHat(Hat::UP, 25);
    pushButton(Button::A, 25);
    // ボックスがいっぱいになったら、次のボックスに移動させる
    if (box_line == 6) {
        pushHat(Hat::UP, 25);
        pushHat(Hat::RIGHT, 25);
        // 新しいボックスの1列目のタマゴを引き取る
        pushHat(Hat::DOWN, 25);
        pushHat(Hat::RIGHT, 100, 2);
        adoptedEggs(0);
    } else {
        // タマゴをボックスから引き取る
        pushHat(Hat::RIGHT, 25);
        adoptedEggs(box_line);
    }
    // ボックスを閉じる
    closeBox();
}

// マイコンのセット時に1度だけ行われる処理
void setup() {
    // Switchがマイコンを認識するまでは信号を受け付けないため、適当な処理をさせておく
    pushButton(Button::B, 500, 5);

    // マイコンを認識したら、メニューの左上にカーソルを持っていく
    pushButton(Button::X, 600);
    holdHat(Hat::UP_LEFT, 750);

    // ボックスを開く
    pushHat(Hat::RIGHT, 25);
    pushButton(Button::A, 1250);
    pushButton(Button::R, 1500);

    // 孵化させるタマゴを手持ちに加える
    pushButton(Button::Y, 25);
    pushButton(Button::Y, 25);
    adoptedEggs(0);

    // ボックスを閉じる
    closeBox();
}

// ここに記述した内容がループされ続ける
void loop() {
    for (int box_line = 1; box_line < 7; box_line++) {
        withdrawEggs(box_line);
    }
}

設定の確認

マイコンを繋げる前に、以下の状態になっていることを確認してください。

2022年5月12日追記:必要な設定を一部追加しました。

  1. ハシノマはらっぱにいること
  2. 自転車に乗っていること
  3. 手持ちが1体のみのこと
  4. Xボタンを押したときに「タウンマップ」が左上、「ポケモン」がその右にあること
  5. ボックスが空のこと
  6. オフライン状態であること(機内モード推奨)
  7. 無線のコントローラー(プロコンなど)が接続されていないこと
  8. 「設定」から「話の速さ」を「速い」に、「手持ち/ボックス」を「自動で送る」に、「ニックネーム登録」を「しない」にしておくこと
  9. ちょいらくモードが「しない」であること
  10. まるいおまもりを所持していること

最後に

ボックス関連の操作に関しては何度もチェックしたので、おそらく大丈夫かと思います。孵化のタイミングに関してはやや検証不足ではあるものの、孵化用のコードを作成する際に調べたデータを活用しているので、こちらも問題ないと思われます。

ボックスに空きの列があるとループが止まってしまう問題に関しては、どうしてもスマートに解決することができませんでした。何か良い改善案があれば、@lefmarnaまでお知らせいただけるとありがたいです!

スポンサーリンク