以下の内容はhttps://tangential-star.hatenablog.jp/entry/Arduino_pokemon_FRLG04_auto_hunt_Shiny_Zapdosより取得しました。


【FRLG自動化04】色違いサンダー厳選【むじんはつでんしょ】

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

 

今回はFRLG自動化の第4弾として、準伝説ポケモン・サンダーの色厳選を自動化しました。
※一般ポケモンの色厳選はこちら→【FRLG自動化02】野生ポケモン色違い厳選【あまいかおり】

 

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

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

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

 

概要

今回は、準伝説ポケモン・サンダーの色厳選を自動化しました。むじんはつでんしょの出入りを色違いが出るまで繰り返します。ゴールドスプレー利用想定で、ざっくり8時間放置で1,000回、20時間で2,500回の色厳選が行えます。

建物を出入りし、サンダーが色違いじゃなかったら逃げるをひたすら繰り返す。
20時間の放置で、約2,500試行できる。「ゴールドスプレー」は必携だぞ

目次です。今回は、理論抜きのあっさりです。

お急ぎの方は4.ソースコード まで読み飛ばしてください。

 

0.成功報告

筆者は丸2日放置6,398試行目で、色違いのサンダーに無事に会えました

使用した「ゴールドスプレー」は延べ255本です(キリが良いですね)

筆者は無事に色違いのサンダーと遭遇できた。
延べ6,398試行、経過時間は50時間55分51秒だった

画面録画の都合上、2回に分けて実行しましたが、少なくとも筆者環境・本記事紹介のソースコードで「27時間4分22秒(3,400試行)の連続稼働」を確認しています*1。また、色違い遭遇後も逃げることなく、終始動作が安定していました。

※筆者が使ったマイコンボードは「」です。導入方法は【Arduino自動化01】Arduino開発環境の導入をご参考ください。

FRLG自動化の動作は「Switch2」で確認している。
筆者はSwitch2のドックに有機EL用のUSBハブスタンドと4つを組み合わせ、
有線コントローラーを接続しているぞ(2026/4/1現在)

 

1.Switch版FRLGの伝説・準伝説は、逃げればマップ切り替えで復活する

まず、FRLGの色違いの厳選についてです。

FRLGにおいて、ミュウツーなどの「伝説ポケモン*2」や、「ファイヤー」などの準伝説ポケモンは「固定シンボル」として登場します。固定シンボルとは、言い換えると、Aボタンを押して話しかけることで戦闘になるポケモンです。

固定シンボルで登場するポケモンの多くは、野生ポケモンの色違い厳選とは異なり、作中で1匹しか手に入れることができませんので、色違いの価値は相対的に高いものになります。

「固定シンボル」とは、Aボタンで話しかけることで戦闘になるポケモンのことだ。
ミュウツーやフリーザー・サンダー・ファイヤーなどの伝説ポケモンの多くが該当するぞ
作中に1匹しか出ない準伝説/伝説ポケモンの色違いは、とにかく希少なのだ

FRLGでは、この伝説・準伝説ポケモンの前でセーブをしておき、話しかけて色違いじゃなかったらリセットを繰り返す、いわゆる「固定リセット」という方法で色厳選を行います。

もちろん、Switch版でもGBA版と同様の方法で色厳選を行うことができますが、Switch版のFRLGでは、伝説・準伝説ポケモンとの戦闘で「にげる」を選択して戦闘を離脱しても、マップを再読み込みすることでその固定シンボルが復活する*3ように仕様が変更されています(注:「にげる」で復活する固定シンボルのは伝説・準伝説のみ*4です)。

すなわち、Switch版のFRLGにおいて、固定シンボルで登場するポケモンによっては、タイトル画面~あらすじを見終わるまでの待機時間が発生するソフトリセットよりも短い時間間隔で、高効率に色厳選ができると言い換えることができます*5

そして、固定リセットよりも効率的に色厳選ができる筆頭が、「むじんはつでんしょ」に登場する「サンダー」です

戦闘で逃げると「サンダーは どこかへ とびさって いった!」となり姿をくらます。
Switch版のFRLGでは建物を出入りすると帰ってくるのだ(「にげる」を選択した場合のみ)

 

2.サンダーは「むじんはつでんしょ」の最奥にいる

前節では「リセットをしない色厳選(建物の出入り)」にサンダーが適していることを紹介しました。

