【マイコン】ポケモン剣盾でタマゴの受け取りを自動化するコード!

ポケモン剣盾で、孵化はせずにタマゴだけをひたすら受け取っていくコードを用意しました。

親名にこだわりたい人に、タマゴのまま贈る際など役に立つと思います。

受け取ったタマゴの中身を確認する際には、以下のコードも合わせてご利用ください。

関連記事

ポケモン剣盾のボックスに、眠ったままになっているタマゴはありませんか? タマゴは孵化しないと逃せないので邪魔ですよね… しかし、自動化に慣れてしまうと孵化しそこねたタマゴを割っていくのもめんどうなものです。 そんな悩みを解決する[…]

ポケモン剣盾
ボックスのタマゴ
自動孵化!

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

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

関連記事

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

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

今回のコードは「NintendoSwitchControlLibrary」を使用しています。まだダウンロードされていない方は、解凍したフォルダを『Arduino』フォルダの中にある『libraries』フォルダの中にコピーしておいてください。

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

今回のコードは、空のボックスが続いている状態で使用してください。(例:ボックス1〜ボックス5が全て空の状態)

理由

タマゴを預ける際に、該当箇所にすでにポケモンが存在していると、そのポケモンと入れ替える形になってしまいます。ボックスの中身がぐちゃぐちゃになるだけでなく、次のタマゴをボックスに預けることに失敗してしまいます。

途中でタマゴが孵化することを想定していないため、預けるのに失敗したタマゴが孵化することでループが破綻してしまう可能性があります。

この問題を解消しつつ、より効率化できる手法についても考えており、それらの問題を解決したものも近日中に公開したいと思っております。

ソースコード

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

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

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

// タマゴを受け取るまでの間隔(数値が大きいほど間隔が長くなる)
const int INTERVAL = 15;

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

// 初期位置から育て屋さんに移動しタマゴを受け取る関数
void getEggFromBreeder() {
    // 初期位置(ハシノマはらっぱ)から育て屋さんのところまで移動
    pushButton(Button::PLUS, 600);
    tiltRightStick(Stick::MAX, Stick::NEUTRAL, 2000);
    tiltLeftStick(166, Stick::MIN, 800);
    pushButton(Button::PLUS, 450);
    // 育て屋さんから卵をもらう
    pushButton(Button::A, 450, 3);
    delay(750);
    pushButton(Button::B, 450, 10);
    delay(50);
}

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

// 孵化した手持ちのポケモンをボックスに預ける関数
// box_line : 何列目にポケモンを預けるか
void depositPokemon(int box_line, int egg_num) {
    // ボックスを開く
    pushButton(Button::X, 500);
    pushHat(Hat::RIGHT, 25);
    pushButton(Button::A, 1250);
    pushButton(Button::R, 1500);
    // 手持ちの孵化したポケモンを範囲選択
    pushHat(Hat::LEFT, 25);
    pushHat(Hat::DOWN, 25);
    pushButton(Button::Y, 25);
    pushButton(Button::A, 25);
    // ボックスに移動させる
    pushHat(Hat::RIGHT, 100, box_line + 1);
    if (egg_num == 4) {
        pushHat(Hat::UP, 25);
    } else {
        pushHat(Hat::DOWN, 100, egg_num);
    }
    pushButton(Button::A, 25);
    // ボックスがいっぱいになったら、次のボックスに移動させる
    if (box_line == 5 && egg_num == 4) {
        pushHat(Hat::UP, 25);
        pushHat(Hat::RIGHT, 25);
    }
    // ボックスを閉じる
    pushButton(Button::B, 25);  // ボックスが空でなかった場合でも、ボックスを閉じてループを実行し続けさせるのに必要な記述
    pushButton(Button::B, 1500);
    pushButton(Button::B, 1250);
    // メニュー画面のカーソルをタウンマップに戻す
    pushHat(Hat::LEFT, 25);
}

// 実際にループ内で呼び出す関数
void receiveEggs(int box_line) {
    // 手持ちが1体の状態から、卵受け取り→孵化を繰り返していく
    for (int egg_num = 0; egg_num < 5; egg_num++) {
        moveToInitialPlayerPosition();
        getEggFromBreeder();
        depositPokemon(box_line, egg_num);
        moveToInitialPlayerPosition();
        // 野生ポケモンとのエンカウントを避けるため初期位置から少し移動する
        tiltLeftStick(Stick::MAX, Stick::NEUTRAL, 500);
        runAround(INTERVAL);
        pushButton(Button::X, 500);
    }
}

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

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

    // 空飛ぶを使うことで、位置情報をリセットする
    moveToInitialPlayerPosition();

    // 初めのタマゴが出現するまで走り回る
    tiltLeftStick(Stick::MAX, Stick::NEUTRAL, 500);
    runAround(INTERVAL);

    // メニューを開く動作をループに含めてしまうと、毎回メニューを閉じないといけなくなってしまうため、ループから外すことにした
    pushButton(Button::X, 500);
}

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

コードの使い方

コードを使うにあたって確認して欲しいことが2点ほどあります。

設定の確認

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

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

タマゴを受け取る間隔を調整する

コードの20行目に注目してください。

const int INTERVAL = 15;

となっている箇所が見つけられましたか?

この『15』を大きな数字にすることでタマゴを受け取りに行くまでの間隔を長く小さい数字にすることでタマゴを受け取りに行くまでの間隔を短くすることができます。

「タマゴの見つかりやすさ」は預けているポケモンの相性によって決まり、預かり屋のコメントから確認することができます。

コメント 見つかりやすさ
とっても仲がいいようだ 見つかりやすい
まずまずのようだ それなりに見つかる
それほど仲が良くないようだ 見つかりにくい
別々に遊んでいる 見つからない

とはいえ、「とっても仲がいいようだ」を出すのはやや難しく、現実的には「まずまずのようだ」で回すことがほとんどかと思います。

今回の初期設定である『15』という値は「まずまずのようだ」において、9割近い確率でタマゴを受け取れることを確認しており、パフォーマンス的に優秀だと判断して設定しました。

『15』という値は厳密に計算された値ではなく、短期的なテストで使われていただけの適当な値です。自身でこの値を調整しながら回していくと良いでしょう。

最後に

ボックスに空きがある限りは、安定して回せるかと思います。しかし、ボックスに空きがなくなるとループから抜けてしまうことも考えられますので、できるだけ猶予のある状態で使用してください。

この問題を改善したバージョンも制作中でして、近日中に公開する予定です。そちらもご期待いただければと思います。

スポンサーリンク