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


【FRLG自動化02】野生ポケモン色違い厳選【あまいかおり】

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

 

今回は、FRLG自動化の第2弾として、野生ポケモンの色違い厳選を自動化しました。

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

 

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

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

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

 

概要

今回は、野生ポケモンに出会うことができる「あまいかおり」によるエンカウントを自動化し、「放置色違い厳選」を実現しました。草むらや洞窟など、ほとんどどこでも放置で色違いとエンカウントできます。1試行あたり約27.2秒です。

色違いが出るまでひたすら、逃げては「あまいかおり」を繰り返すのだ。
1試行あたり約27秒で、1時間あたり約132試行の時間効率になる

目次です。今回は理論も多いですが、GIF動画が多めなので楽しく読めると思います。「早くソースコードが欲しい」という方は⇒ 5.ソースコード

 

1.第三世代の色違い確率は1/8192で、FRLGの色厳選は苦行

近年のポケモン作品(例えば剣盾・SV・ZAなど)において「色違い」の出現確率は皆様ご存じ「1/4096」ですが、いわゆる第五世代(ポケモンBW)以前のポケモン作品ではその半分の「1/8192」です。つまり、今回のファイアレッド・リーフグリーンにおける色違いの出現確率はわずか1/8192です。しかも、同じ1/8192の作品でも、BW2には「ひかるおまもり」という色違いとの遭遇率を3倍にするアイテムが登場しますし、DPPtでは「ポケトレ連鎖」など色違いの確率を高めるアイテムも登場しますが、第三世代はこれらのアイテムが実装される前ですから、これ以上効率を高めることもできません。つまり、FRLGでの色違い厳選は、近年のポケモン作品と比べると苦行になります。

どのくらい苦行かと言えば、5000回野生ポケモンに出会っても色違いに出会える確率は5割を切るというとんでもない低確率です。第六世代以降(ポケモンXY)でもポケモンFRLGに出るポケモンは捕まえることができますから、色違いが欲しいだけならFRLGにこだわる理由はありません。

第三世代の色違い確率はわずか1/8192。
5,678度試行しても、色違いに会えるかは五分五分なのだ

FRLGでの厳選が苦行とは言え、「GBA作品がSwitchで遊べる」という点や、今後ルビー・サファイアなどのSwitch版が出るであろう点*1を考慮すると、FRLGで色違いを捕まえておく価値は十分にあります。それに、第三世代をリアルタイムで遊んでいた世代からすれば、「第三世代だからこそ」厳選したい、という気持ちが出てくるのはよくわかります。

何よりも、この令和の時代に、ドット絵のポケモンで色違いが厳選できるってだけでエモいですからね!

 

2.効率的に色違い厳選するには「あまいかおり」が最適

さて、(あえて)FRLGで色違い厳選を進める上で、野生ポケモンと効率的に出会うためには、やはり「あまいかおり」による強制エンカウントが便利です。これは、草むらから1歩も歩くことなくボタン操作のみで完結し、野生ポケモンの出現にかかる時間も一定になるため、「どのくらい時間をかけられるか」の目安が示しやすいためです。

あまいかおりを使ったエンカウントでは、草むらをウロウロする操作が不要で、誤って草むらの外に出たりトレーナーに見つかったり、あるいは毒などで手持ちが力尽きたりが発生しないため、結果的にストレスも少なくなります。そして、特に、本ブログで扱うような「(画像認識を使わない)Switch自動化」を行う場合には、エンカウント時間が一定、必ずエンカウントできる、というのは非常に重要です。

「あまいかおり」を使えば、野生ポケモンに【必ず】エンカウントできる。
エンカウントまでの時間が一定なので、色違いの厳選の自動化にも応用できるのだ

ちなみに「あまいかおり」を、道路などポケモンが生息しない場所で使うと
「ここには なにも いないようだ…」と教えてくれるぞ

 

3.色違いは「キラン」と光るエフェクトの有無で判断できる

3-1.意外と見逃しやすい色違い

一般的に「色違い厳選」と聞けば、その判断には、文字通り「色が違うかどうか」を目視で判定することが考えられます。

しかしながら、そもそも外見として「色違いかどうかが分かりづらいポケモン」が一定数いる上に、特に、大変な試行回数を要する色厳選では集中力が途切れがちで、せっかく色違いが出たのに気づかずにリセットしたり逃げたりしてしまう事故もよく起こります。特に、人間が見ても色違いかどうか迷うようなポケモンは、画像認識でも数値的な差が出にくいため、コンピュータですら判断を誤ってしまう可能性もあります。

例えば、FRLGだとケーシィやニャースは見分けづらい筆頭候補だと思います。