サンダーは、イワヤマトンネルのポケモンセンターの近くにある「むじんはつでんしょ」に生息しています。ただし「むじんはつでんしょ」に向かうためには「なみのり」が必要なので、シナリオ上はセキチクシティまで進める必要*6があります。特にギミックもありませんので、そのまま中に入りましょう。

なお、「むじんはつでんしょ」の中は概ね1本道です。そのまま奥に進むと、サンダーがいます。

むじんはつでんしょの最寄りはイワヤマトンネルのポケモンセンターだ。
「なみのり」を使って南に進めばたどり着くぞ
「むじんはつでんしょ」の中に入ったら、一番奥の部屋を目指そう。
そこに、でんせつのとりポケモン「サンダー」がいるのだ

 

3.サンダーの色厳選のために「ゴールドスプレー」を買っておこう

さて、「むじんはつでんしょ」のサンダーがいる場所までたどり着いたら、あとは色違いの厳選を行うだけです。話しかける前に、セーブをしておきましょう。

3-1.サンダーの色違い厳選の手順

色違い厳選の具体的な手順は、下記の通りです。

  1. 「A」ボタンでサンダーに話しかける
  2. サンダーの色を確認する。
  3. 色違いでなければ、「にげる」を選んで戦闘を終える
  4. 「サンダーは どこかへ とびさって いった!」となる
  5. 左の出口から出て、再度その入口から入る
  6. サンダーの固定シンボルが復活している
  7. 再びサンダーに話しかける
  8. 手順3に戻る

サンダーの色を確認して、通常色なら「にげる」のを、ひたすら繰り返すのだ


3-2.サンダーの色厳選には「ゴールドスプレー」が必須

ところで、サンダーが登場する「むじんはつでんしょ」では、洞窟や草むらと同様に、野生ポケモンとのランダムエンカウントが1歩ごとに判定されます。

これはすなわち、色厳選中に野生ポケモンが出現する可能性があり、効率が落ちてしまうことが考えられます。

戦闘直後でさえ「方向転換するだけでエンカウント」することがあるのだ。
長時間の色厳選のストレスを無くすためには、ゴールドスプレーは必須だと言える

このような事故を無くすためには、野生ポケモンと出会わないように「むしよけスプレー(100歩)」「シルバースプレー(200歩)」「ゴールドスプレー(250歩)」のいずれかのアイテムを利用することが有効です。これらのスプレー系のアイテムは、先頭ポケモンのレベルより低いポケモンとのエンカウントを防いでくれる効果があり、各地のフレンドリィショップで購入することができます。

なお、1歩あたりの金額という点で「シルバースプレー」が最もコスパに優れてはいるのですが、色厳選という特性上、試行回数が要求される用途では、できるだけ長い歩数のエンカウントを防止したいので、「ゴールドスプレー」が最適だと言えます。

なお、「ゴールドスプレー」は、ヤマブキシティ・セキチクシティ・グレンタウン・セキエイこうげんなどで購入することができます*7

サンダーの色厳選の前には、「ゴールドスプレー」を買えるだけ買っておこう。
「ゴールドスプレー」はヤマブキシティのポケモンセンターなどで買えるぞ

 

4.ソースコード

今回は、「むじんはつでんしょ」の最奥にいるサンダーの色厳選を、で自動化しました。約1時間で125試行できます。ゴールドスプレーを使って、サンダー以外の野生ポケモンとは出会わないように工夫しました。

4-1.事前準備

まず、ゲーム側の準備です。

「むじんはつでんしょ」の最奥にいる、サンダーのすぐ左のマスに立って、主人公が右を向いている状態にしてください(Aを押したらそのまま戦闘が始まる場所に立ちます)。

そして、「せってい」から、「はなしのはやさ」を「はやい」、「せんとうアニメ」を「みない」、「ボタンモード」を「LR」に、それぞれ変更してください。

また、「どうぐ」の1番上に「ゴールドスプレー」を大量に準備(目安:150個程度)して、それにカーソルをあわせた状態でバッグを閉じます*8。そのまま、メニューの「バッグ」にカーソルをあわせてメニューを閉じれば、ゲーム側は準備完了です。

必ず「ボタンモード」を「LR」にして、「はなしのはやさ」を「はやい」にしておこう
「どうぐ」の一番上に「ゴールドスプレー」を準備してカーソルを合わせてメニューを閉じよう

