こんにちは。ますたーです。
今回はFRLG自動化の第7弾として、準伝説ポケモン・ファイヤーの色厳選を自動化しました。
※一般ポケモンの色厳選はこちら→【FRLG自動化02】野生ポケモン色違い厳選【あまいかおり】
※サンダーの色厳選はこちら→【FRLG自動化04】色違いサンダー厳選【むじんはつでんしょ】
※フリーザーの色厳選はこちら→【FRLG自動化06】色違いフリーザー厳選【ふたごじま】
※デオキシスの色厳選はこちら→【FRLG自動化08】色違いデオキシス厳選【たんじょうのしま】
なお、Arduino Leonardo自動化の導入・機材構成については導入記事を参考にしてください。
導入記事:【Arduino自動化01】Arduino開発環境の導入
※本ブログに初めてお越しの方は「本ブログについて」もぜひ、ご覧ください。
概要
今回は、準伝説ポケモン・ファイヤーの色厳選を自動化しました。
1試行あたり約43.6秒で、ざっくり12時間で約1,000回(990回)、丸1日放置で1,981回の色厳選が行えます。

ともしびやまの頂上を行き来して、ファイヤーが色違いじゃなかったら逃げるを繰り返す。
「かいりき」の部分も含めて自動で操作してくれるぞ。1試行あたり約43.6秒だ。
目次です。今回の手順・内容はサンダーの色厳選や、フリーザーの色厳選とほぼ一緒なので、あっさり!
※先にサンダーの色厳選をみておくことをおすすめします(見なくても理解はできます)。
tangential-star.hatenablog.jp
0.成功報告
筆者は延べ37時間37分53秒の放置、3,107試行目で色違いのファイヤーに会えました。

筆者は無事に色違いのファイヤーと遭遇できた。
37時間37分53秒、わずか3,107試行で出会うことができた
今回の自動化は、「ゴールドスプレー」も不要ですし、1試行もおおよそ43.6秒でフリーザーと比べても短いので、割と安定します。
1.FRLG版(Switch版)のファイヤーはマップ切り替えで復活する
サンダーの色厳選やフリーザーの色厳選でも紹介している通り、Switch版のポケモンFRLGでは、伝説・幻ポケモンの固定シンボルは「にげる」で戦闘を離脱すると、マップを切り替えることで復活するようになっています。
すなわち、A,B,X,Yの同時押しによるタイトルリセット(いわゆる固定リセット)を行うことなく色違いの厳選ができる、ということです。
今回のファイヤーの色厳選の自動化においても、この方法でやっていきます。
【ファイヤーの色厳選の手順】
- 「A」ボタンでファイヤーに話しかける
- ファイヤーの色を確認する。
- 色違いでなければ、「にげる」を選んで戦闘を終える
- 「ファイヤーは どこかへ とびさって いった!」となる
- ともしびやまの頂上を出て、もう一度山頂に行く
- 「かいりき」で岩をどかして最奥に行く
- ファイヤーの固定シンボルが復活している
- 再びファイヤーに話しかける
- 手順3に戻る

Switch版のFRLGでは、三鳥は逃げてもマップを切り替えれば復活する。
つまり、A,B,X,Y同時押しのタイトルリセットを行う必要は無いのだ
2.ファイヤーの色厳選にゴールドスプレーは不要だが、要所持
本ブログでは過去にサンダーの色厳選や、フリーザーの色厳選を紹介してきましたが、サンダー・ファイヤーはダンジョン内に生息しているため野生ポケモンとの遭遇が大きな懸念でした。そこで、「ゴールドスプレー」を使って野生ポケモンと遭遇しないようにする必要がありました。
一方で、三鳥の中でもファイヤーに限っては野生ポケモンが出現しない場所に生息しているため、ゴールドスプレーを使う必要はありません。
ただし、本ブログで扱う自動化では「色違いの判定」のために戦闘中にバッグの一番上のゴールドスプレーを使います*1。
バッグの一番上に置いておいてください。1個あれば十分です。