ぱっとみて色違いかどうかがわかりにくいポケモンもいるのだ。
(色違いは左右どっちでしょう? こたえ:「ひだり←範囲選択して読んでください

 

3-2.戦闘での登場時に色違いは「キラン」と光る

さて、色厳選をしている方はご存じだと思いますが、目視以外にも「色違いポケモン」を判断できる方法があります。それは、色違いの登場時に発生する「キランと光るエフェクト(映像効果)やSE(効果音)」を使う方法です。

もちろん、目視では登場シーンを見逃す・聞き逃すリスクこそありますが、色以外の「明確な差」であるため、機械的には、これを正確な判断材料にするのが適切だと言えます。特に初代のポケモン(FRLGで登場するポケモン)には色違いがわかりにくいポケモンが多いため、キランと光るエフェクトの目視が大変有効です。

どんなに色違いがわかりにくいポケモンでも、等しく「キラン」と光るのだ

 

3-3.色違いと通常色のメッセージ表示には約1.519秒の差がある

先述の通り、色違いのポケモンが登場すると「キラン」とエフェクトが出現しますが、このエフェクトの有無が、Switch操作の自動化での色違い判定にも有効です。

具体的には、通常色と色違いでは「あまいかおり」を発動してから、「あ!やせいの ●●が とびだしてきた!▼」というメッセージが表示されるまでに「1.519秒」の差があるのです(※筆者計測値)。

つまり、この時間差をうまく使えば、画像認識や音声認識に依存しない(文字通り視聴覚を必要としない)完全な自動化が実現できるのです。

実は、通常色と色違いで、「とびだしてきた!▼」が表示されるまでの時間が違うのだ。
「あまいかおり」発動から、通常色は9秒と2フレーム、色違いは10秒33フレームになる。
すなわち、1秒31フレームの差(約1.519秒)だ(※筆者による計測値。1秒=60Fで計算)

※完全に余談ですが、筆者が過去に公開したBDSP版の「アルセウス色厳選」(Poke-Controller使用)や、ポケモンエメラルド「みなみのことうミュウの色厳選」(DS Lite改造)も、この時間差に着目して実装しています。

 

4.色違いエフェクトの有無を活かした色違い厳選の自動化

ここからはArduino自動化を行うことを念頭に、「あまいかおり」での野生色厳選について解説します。ただし、「動作原理はいらない、早くソースコードが欲しい」という方は⇒ 5.ソースコード まで読み飛ばしてください。

まず、色違いが出現するまでの時間が一定で、かつ、野生ポケモンに必ずエンカウントできるという点で、野生ポケモンを出す方法としては「あまいかおり」を採用します。

そして、前述の通り色違いの時には、「●●がとびだしてきた!▼」が表示されるまでに約1.5秒の遅延がありますので、この遅延の間に、「→」と「↓」を入力すれば、通常色のときにはカーソルを「にげる」、色違いのときには「たたかう」に合わせることができます。これによって、通常色と色違いとの挙動を分断することが可能になります。

すなわち、「あまいかおり」を発動しては逃げ続ける「通常色のループ操作」をベースに、色違い遭遇時の「戦闘画面」を抜けないように(攻撃したり、逃げたり、道具を使ったりしないように)キー操作を調整すれば、自動化プログラムを作ることができます。下記は、実際に筆者がコーディングしたプログラムの手順(アルゴリズム)をまとめたものです。

 

【野生ポケモンの色厳選 キー入力操作の手順】

  1. フィールドで「あまいかおり」を発動する
    1. 「X」を押してメニューを開く
    2. 「→」を入力しておく(重要)
    3. 「A」を押して「ポケモン」を開く
    4. 「↑」を押して「あまいかおり」を覚えたポケモンにカーソルをあわせる
    5. 「A」を押して、そのポケモンを選択する
    6. 「↓」を押して、「→あまいかおり」にカーソルをあわせる
    7. 「A」を押して、「あまいかおり」を発動する
  2. その9.3秒後に通常色は「●●がとびだしてきた!▼」となるのでAを押す
  3. さらに2.8秒待機して「→」と「↓」を入力する
  4. 2秒ほど待機して、「B」を押して色違いの「●●がとびだしてきた!▼」を送る
  5. もう一度「B」を押して(重要)、2.8秒待機する
  6. この時点で、通常色は「→にげる」、色違いは「→たたかう」にカーソルがある
  7. 「A」を押して、通常色は戦闘から逃げる、色違いはわざ選択画面になる
  8. 「B」を押して、色違いは「→たたかう」カーソル状態に戻る
  9. 手順1に戻ってループ

上記の9つの手順をひたすら繰り返すことで、画像認識が不要な、純粋なコントローラー操作だけで色厳選の自動化が可能になります。

その様子を撮影・図示したものを下記YouTubeの動画にアップロードしました。映像は実機(Switch2)で実際に操作しているものです。興味があればご覧ください。

 

※解説音声などは入っていません。キー入力が図示されているだけの動画です。


www.youtube.com

 

それでは、次章ではいよいよお待ちかね、自動化のソースコードの紹介です。

 

5.ソースコード

今回は、「あまいかおり」を使って野生ポケモンと出会い、色違いでなければ「にげる」を押して再挑戦、色違いが出たら戦闘画面でとどまる操作を自動化しました。

5-1.事前準備

事前準備として、まず、手持ちに「あまいかおり」が使えるポケモンを加えてください。ただし、「あまいかおり」を使えるポケモンは、他のひでんわざ(いあいぎり等)を覚えさせないようにしてください。

てもちに「あまいかおり」を覚えたポケモンを準備しよう。
「いあいぎり」や「あなをほる」など、他のフィールドで使えるわざを覚えさせないように注意!

続いて、「せってい」の「ボタンモード」を「LR」にしてください。また、「はなしのはやさ」を「はやい」にして、「せんとうアニメ」は「みない」にしてください。

そして、「ポケモン」にカーソルをあわせた状態で、メニューを閉じてから、草むらの中や洞窟の中など、野生ポケモンが出現する場所に立ってください。

必ず「ボタンモード」を「LR」にして、「はなしのはやさ」を「はやい」にしておこう
「ポケモン」にカーソルがある状態でメニューを閉じて準備完了だ!

続いて、プログラムのソースコードの45行目・48行目の数字を必要に応じて修正してください。具体的には、手持ちポケモンの数と、「あまいかおり」が使えるポケモンが何番目かを入力してください。

// ★「あまいかおり」を覚えたポケモンが手持ちの何匹目かを指定↓
const int AMAI_KAORI = (1);  // 手持ち先頭:「1」~ 最後尾:「6」

// ★手持ちポケモンが何匹いるかを指定↓
const int TEMOCHI_NUM = (6); // 手持ちポケモンが6匹なら「6」

例えば、手持ちが4匹しかいなければ「TEMOCHI_NUM = (4);」で、先頭ポケモンが「あまいかおり」を覚えているのであれば「AMAI_KAORI = (1);」でOKです。

 

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

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

/*  FRLG 「あまいかおり」で自動放置色違い厳選 developed by ますたー(@tangential_star)
 *   
 *   【説明】
 *   「あまいかおり」を使って野生ポケモンと出会います。
 *   色違いじゃなかったら逃げて再度「あまいかおり」を使います。
 *   色違いだったら、戦闘画面のままになります。
 *   ※「プレッシャー」など、登場時にとくせいが発生するポケモンがいる場合には対応していません
 *   (未検証ですが、構想をソースコード中に記しています)
 *   
 *   【準備】
 *   ・くさむらの上や洞窟の中など、「あまいかおり」でポケモンが登場するところに立ちます。
 *   ・先頭ポケモンは、野生ポケモンに対して十分に素早さが高いポケモンにします(確実に逃げられるように)。
 *   (ほかにも、相手が「ありじこく」が出る可能性がある場合は、ひこうタイプにするなどのケアを行ってください)
 *   ・先頭ポケモンは、戦闘開始時に「とくせい」が発生しないポケモンにしてください。
 *   (色違いエフェクトの有無による時間差で色違いの判定を行うので「プレッシャー」や「いかく」などが入ると正しく動作しません)
 *   ・「あまいかおり」が使えるポケモンは、フィールドで使える他のわざ(フラッシュ・いあいぎりなど)を覚えさせないようにしてください。
 *   ・バッグの中にどうぐ/たいせつなもの/モンスターボールを各1種類以上いれておいてください(戦闘中に開いたときに道具が1つもなくて「→やめる」だけにならないようにしてください)。
 *   ・「X」でメニューを開いて「ポケモン」にカーソルを合う状態にしてメニューを閉じます【重要】
 *   ・「せってい」から「せんとうアニメ」を「みない」にしておく。
 *   ・「せってい」から「話のはやさ」を「はやい」にしておく。
 *   ・「せってい」から「ボタンモード」を「LR」または「ヘルプ」にする ※「かたて」にしない【重要】
 *   ・ソース45行目の「AMAI_KAORI」の数字に「あまいかおり」を覚えた手持ちポケモンが何匹目かを入力
 *   (手持ちの先頭なら「1」、最後尾なら「6」を入力)
 *   ・ソース48行目の「TEMOCHI_NUM」に手持ちの数を入力。
 *   (手持ちの数が6匹全部埋まっていたら「6」,3匹なら「3」など)
 *   
 *   ★Switch2でしか動作確認していません。必要に応じて、待機時間などを調整してください。
 *   ★万が一、色違いから逃げても操作が狂ってボールを投げても筆者は当然責任を負いません。よろしくお願いしますね。
 *   ★第三世代での色違い出現確率は1/8192です。第六世代以降の半分です。めっちゃ出にくいですよ!
 *   (参考まで1試行あたり約27.2秒なので、8192試行行う場合は、27.2秒×8192≈61.9時間(約2.6日)になります)※注意:8192試行しても、出現する確率は約63.2%です。出ないときは出ません。祈ってください!
 *   (確率的に、色違い遭遇率が90%を超えるのは18,863回目で、時間にすると142.5時間です。沼ですねぇ笑)
 *   (でも、そこまでしても色違いが欲しい!という気持ちは理解できます。一緒に頑張りましょう)
 *   
 *  (c) 2026 ますたーの忘備録
 *  https://tangential-star.hatenablog.jp/
 */

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

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

// ★「あまいかおり」を覚えたポケモンが手持ちの何匹目かを指定↓
const int AMAI_KAORI = (1);  // 手持ち先頭:「1」~ 最後尾:「6」

// ★手持ちポケモンが何匹いるかを指定↓
const int TEMOCHI_NUM = (6); // 手持ちポケモンが6匹なら「6」

// ★手持ちポケモン「プレッシャー」など、戦闘開始時に発動・表示されるとくせいがある場合は(1)にする。
const int hasAbility = (0);    // *未検証です。
const int AbilityTime= (1200); // *特性の発動にかかる待機時間を正確に入力[ミリ秒](~はプレッシャーをはなっている! など)

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

// ボタン押しラッパー関数
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 setup() {
  for(int i=0;i<3;i++)PushKey("B", HOLDTIME, 300); // Bボタンを3回押してSwitchに認識されるのを待つ
  PushKey("B", HOLDTIME, 300); // Bを押しておく。
  delay(1000);
}

// 草むらの上などでスタート
void loop() {

  // ■フィールドで「あまいかおり」を使う
  useSweetScent(AMAI_KAORI);

  // あまいかおり エフェクト~「あ! やせいの ●●が とびだしてきた!▼」まで待機
  delay(9300);

  // ■戦闘に入る
  // あ! やせいの ●●が とびだしてきた!▼
  PushKey("A", HOLDTIME, 10); // [色違いとの戦闘画面2回目:→つかう]
  // ゆけっ! ●●!!
  delay(2800);

  // もし「プレッシャー」等に対応させる場合はここに記載
  if( hasAbility ){ // *未対応&未検証
    delay(AbilityTime);
  }

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

  // この時点で[色違いとの戦闘画面1回目:●●が とびだしてきた!▼]
  // [色違いとの戦闘画面2回目:→やめる]
  PushKey("B", HOLDTIME, 300);  // [色違いとの戦闘画面1回目:ゆけっ! ●●!!][色違いとの戦闘画面2回目:道具にカーソル]
  PushKey("B", HOLDTIME, 2800); // [--(ポケモン繰り出し中)][色違いとの戦闘画面2回目:バッグを閉じて戦闘画面に戻る]

  // もし「いかく」「プレッシャー」等に対応させる場合はここに記載
  if( hasAbility ){ // *未対応&未検証
    delay(AbilityTime);
  }

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

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

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

  // フィールドに戻る [色違いとの戦闘画面:●●はどうする? →バッグ]

  
}


int useSweetScent(int who_can_use){
  if(who_can_use <= 0 || who_can_use > 6) return 0;
  int lpcnt;
  PushKey("X",HOLDTIME, 800); // ★メニューを開く [色違いとの戦闘画面:なにもしない]
  PushKey("right",HOLDTIME, 30); // ダミー入力 [色違いとの戦闘画面:→バッグ]
  
  PushKey("A",HOLDTIME, 1600); // ★「ポケモン」を開く [色違いとの戦闘画面:バッグが開く]

  // ★カーソルをあわせる(上入力を必ず入れておきたいので逆順で処理) [色違いとの戦闘画面:バッグの1番上にカーソル]
  for(lpcnt = (TEMOCHI_NUM+2); lpcnt > who_can_use ; lpcnt-- ){ 
    PushKey("Up",HOLDTIME, 100); // ↑を押しまくる
  }

  PushKey("A",HOLDTIME,    500); // ★→つよさをみる [色違いとの戦闘画面:→つかう バッグ1番目]
  PushKey("Down",HOLDTIME, 400); // ★→あまいかおり [色違いとの戦闘画面:→やめる バッグ1番目]
  PushKey("A",HOLDTIME,    10); // ★(あまいかおりを使う) [色違いとの戦闘画面:バッグの1番目にカーソル]

  return lpcnt;
}


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;
}

 