続いて、ソースコードの修正です。

ソース49行目の「RepelNum」の数字に、自分が所持している「ゴールドスプレー」の数を入力してください。ゴールドスプレーを利用する場合は、この1箇所のみの書き換えでOKのはずです。

なお、「ゴールドスプレー」の代わりに「シルバースプレー」や「むしよけスプレー」を使う場合は、48行目の「RepelSteps」にスプレーの種類に応じた歩数を入力してください(ただし、筆者は未検証です。「ゴールドスプレー」を使うことを推奨します)。

// ★「ゴールドスプレー」「シルバースプレー」「むしよけスプレー」どれを使うか(歩数を指定)
const int RepelSteps = (250); // 使うスプレーの歩数を入力(ゴールドスプレー:250 / シルバースプレー:200 / むしよけスプレー:100)
const int RepelNum = (159);   // 持っているスプレーの数を入力

 

4-2.ソースコード全文

ソースコードの全文です。コード冒頭の注意事項もよく読んで利用してください。

/*  FRLG 色違いサンダー自動厳選 developed by ますたー(@tangential_star)
 *   
 *   【説明】
 *   むじんはつでんしょの最奥にいるサンダーに話しかけては逃げるを繰り返します。
 *   色違いのときは逃げません。
 *   「ゴールドスプレー」を使います!どうぐの一番上にして、かつ、十分な量を持ってください。
 *   あと、カーソルもこれに合わせてください。
 *   
 *   ゴールドスプレーを使い切ると、プログラムは止まります!十分な量のスプレーを用意してください。
 *   1試行あたり10歩なので、ゴールドスプレー1本で25試行、色厳選ができます。
 *   ※参考までに999本のゴールドスプレがあれば、(999-1)*25=24,950試行実施できます。
 *   
 *   【準備】
 *   ・「むじんはつでんしょ」最奥にいるサンダーのすぐ左のマスに立ち、主人公が右に向いた状態にします(Aを押したら戦闘できる状態)。
 *   ・先頭ポケモンは、野生のサンダーに対して十分に素早さが高いポケモンにします。(確実に逃げられるように)必要素早さの目安は133です。
 *   ・先頭ポケモンは、レベルが少なくとも36以上(LG版はLv35以上)であることを確認してください(ゴールドスプレーの効果を有効にするため)。【重要】
 *   ・先頭ポケモンは、戦闘開始時に「とくせい」が発生しないポケモンにしてください。
 *   (色違いエフェクトの有無による時間差で色違いの判定を行うので「いかく」などが入ると正しく動作しません)
 *   ・バッグの一番上には「ゴールドスプレー」を置いて、かつ、未発動の状態にしてください。少なくとも150個程度の所持を推奨します【超重要】
 *   ・バッグの一番上にカーソルがあっている状態にしてください(まだスプレーは使わないでください)。【重要】
 *   ・「X」でメニューを開いて「どうぐ」にカーソルを合う状態にしてメニューを閉じます【重要】
 *   ・「せってい」から「せんとうアニメ」を「みない」にしておく。
 *   ・「せってい」から「話のはやさ」を「はやい」にしておく。
 *   ・「せってい」から「ボタンモード」を「LR」または「ヘルプ」にする ※「かたて」にしない【重要】
 *   
 *   ・ソース48行目の「RepelSteps」の数字に、どうぐ欄の1番上に置いたスプレーに応じた「歩数」を入力する
 *   (ゴールドスプレーなら「250」を入力)
 *   ・ソース49行目の「RepelNum」に、どうぐ欄の1番上に置いたスプレーの「個数」を入力する
 *   (例えば、30個もっていれば「30」、999個持っていれば「999」と入力します)
 *   
 *   ★Switch2でしか動作確認していません。必要に応じて、待機時間などを調整してください。
 *   ★万が一、色違いから逃げても操作が狂って意図しない動作が起こっても、筆者は一切の責任を負いません。自己責任でご利用ください。
 *   ★第三世代での色違い出現確率は1/8192です。第六世代以降の半分です。めっちゃ出にくいですよ!
 *   (成功報告:筆者は2026/3/31に「6,398試行目」にて色違いサンダーに出会えました!放置時間は50時間55分51秒、すなわち丸2日超です)
 *   
 *  (c) 2026 ますたーの忘備録
 *  https://tangential-star.hatenablog.jp/
 */