ファイヤーの色厳選ではサンダーやフリーザーとは違い「ゴールドスプレー」は不要だ。
(ただし、自動化の際にはバッグの1番上はゴールドスプレーにしておこう)
3.ソースコード
今回は、「ともしびやま」の山頂にいるファイヤーの色厳選を、Arduino Leonardoで自動化しました。時間効率は、約1時間で82試行(1試行あたり43.6秒)です。
3-1.自動化準備(ゲーム側の準備とソース修正)
まず、プレイヤーの位置ですが、「ともしびやま」最奥のファイヤーのすぐ下のマスに立って、主人公は上を向いている状態にします(Aを押したらそのまま戦闘に入れる状態)。
「せってい」としては、「はなしの はやさ」「せんとう アニメ」「ボタンモード」をそれぞれ「はやい」「みない」「LR」にしてください。
最後に、バッグの一番上に「戦闘中に使えないどうぐ」を並び替えて、それにカーソルを合わせた状態でメニューを閉じてください(ゴールドスプレーでOKです)。
※戦闘中に「バッグ」を開いてAを押す挙動があるため、使えるどうぐにカーソルが当たっていると色違い遭遇後に想定外の挙動を起こしてしまいます。

必ず「ボタンモード」を「LR」にして、「はなしのはやさ」を「はやい」にしておこう

「バッグ」の一番上に「戦闘中に使えないどうぐ」を準備してカーソルを合わせよう。
戦闘中に使えないどうぐなら何でもOKだ。ゴールドスプレーなどが良いだろう