6.動作確認

無事に17時間42分の放置の末、筆者FRLG初の色違いポケモンとして「色違いのニャース」に出会うことができました!1試行当たり約27.2秒ですから、推定2,343回で、めちゃくちゃ運が良いです。

ちなみに、筆者はこのプログラムを使って、計4匹のポケモンの色違い遭遇を実現しています。それなりに信頼性はあると思いますが、あくまでも「自己責任」で利用いただければと思います。

17時間42分の放置で、無事に色違いのニャースに出会うことができた

ついに出会えた色違いのニャース!かわいいぞ!
FRLGでの色違いは、ステータス画面の枠が水色になって、右上に小さな星が付くのだ

 

7.あとがき

今回は、前回(序盤の金策)に引き続き、FRLG自動化第2弾の記事として、野生ポケモンの色厳選を自動化しました!やっぱり「色違い」集めは楽しいですよね~!

個人的には昨日から鼻風邪を引いてしまい、安静にしなきゃと思いつつも、ずっと回し続けていたこの色厳選が「成功」してしまったので、その喜びに乗った勢いで記事を執筆しました。

しかも、色厳選に丸3日ほどかかると想像していただけに、運よく17時間42分で色違いに出会えた喜びはひとしおで、結局シナリオを未だ進めることなく他のポケモンの色違い厳選に取り組んでいます(プレイ時間は130時間超なのに、まだバッジは3個…笑)。