#include <SwitchControlLibrary.h>
#define HOLDTIME (95) // 1回のキー入力の長押し時間
#define SWITCH_VER (20)

// ----------------------------------
// ★★★ここを書き換える↓★★★

// ★「ゴールドスプレー」「シルバースプレー」「むしよけスプレー」どれを使うか(歩数を指定)
const int RepelSteps = (250); // 使うスプレーの歩数を入力(ゴールドスプレー:250 / シルバースプレー:200 / むしよけスプレー:100)
const int RepelNum = (159);   // 持っているスプレーの数を入力

// ★サンダーのすぐ左で、手動でスプレーを使った状態でプログラムを無理やり開始する場合は「true」にしてください(未検証)
volatile bool usingRepel = false;

// ★もし、上記を完全に無視する(スプレーを一切使わない)場合は下記を「true」にしてください(未検証。ただし、どうぐの1番上=カーソルがあっているアイテムは、戦闘中に「使えない」アイテム(例:つきのいし・ゴールドスプレーなど)にしてください)
const bool IGNORE_REPRL = false;

// ★★★ここを書き換える↑★★★
// ----------------------------------

// グローバル変数
volatile int used_Repel  = 0; // むしよけスプレーを使った数
volatile int steps_taken = 0; // 歩いた歩数
volatile bool needRepelUse = true;

// ボタン押しラッパー関数
int PushKey(char* keyname, int holdtime, int delaytime);
void TiltLeftStick(int direction_deg, double power, int holdtime, int delaytime);
void TiltRightStick(int direction_deg, double power, int holdtime, int delaytime);
void renda(char* key ,long int time_to_press_repeatedly);

// 今回の関数
void die(void);
bool useRepel(void);
bool SkipRepelMessage(void);


void setup() {
  for(int i=0;i<3;i++)PushKey("B", HOLDTIME, 300); // Bボタンを3回押してSwitchに認識されるのを待つ
  PushKey("B", HOLDTIME, 300); // Bを押しておく。
  delay(1000);
}

// サンダーのすぐ左でスタート!
void loop() {

  // ■どうぐ「ゴールドスプレー」を使う
  if(IGNORE_REPRL==false){ // 基本的には使う前提で組んでいます。
    // スプレーを使い切っていたらこのプログラムは終了
    if( (usingRepel==false) && (used_Repel >= RepelNum) ){
      die(); 
    }
    // スプレー使用可否の判定
    if(needRepelUse){
      if( usingRepel ){
        // スプレー使用中は何もしない。
      }else{
        // スプレー未使用時は、バッグを開いてスプレー利用
        useRepel(); 
      }
    }
    // この時点で[色違いとの戦闘画面:→バッグ]
  }

  // ■サンダーに話しかける
  PushKey("A", HOLDTIME, 1700); // ギヤーオ! [色違いとの戦闘画面:→ゴールドスプレー]
  PushKey("A", HOLDTIME, 10); // 戦闘開始 [色違いとの戦闘画面:→やめる]

  // 「あ! やせいの サンダーが あらわれた!▼」まで待機
  delay(5180);

  // ■戦闘に入る
  // あ! やせいの サンダーが あらわれた!▼
  PushKey("A", HOLDTIME, 100); // [色違いとの戦闘画面:→ゴールドスプレー]
  
  // ゆけっ! ●●!!
  PushKey("A", HOLDTIME, 100); // dummy [色違いとの戦闘画面:→やめる]
  delay(2700);

  // ■サンダーが色違いじゃない場合、「にげる」にカーソルをあわせる
  // ●●は どうする? →たたかう  バッグ
  //            ポケモン  にげる
  PushKey("right",HOLDTIME, 20); // →キー入力
  PushKey("down", HOLDTIME, 20); // ↓キー入力
  // ●●は どうする?  たたかう  バッグ
  //            ポケモン →にげる
  delay(2100); // 待機

  // この時点で[色違いとの戦闘画面1回目:あ! やせいの サンダーが あらわれた!▼
  PushKey("B", HOLDTIME, 300);  // [色違いとの戦闘画面1回目:ゆけっ! ●●!!]
  PushKey("B", HOLDTIME, 2800); // [--(ポケモン繰り出し中)]

  // ■この時点で「●●は どうする?」になって、カーソルが
  // 色違い以外: →にげる
  // 色違い1回目:→たたかう
  // 色違い2回目:→バッグ

  // ■逃げる
  PushKey("A", HOLDTIME, 1100); //  [色違いとの戦闘画面1回目:→わざ1番目] [色違いとの戦闘画面2回目:バッグの中] 

  // うまく にげきれた!▼
  PushKey("B", HOLDTIME, 4200); //  [色違いとの戦闘画面1回目:→たたかう] [色違いとの戦闘画面2回目以降:→バッグ]

  // フィールドに戻って暗転
  // ■サンダーは どこかへ とびさって いった!
  PushKey("B", HOLDTIME, 300); // フィールドに戻る

  // ■むじんはつでんしょを出る
  SwitchControlLibrary().PressButtonB(); // Bを押しながら
  SwitchControlLibrary().MoveHat(6); // ←キーを長押し
  delay(2750); // 10ばんどうろ に出て1歩左
  SwitchControlLibrary().MoveHat(8); // ←キーを離す
  delay(10);
  steps_taken+= 4;

  // ■歩数調整(上下で2歩消費)
  SwitchControlLibrary().MoveHat(4); // ↓キーを長押し
  delay(100);
  SwitchControlLibrary().MoveHat(8); // ↓キーを離す
  delay(10);
  SwitchControlLibrary().MoveHat(0); // ↑キーを長押し
  delay(100);
  SwitchControlLibrary().MoveHat(8); // ↑キーを離す
  delay(10);
  steps_taken+= 2;

  // ■むじんはつでんしょに入る
  SwitchControlLibrary().MoveHat(2); // →キーを長押し
  delay(3600); // サンダーに接触
  SwitchControlLibrary().MoveHat(8); // →キーを離す
  SwitchControlLibrary().ReleaseButtonB(); // Bを離す 
  delay(100);
  steps_taken+= 4;

  // [色違いとの戦闘画面1回目:→バッグ] [色違いとの戦闘画面2回目以降:→バッグ]

  // ■スプレーの効果が切れたらBを押す&もろもろ変数を更新
  SkipRepelMessage();

}