ファイヤーのすぐ下の位置で上を向けば、準備完了だ。
念のため、この状態でセーブしておこう
3-2.ソースコード全文
ソースコードの全文です。コード冒頭の注意事項もよく読んで利用してください。
#include <SwitchControlLibrary.h>
#define HOLDTIME (95)
#define SWITCH_VER (20)
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);
const int UP = 0;
const int RIGHT= 2;
const int DOWN = 4;
const int LEFT = 6;
const int NONE = 8;
void setup() {
for(int i=0;i<3;i++)PushKey("B", HOLDTIME, 300);
PushKey("B", HOLDTIME, 300);
delay(1000);
}
void loop() {
PushKey("A", HOLDTIME, 1700);
PushKey("A", HOLDTIME, 10);
delay(5180);
PushKey("A", HOLDTIME, 100);
PushKey("A", HOLDTIME, 100);
delay(2700);
PushKey("right",HOLDTIME, 20);
PushKey("down", HOLDTIME, 20);
delay(2100);
PushKey("B", HOLDTIME, 300);
PushKey("B", HOLDTIME, 2800);
PushKey("A", HOLDTIME, 1100);
PushKey("B", HOLDTIME, 4200);
PushKey("B", HOLDTIME, 300);
SwitchControlLibrary().PressButtonB();
SwitchControlLibrary().MoveHat(DOWN );
delay(500);
SwitchControlLibrary().MoveHat(NONE );
SwitchControlLibrary().MoveHat(LEFT );
delay(100);
SwitchControlLibrary().MoveHat(NONE );
SwitchControlLibrary().MoveHat(DOWN );
delay(500);
SwitchControlLibrary().MoveHat(NONE );
SwitchControlLibrary().MoveHat(RIGHT);
delay(100);
SwitchControlLibrary().MoveHat(NONE );
SwitchControlLibrary().MoveHat(DOWN );
delay(800);
SwitchControlLibrary().MoveHat(NONE );
SwitchControlLibrary().ReleaseButtonB();
delay(1000);
PushKey("up", 2400, 100);
PushKey("A",HOLDTIME, 1200);
PushKey("B",HOLDTIME, 1200);
PushKey("A",HOLDTIME, 2900);
PushKey("B",HOLDTIME, 950);
PushKey("B",HOLDTIME, 300);
PushKey("right",160, 200);
PushKey("up", 1030, 100);
PushKey("left", 1030, 100);
PushKey("up", 160, 200);
PushKey("left", 1030, 100);
PushKey("up", 1030, 100);
PushKey("left", 160, 200);
PushKey("up", 160, 200);
PushKey("right",1800, 500);
PushKey("up", 800, 300);
}
void die(void){
for(;;) delay(100);
}
int PushKey(char* keyname, int holdtime, int delaytime){
if(strlen(keyname)==1){
switch(keyname[0]){
case 'A': case 'a':
SwitchControlLibrary().PressButtonA(); delay(holdtime);
if(holdtime>0)SwitchControlLibrary().ReleaseButtonA(); delay(delaytime);
break;
case 'B': case 'b':
SwitchControlLibrary().PressButtonB(); delay(holdtime);
if(holdtime>0)SwitchControlLibrary().ReleaseButtonB(); delay(delaytime);
break;
case 'X': case 'x':
SwitchControlLibrary().PressButtonX(); delay(holdtime);
if(holdtime>0)SwitchControlLibrary().ReleaseButtonX(); delay(delaytime);
break;
case 'Y': case 'y':
SwitchControlLibrary().PressButtonY(); delay(holdtime);
if(holdtime>0)SwitchControlLibrary().ReleaseButtonY(); delay(delaytime);
break;
case 'L': case 'l':
SwitchControlLibrary().PressButtonL(); delay(holdtime);
if(holdtime>0)SwitchControlLibrary().ReleaseButtonL(); delay(delaytime);
break;
case 'R': case 'r':
SwitchControlLibrary().PressButtonR(); delay(holdtime);
if(holdtime>0)SwitchControlLibrary().ReleaseButtonR(); delay(delaytime);
break;
case 'H': case 'h':
SwitchControlLibrary().PressButtonHome(); delay(holdtime);
if(holdtime>0)SwitchControlLibrary().ReleaseButtonHome(); delay(delaytime);
break;
case '+': case 'p': case 'P':
SwitchControlLibrary().PressButtonPlus(); delay(holdtime);
if(holdtime>0)SwitchControlLibrary().ReleaseButtonPlus(); delay(delaytime);
break;
case '-': case 'm': case 'M':
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':
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':
SwitchControlLibrary().MoveHat(2); delay(holdtime);
if(holdtime>0)SwitchControlLibrary().MoveHat(8); delay(delaytime);
break;
case 'l': case 'L':
SwitchControlLibrary().MoveHat(6); delay(holdtime);
if(holdtime>0)SwitchControlLibrary().MoveHat(8); delay(delaytime);
break;
case 'u': case 'U':
SwitchControlLibrary().MoveHat(0); delay(holdtime);
if(holdtime>0)SwitchControlLibrary().MoveHat(8); delay(delaytime);
break;
case 'd': case 'D':
SwitchControlLibrary().MoveHat(4); delay(holdtime);
if(holdtime>0)SwitchControlLibrary().MoveHat(8); delay(delaytime);
break;
case 'H': case 'h':
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){
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){
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;
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;
}
4.動作確認
プログラムは安定しており、37時間37分53秒間の放置を確認できました(3,107試行)。
無事にファイヤーの色違いにも遭遇することができました。
無事に3,107試行目で色違いのファイヤーに出会うことができた。
ニックネームは「もえもえ」にしたぞ
5.あとがき
これで無事に三鳥の色違いが揃いました!長かった~~!
読者のみなさまにも、自動化ソースコードで幸せのおすそ分けができるんじゃないかな、と思います!(ぜひとも色違い厳選を、Arduino Leonardoで試してみていただければと思います!)
無事に三鳥トリオを色違いで揃えることができた。
さんさん・ふりふり・もえもえの3匹は大事にしていくぞ
ところで、筆者のFRLGのストーリー進捗状況ですが、ついに!さきほど!ようやく四天王をクリアしました!!やった~~!
FRLGは、エンディングの演出も大好きなんですよね!今まで歩いてきた街々を、振り返って歩いていくさまがエンドロールで流れていく…エモすぎる~~!

四天王を倒し、遂にでんどういり!エンディングも感動の演出だった…
余談ですが、この時点のエンドロールに「てんじ かんしゅう にっぽんてんじとしょかん」の文字があるのは、なんだかすごくエモいですよね。
というのも、FRLGではエンディングに至るまでは、「1のしま」~「3のしま」までの冒険は追加されているものの、基本的には初代の冒険と基本的に変わらないため、この時点では点字が出る要素が無いのです。
つまり、ここに「点字監修」という文字があるだけで、エンドロール「以降」に何かしら点字の要素が登場することがわかります(きっと、今までFRLGを遊んだことがなかった人は、エンディング後に「4のしま」~「7のしま」の冒険があることについて驚いたのではないでしょうか)。
もっとも、FRLGの箱の中には点字一覧表が説明書と別についてましたし、ポケモンRSを先に遊んでいる筆者としては、当時FRLGで点字が出ることには何の疑問も持たなかったですがね…。

エンディングのスタッフロールの一コマ。おわかりいただけただろうか…。
この時点では「点字」は登場していないが、日本点字図書館による監修の文字がある。
これからの冒険に期待が高まる演出だ…!
⠾⠎⠐⠪⠞⠇⠄ ⠃⠷⠐⠡⠁⠙ (ものごとにわ いみがある)
さらに、エンドロールを終えて「つづきからはじめる」と、マサラタウンに帰った主人公にオーキド博士が話しかけてくれます。その時、ポケモンずかんの「つかまえたかず」が60匹以上だと、ずかんを全国図鑑モードにアップデートしてくれます。
ようやく私も新しい冒険に出ることができます!
エンドロールが終わって続きから始めると、新しい冒険が始まるのだ…!
(めちゃくちゃエモい~~~)
さてさて、話が逸れてしまいました。
本ブログではFRLG自動化の中でも、野生ポケモンと三鳥の色厳選を紹介してきましたが、引き続き色厳選には挑戦していきたいと思っています。
でんどういりすることで、バッグの中の「たいせつなもの」ポケットには「オーロラチケット」「しんぴのチケット」が追加されますが、これがあればデオキシスやホウオウ、ルギアに出会うことができます(むしろ、これが目当てでSwitch版のFRLGを遊んだと言っても過言じゃありません)。
まずはクチバシティに行ってシナリオを進めつつ、彼らの色厳選にもチャレンジしていきたいと考えています。
でんどういりするとバッグの中に「オーロラチケット」「しんぴのチケット」が増えている。
これがあれば、へそのいわ・たんじょうのしまに行くことができるのだ
引き続き、Arduino LeonardoでFRLG自動化にチャレンジしていきますので、これからも本ブログを応援いただければと思います!(みなさまの応援のコメントは、本当に支えになっています!)
皆様のファイヤーの厳選を含む、色違い厳選の成功報告なんかもお待ちしています!
ではではc⌒っ.ω.)っ
前回の記事:【FRLG自動化06】色違いフリーザー厳選【ふたごじま】
次回の記事:【FRLG自動化08】色違いデオキシス厳選【たんじょうのしま】
(FRLGの記事一覧はこちらから→ ポケモンFRLG自動化 カテゴリーの記事一覧)
--
本ブログについて:本ブログについて
Arduino導入記事:【Arduino自動化01】Arduino開発環境の導入
ポケモン剣盾の記事:ポケモン剣盾Arduino自動化 カテゴリーの記事一覧
ポケモンBDSPの記事:ダイパリメイクArduino自動化 カテゴリーの記事一覧
レジェンズアルセウスの記事:レジェンズアルセウスArduino自動化 カテゴリーの記事一覧
スカーレット・バイオレットの記事:スカーレットバイオレットArduino自動化 カテゴリーの記事一覧
レジェンズZ-Aの記事:レジェンズZA自動化 カテゴリーの記事一覧
ポケモンFRLGの記事:ポケモンFRLG自動化 カテゴリーの記事一覧
YouTubeチャンネル:ますたーの忘備録 - YouTube
www.youtube.com