今ではニャースのほかに、ポッポ・サンド・オニスズメを加えた計4匹を捕まえられたので、大満足です!(ただ、1章にも書いた通り、第三世代の色厳選は本当に大変なので、色違いを出すことを目的にせず、ポケモンを楽しむ目的で色厳選とうまく付き合うと良いと思います)。私も色厳選はほどほどにしてシナリオを進めていきたいと思います。

筆者はこのプログラムで4匹のポケモンの色違いと出会うことができた!(再掲)

 

ところで、先日のPokémon Presents 2026.2.27、とっても良かったですね!改めてYouTubeのアーカイブ動画も視聴しましたが、ついに第10世代のポケモンとして「ウインド」「ウェーブ」が発表されましたし、昨日3/5からは「ぽこ あ ポケモン」も発売されましたし、ポケモン界隈は大いに盛り上がっていますね!

一方でそれと時を同じくして、今回のブログでも取り扱った「ファイアレッド・リーフグリーン」のSwitch版が発売されたり、ポケモンのスマホゲーム「ポケモンマスターズEX」では6.5周年記念で、杉森建さんが当時に描いていた絵を再現した「レッド(1996)」が参戦したりと、平成当時のポケモンも感じられる数々の展開があり、30周年という節目として胸熱です。

特に、私は第三世代が本当に大好きだったので、この、昔のポケモン作品をリバイバルする流れはとても喜ばしく感じています!(本ブログでも過去には、ゲームキューブ「ポケモンコロシアム」100人抜きを自動化してみたり、DS Liteを改造して「エメラルド版」みなみのことうミュウの色厳選を自動化してみたり、いろいろやっていました。…が、一応、Switch自動化専門ブログを運営している身としては、やはり嬉しいですね!)

 

ともかく、引き続きFRLGのシナリオを進めて、また自動化できそうなものがあれば更新していけたらと思いますので、本ブログを引き続きよろしくお願いいたします!

あと、この記事で初めて私のブログをご覧いただいた方、ここまで読んでいただき本当にありがとうございます!こんな感じで、文字多め・GIF動画多めのブログなので、よければ他の記事も読んでみてください!

 

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

 

 

前回の記事:【FRLG自動化01】ゴールデンボールブリッジきんのたま回収【序盤金策】

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


--

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

 

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

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

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

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

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

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

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

 

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

www.youtube.com

 

 

*1:FRLGで手に入る「イーブイ」の進化先としてエーフィやブラッキーなどがいますが、RSEでは時間が流れているので進化することができるのに対し、FRLGだけでは進化させることができません。ここから考えると、全国図鑑モードがあるFRLGがSwitchで発売されたことから、RSEが登場することが仮説として自然に成り立ちます




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

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