// 以下、今回の関数 --------------------------------------
void die(void){
  for(;;) delay(100);
}
bool useRepel(void){
  PushKey("X",HOLDTIME, 800);  // ★メニューを開く [色違いとの戦闘画面:→バッグ]
  PushKey("A",HOLDTIME, 1000); // → バッグ [色違いとの戦闘画面:→ゴールドスプレー]
  PushKey("A",HOLDTIME, 400);  // → ゴールドスプレー×159 [色違いとの戦闘画面:→やめる]
  PushKey("A",HOLDTIME, 400);  // ゴールドスプレーをどうしますか? →つかう [色違いとの戦闘画面:→ゴールドスプレー]
  PushKey("A",HOLDTIME, 1200); // ますたーは ゴールドスプレーを つかった! [色違いとの戦闘画面:→やめる]
  PushKey("B",HOLDTIME, 500);  // → ゴールドスプレー×158 [色違いとの戦闘画面:→ゴールドスプレー]
  PushKey("B",HOLDTIME, 1000); // → バッグ [色違いとの戦闘画面:→バッグ]
  PushKey("B",HOLDTIME, 300);  // ★フィールドに戻る [色違いとの戦闘画面:→バッグ]

  // むしよけスプレーを使った数を更新
  used_Repel++;

  // 現在の歩数をリセット
  steps_taken = 0;

  // むしよけスプレーを使っている状態に変更。
  usingRepel = true;

  return true;
}

bool SkipRepelMessage(void){
  // もし歩数がスプレーの有効歩数になった場合
  if( steps_taken >= RepelSteps){
    usingRepel = false;

    // スプレーの こうかが きれた
    delay(150);
    PushKey("B", HOLDTIME, 300);
    needRepelUse=true;
    return true;
  }
  return false;
}


// 以下、汎用---------------------------------------------------------------

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 TiltLeftStick(int direction_deg, double power, int holdtime, int delaytime){
  double rad = (double)direction_deg*PI/180.0; // 弧度法(ラジアン)変換
  int x, y;
  x = (double)128*sin(rad)*power;
  y = (double)-128*cos(rad)*power;
  x += 128; y += 128;
  if(x >= 255) x=255; if(x <= 0) x=0;
  if(y >= 255) y=255; if(y <= 0) y=0;

  SwitchControlLibrary().MoveLeftStick(x,y);
  if(holdtime> 0){ // holdtime=0のときは押しっぱなし。
    delay(holdtime);
    SwitchControlLibrary().MoveLeftStick(128,128); // 傾きを直す
  }
  if(delaytime>0) delay(delaytime);
  return;
}

void TiltRightStick(int direction_deg, double power, int holdtime, int delaytime){
  double rad = (double)direction_deg*PI/180.0; // 弧度法(ラジアン)変換
  int x, y;
  x = (double)128*sin(rad)*power;
  y = (double)-128*cos(rad)*power;
  x += 128; y += 128;
  if(x >= 255) x=255; if(x <= 0) x=0;
  if(y >= 255) y=255; if(y <= 0) y=0;

  SwitchControlLibrary().MoveRightStick(x,y);
  if(holdtime> 0){ // holdtime=0のときは押しっぱなし。
    delay(holdtime);
    SwitchControlLibrary().MoveRightStick(128,128); // 傾きを直す
  }
  if(delaytime>0) delay(delaytime);
  return;
}

void renda(char* key ,long int time_to_press_repeatedly){
  unsigned long int current_time=0;
  unsigned long int start_time=0;

  // 決められた時間ずっとA連打
  for( start_time=millis(), current_time=start_time ; current_time - start_time < (unsigned long)time_to_press_repeatedly*1000UL ; current_time=millis() ){
    PushKey(key, 50, 50); // ひたすら連打
  } 
  return;
}

 

5.動作確認

さて、今回実装したサンダーの自動色厳選ですが、無事に丸2日間・延べ6,398試行目で色違いに出会うことができました。在宅勤務日の早朝に出会うことができたため、捕まえてから気持ちよく仕事に臨むことが出来ました。

色違いサンダーに気づいたのは8:07頃。それから10分ほど捕獲に費やした。
投げたハイパーボールは34個。手に汗握る戦いだった。

さて、個人的な感想ですが、自動化のコーディングや待機時間もそれなりにかかったのですが、振り返ると、サンダーを捕獲するのが一番苦労したかもしれないと思います。

というのも、フシギバナの「ねむりごな(PP15)」のPPがすべて枯れるほど捕獲が難航したからです。その場でピーピーエイドを使ってPPを補いつつ、「あまいかおり」でねむりごなを必中にしつつ、適宜眠らせていましたが、とにかくサンダーのPP切れが非常に怖かったです。

もし、今からチャレンジされる方がいらっしゃるなら、事前に捕獲やPP切れ対策の練習をしておくことを強くおすすめします

特に、HP削り要員や催眠要員の準備、ならびに手持ちのレベル上げをしておくべきでした。筆者は旅パのそのままだったので、相手の「ドリルくちばし」に大変苦労しました。サンダーはでんきタイプの技を持っていないですが、タイプ一致の飛行技はかなり凶暴です。

とは言え、個人的には(準備不足は否めませんでしたが)無事に捕獲することができたので大満足の結果になりました。

色違いサンダーに出会ったら、あとは捕まることを祈ってボールを投げよう。
色違いは捕まえなければ意味がない。「ねむり」の状態異常は重要かも!?

無事に捕まえた色違いのサンダー。名前は「さんさん」にしたぞ

 

6.あとがき

ついに4月になりました。年度が変わって2026年度ですね!皆様はいかがお過ごしでしょうか。筆者は、仕事もプライベートも超充実!で、かなり時間的に余裕が無い生活をしています。というか仕事内容が4月から増えたため、結構てんやわんやしています。

さて、仕事の話は置いておいていったんポケモンFRLGの状況について雑記です。私は未だにポケモンFRLGのシナリオはバッジ6個です

その途中に色違いのサンダーの放置厳選を始めて丸2日間かけたり、まだ作成中ですがフリーザーの色厳選をプログラミングしてみたりと、かなりゆっくりとシナリオを進めています。上述の通り無事に色違いサンダーにも会えましたし、手持ちには【FRLG自動化02】野生ポケモン色違い厳選【あまいかおり】で見つけた色違いのロコン(現在はキュウコン)もいて、楽しく遊べています。

そういえば、サンダーを捕まえるために「むじんはつでんしょ」に寄ったのですが、リーフグリーン版は野生でエレブーが出ないんですね(´・ω・`)。子供の頃に遊んでいた頃はファイアレッド版、その後にリーフグリーンの両方を遊んでいたのですが、序盤からナゾノクサやガーディ、コダックが出ないということに改めて驚かされました。バージョン限定ポケモンの存在を改めて痛感させられますね。

余談だが、サンダーの隣には「かみなりのいし」が隠しアイテムとして落ちている。
筆者は、こういうところに、図鑑説明を感じられるのが好きなのだ
(くもの うえから きょだいな いなずまを おとしながら あらわれる でんせつの とりポケモンである。)

さて、4/5現在はようやくグレンタウンに到着、「ふたごじま」にも足を運び、フリーザーの色違いがほしいなぁと思いながらプログラムを書いています。

しかしながら、フリーザーの色厳選はなかなか動作が安定せず、デバッグだけで3日間ほどかかっており、公開できるかは怪しいかな?と思いつつです(「なみのり」の移動マス数が実行する度に変わる。おそらく野生エンカウント判定の割り込み処理でFRLGの動作が重くなるタイミングがあるのかも)。サンダーの色厳選は動作が安定していたので、純粋に移動距離と複雑さが影響しているのだと感じます。

こちらは、のんびりとコーディング&動作検証してみます(公開しないかもしれませんし、後日ベータ版として公開しちゃうかも。ここは未来の私に任せます)。

2026/4/5現在コーディング&動作確認中の「フリーザー色厳選自動化」
なかなか動作が安定せず、公開できないかもしれない。

 

ともかく、早いものでFRLG自動化の記事もいよいよ4本になりました。

こんな感じでのんびりと更新していけたらと思いますので、引き続き応援の程よろしくお願いいたします!皆様の成功報告もお待ちしておきます!

 

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

 

前回の記事:【FRLG自動化03】物語中盤レベル上げ【ポケモンタワーであまいかおり】

(FRLGの記事一覧はこちらから→ ポケモンFRLG自動化 カテゴリーの記事一覧

--

本ブログについて:本ブログについて

 

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

ポケモン剣盾の記事:ポケモン剣盾Arduino自動化 カテゴリーの記事一覧

ポケモンBDSPの記事:ダイパリメイクArduino自動化 カテゴリーの記事一覧

レジェンズアルセウスの記事:レジェンズアルセウスArduino自動化 カテゴリーの記事一覧

スカーレット・バイオレットの記事:スカーレットバイオレットArduino自動化 カテゴリーの記事一覧

レジェンズZ-Aの記事:レジェンズZA自動化 カテゴリーの記事一覧

ポケモンFRLGの記事:ポケモンFRLG自動化 カテゴリーの記事一覧

 

YouTubeチャンネル:ますたーの忘備録 - YouTube

www.youtube.com

 

*1:長時間放置を推奨するものではなく、動作を保証するものではございません。あくまでも参考情報として、連続27時間の放置ができたことを報告するものです。なお、筆者はNintendo Switch2をドックに挿したTVモードで利用し、Switch2上部またはドック左側のUSBポートからArduino Leonardoを挿している構成で行っております

*2:伝説ポケモン:ミュウツーやホウオウ、ルギアなどを指す愛称。かつてレート戦に出られなかったことから、「禁止級」「禁止伝説」という呼び名でも知られる

*3:Switch版のFRLGで固定シンボルが復活するのは「にげる」を押して戦闘を終えた時だけです。当然ですが、倒したり捕まえたりすると復活しませんので注意しましょう

*4:たとえば「カビゴン」や「マルマイン」など、同じシンボルエンカウントでも「復活しない」ポケモンもいます。注意しましょう

*5:ソフトリセットを用いないので、本ブログで紹介しているによる画像認識を用いないSwitch自動化にも応用できると言えます

*6:ひでんマシン03「なみのり」は、セキチクシティ「サファリゾーン」の最奥の建物「トレジャーハウス」の男性に話しかけるともらえます。なお、使用するには「ピンクバッジ」も必要なので、同じくセキチクシティのジム戦も攻略しておきましょう

*7:その他「3のしま」「4のしま」「6のしま」「7のしま」などでも購入することができます

*8:スプレーはプログラムが自動的に使用しますので、準備段階であらかじめ使う必要はありません




以上の内容はhttps://tangential-star.hatenablog.jp/entry/Arduino_pokemon_FRLG04_auto_hunt_Shiny_Zapdosより取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14