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

デオキシスとの追いかけっこと、色違いじゃなかったら逃げるを繰り返す。
1試行あたりジャスト1分なので、試行回数が把握しやすいのだ
目次です。今回の手順も、サンダー・フリーザー・ファイヤーの色厳選とほぼ一緒の流れです。
※先にサンダーの色厳選をみておくことをおすすめします(見なくても理解はできます)。
tangential-star.hatenablog.jp
0.成功報告
筆者は192時間19分04秒の放置、11,539試行目で色違いのデオキシスに会えました。8日と19分ですね。長かった…。

筆者は無事に色違いのデオキシスと遭遇できた。追いかけっこも楽しい。
かかった時間は192時間19分(=11,539分)。つまり、11,539試行だ(1試行=1分)
1.デオキシスに会うには「でんどういり」と「3のしま」攻略が必要
ご存知の通り、デオキシスは「たんじょうのしま」という孤島に生息しています。
まずは「たんじょうのしま」に行くための準備(デオキシスとの出会い方)について紹介します。
1-1.まずは「でんどういり」で「オーロラチケット」を入手
「たんじょうのしま」に行くには、クチバシティから船に乗っていく必要があるのですが、この際に必要になるのが「オーロラチケット」です。
Switch版のFRLGでは「でんどういり」をするだけでオーロラチケットを入手できます*2。
でんどういりすると、いつの間にか「オーロラチケット」がバッグに入っているのだ
ちなみに、GBA版(当時)のFRLGでは、作中での入手方法は無く、当時の映画「劇場版ポケットモンスター アドバンスジェネレーション 裂空の訪問者 デオキシス」の前売り券での配布でのみ入手することができました。懐かしい…。
1-2.続いてニシキの依頼で「ルビー」と引き換えに「レインボーパス」を入手
さて、前節の「オーロラチケット」があれば無条件で「たんじょうのしま」へ連れて行ってくれるわけではありません。
「たんじょうのしま」は「6のしま」の近くにある孤島ですから、「1のしま」~「3のしま」にしか行けない「トライパス」しか持っていない状態では、そもそも資格がないのです。言い換えれば、「4のしま」~「7のしま」まで行くことができる「レインボーパス」を持っている必要もあるのです。
でんどういり後、図鑑の「つかまえたかず」が60匹以上であればオーキド博士にポケモン図鑑を「ぜんこくずかん」にしてもらえますが、それを条件として、「1のしま」にいるニシキという人物から「レインボーパス」を受け取ることができます。
より具体的には、ニシキに話しかけてネットワークマシンを作るために石を探している旨を聞き出してから、その状態で「ともしびやま」の右側外壁にある、ロケットだんが空けた横穴を探索することで「ルビー」を手に入れることができます。
このルビーをニシキに渡すと、今度は「対になる石(サファイア)」を探してほしい、と依頼され、その際に「4のしま」~「7のしま」に行くことができる「レインボーパス」を受け取ることができます。

「1のしま」のポケモンネットワークセンターにいるニシキからお願いを聞こう。
ネットワークマシン完成のため「1のしま」のどこかにある「とくべつな いし」が必要らしい
ニシキの話を聞いたら「1のしま」北東に位置する「ともしびやま」の最奥を目指そう。
最奥では「ルビー」を拾うことができるのだ。これをニシキに届けてあげよう

ニシキに「ルビー」を渡すと「レインボーパス」を受け取ることができるのだ。
「追加で石を探してこい」とナチュラルに依頼するニシキの図々しさが際立つ場面でもある
2.FRLG版(Switch版)のデオキシスはマップ切り替えで復活する
前章で「レインボーパス」と「オーロラチケット」を入手して「たんじょうのしま」に上陸できるようになりましたので、本章ではデオキシスの色厳選の手順についてです。
結論から言うと、サンダー・フリーザー・ファイヤーと同様の手順です。
つまり、Switch版FRLGにおけるデオキシスは「にげる」で戦闘終了後、マップを切り替えることで復活しますので、リセット不要の下記手順で色違い厳選できます。
【デオキシスの色厳選の手順】
- 島の中央にある黒い三角形(▲)に「A」ボタンで話しかける
- 黒い三角形が移動するので、最短経路で10回追いかける
- 10回目になると三角形(▲)が真っ赤になる
- その状態で「A」ボタンで話しかけると戦闘になる
- デオキシスの色を確認する。
- 色違いでなければ、「にげる」を選んで戦闘を終える
- 「デオキシスは どこかへ とびさって いった!」となる
- 一度、船着き場まで戻り、もう一度「たんじょうのしま」に上陸する
- 黒い三角形(▲)が復活している
- 再び黒い三角形(▲)に話しかける
- 手順2に戻る

色違いじゃなかったらデオキシスから逃げて、船着き場を経由すると復活するぞ
3.自動化のためにゴールドスプレー所持が必須
今回のデオキシスの色厳選は、ファイヤーの色厳選と同様、野生ポケモンが出現しないエリアのため、スプレー系のアイテムを使う必要はありません。
ただし、本ブログで扱う自動化では戦闘中に、バッグの一番上のゴールドスプレーを「色違いの判定」のために使います。必ずカーソルをあわせておいてください。
1個あれば十分です。もし、どうしてもゴールドスプレーが用意できない場合は、代わりにふしぎなアメなどの戦闘中に使えないアイテムを一番上においてください。

デオキシスの色厳選ではサンダーやフリーザーとは違い「ゴールドスプレー」は不要だ。
(ただし、自動化の際にはバッグの1番上はゴールドスプレーにしておこう)
4.ソースコード
今回は、「たんじょうのしま」にいるデオキシスの色厳選を、Arduino Leonardoで自動化しました。今回の時間効率は、1分=1試行(1時間60試行、1日1,440試行)です。1分の重みを感じられる自動化ですね。
4-1.自動化準備(ゲーム側の準備)
まず「たんじょうのしま」に上陸しておきます。三角形(▲)のすぐ下のマスに立って、Aを押したら追いかけっこが始まる状態(主人公が上を向いている状態)にします。

「たんじょうのしま」の中央には謎の黒い三角形がある。
主人公はその手前に立った状態にしておこう
ちなみに、デオキシスはレベル30ですが、意外と素早いので、十分なすばやさを持つポケモンを先頭にしておきましょう。
余談ですがファイアレッドとリーフグリーンでは、バージョンによってデオキシスのすばやさが違います!実数値でFRで114、LGで74となります(見た目は同じ「ノーマルフォルム」ですが、ファイアレッドでは「アタックフォルム」、リーフグリーンでは「ディフェンスフォルム」になる仕様のため)。
そのため、先頭ポケモンは目安として115以上のすばやさを持つポケモンにしておきましょう。
設定については、今までと同様に、「はなしの はやさ」を「はやい」、「せんとう アニメ」は「みない」、「ボタンモード」は「LR」にしてください。
そして、バッグの一番上には「戦闘中に使えないどうぐ」を並び替えて、それにカーソルを合わせた状態でメニューを閉じてください(ゴールドスプレーでOKです)。
※戦闘中に「バッグ」を開いてAを押す挙動があるため、使えるどうぐにカーソルが当たっていると色違い遭遇後に想定外の挙動を起こしてしまいます。
必ず「ボタンモード」を「LR」にして、「はなしのはやさ」を「はやい」にして、「バッグ」の一番上に「戦闘中に使えないどうぐ」を準備してカーソルを合わせておこう
4-2.動作が時々ズレますが仕様です
ソースコードの冒頭にも書いていますが、追いかけっこ時に1マス足りない挙動を時々起こすことがありますが、仕様です(問題なくループします)。筆者はこの挙動を含めて141時間の連続稼働を目視確認(録画)しています。

今回の自動化では、追いかけっこの途中で1マス分の上移動が足りなくなる場合がある
4-3.ソースコード全文
ソースコードの全文です。コード冒頭の注意事項もよく読んで利用してください。
#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);
void setup() {
for(int i=0;i<3;i++)PushKey("B", HOLDTIME, 300);
PushKey("B", HOLDTIME, 300);
delay(1000);
}
void loop() {
PushKey("A", HOLDTIME, 100);
SwitchControlLibrary().PressButtonB();
PushKey("down", 200, 0);
PushKey("left", 405, 20);
SwitchControlLibrary().ReleaseButtonB();
delay(150);
PushKey("A", HOLDTIME, 100);
SwitchControlLibrary().PressButtonB();
PushKey("right", 500, 0);
PushKey("up", 650, 20);
SwitchControlLibrary().ReleaseButtonB();
delay(150);
PushKey("A", HOLDTIME, 100);
SwitchControlLibrary().PressButtonB();
PushKey("down", 750, 0);
PushKey("right", 405, 20);
SwitchControlLibrary().ReleaseButtonB();
delay(150);
PushKey("A", HOLDTIME, 1600);
PushKey("B", HOLDTIME, 1600);
SwitchControlLibrary().PressButtonB();
PushKey("left", 800, 0);
PushKey("up", 402, 303);
PushKey("left", 120, 20);
SwitchControlLibrary().ReleaseButtonB();
delay(150);
PushKey("A", HOLDTIME, 100);
SwitchControlLibrary().PressButtonB();
PushKey("right", 600, 20);
SwitchControlLibrary().ReleaseButtonB();
delay(150);
PushKey("A", HOLDTIME, 100);
SwitchControlLibrary().PressButtonB();
PushKey("left", 300, 0);
PushKey("down", 300, 20);
SwitchControlLibrary().ReleaseButtonB();
delay(150);
PushKey("A", HOLDTIME, 100);
SwitchControlLibrary().PressButtonB();
PushKey("down", 50, 0);
PushKey("left", 405, 20);
SwitchControlLibrary().ReleaseButtonB();
delay(500);
PushKey("B", HOLDTIME, 1600);
PushKey("A", HOLDTIME, 100);
SwitchControlLibrary().PressButtonB();
PushKey("right", 900, 20);
SwitchControlLibrary().ReleaseButtonB();
delay(500);
PushKey("B", HOLDTIME, 1600);
PushKey("A", HOLDTIME, 100);
SwitchControlLibrary().PressButtonB();
PushKey("left", 500, 0);
PushKey("down", 120, 20);
SwitchControlLibrary().ReleaseButtonB();
delay(500);
PushKey("B", HOLDTIME, 1600);
PushKey("A", HOLDTIME, 100);
SwitchControlLibrary().PressButtonB();
PushKey("up", 500, 20);
SwitchControlLibrary().ReleaseButtonB();
delay(500);
PushKey("B", HOLDTIME, 1600);
PushKey("A", 100, 1600);
PushKey("B", 100, 1600);
PushKey("up", 100, 50);
PushKey("right", 100, 50);
PushKey("A", 100, 1600);
PushKey("A", 100, 100);
delay( 13700 - (100+1600+100+1600+100+50+100+50+100+1600+100+100) );
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);
PushKey("X", 100, 100);
PushKey("left", 50, 50);
PushKey("B", 50, 100);
SwitchControlLibrary().PressButtonB();
PushKey("down", 2720, 0);
SwitchControlLibrary().ReleaseButtonB();
delay(1000);
SwitchControlLibrary().PressButtonB();
PushKey("up", 3300, 0);
SwitchControlLibrary().ReleaseButtonB();
delay(1000);
}
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;
}
5.動作確認
丸8日間(192時間!)の苦行の末、ようやく色違いのデオキシスと無事に遭遇できました。試行回数は11,539試行でした。
試行11,539回目にして色違いのデオキシスに出会うことができた。
ニックネームは「でおでお」にしたぞ
6.あとがき
丸8日間もかかりましたが!ついに!無事に幻のポケモン・デオキシスも捕まえることができました!やったぁぁ!
自分がリーフグリーンを遊んでいるのをすっかり忘れていて、「ディフェンスフォルム」になった姿を見て、あれ、なんで??と一瞬なりました(笑)
いつかファイアレッドでも遊んで、「アタックフォルム」の色違いの姿も目に焼き付けたいです(笑)

デオキシスを捕獲すると、バージョンに合わせてフォルムが変わるのだ。
ファイアレッドは「アタックフォルム」、リーフグリーンは「ディフェンスフォルム」だ

これでサンダー・ファイヤー・フリーザー・デオキシスの色違いがボックスに並んだ!
それはともかく、幼少期時代の悲願が叶いました。本当に嬉しい!!!
当時を思い返すと、FRLGではコントローラ操作を自動化できるなんて想像もしていませんでしたから、色違いの厳選なんて諦めていました。
今回はSwitch版でFRLGが復刻という話を聞いて、もしかしたら「オーロラチケット」配布があるのかも?と楽しみにしており、実際にでんどういりをした人から「バッグに入っている」というツイートを見たときには、とても喜んだことを覚えています(まさか「しんぴのチケット」も一緒に貰えるとは思っていませんでしたが)。
その情報が入るやいなや、私も色厳選の自動化をいつか組みたいなと思っていて、野生ポケモンの色違い厳選を作ってから早105日経ってしまったものの、今回ようやく「デオキシス」の自動厳選を成功させることができました。
これでサンダー・フリーザー・ファイヤーの3匹と合わせて4匹の伝説・幻ポケモンの色違いを手に入れることができて、幸せハッピーです。
この記事で皆様にも幸せのおすそ分けができたらなと思います!!(成功したらぜひとも報告いただければと思います!)
余談だが、ステータス確認画面だと、デオキシスだけは左向きなのだ。
恐らく、ノーマルフォルムのドット絵が左右非対称のポケモンだからだろう
さて。これで無事にデオキシスの色違い厳選が完了したので、次は…ホウオウやルギアにもチャレンジしてみたいです!
というのも、当時は「たんじょうのしま」には上陸したことがあったのですが、「しんぴのチケット」は受け取った記憶がなく、恐らく上陸したことがなかった…気がするのです(もしかしたら上陸したら思い出すかもしれませんが…)。
いずれにしても、自動化を組めたら、またこのブログで紹介できればと思います!
※この記事でArduino Leonardoを知った人はぜひとも導入記事を読んでください!
tangential-star.hatenablog.jp
引き続き、本ブログ記事がみなさまのお役に立てたらと思いますし、皆様のコメントも、本ブログ運営の励みになっております。これからも温かく見守っていただければ幸いです。
これからも、Arduino LeonardoでFRLG自動化にチャレンジしていきますので、今後とも、どうぞよろしくお願いいたします!
ではではc⌒っ.ω.)っ
前回の記事:【FRLG自動化07】色違いファイヤー厳選【ともしびやま】
(FRLGの記事一覧はこちらから→ ポケモンFRLG自動化 カテゴリーの記事一覧)
--
本ブログについて:本ブログについて
Arduino導入記事:【Arduino自動化01】Arduino開発環境の導入
ポケモン剣盾の記事:ポケモン剣盾Arduino自動化 カテゴリーの記事一覧
ポケモンBDSPの記事:ダイパリメイクArduino自動化 カテゴリーの記事一覧
レジェンズアルセウスの記事:レジェンズアルセウスArduino自動化 カテゴリーの記事一覧
スカーレット・バイオレットの記事:スカーレットバイオレットArduino自動化 カテゴリーの記事一覧
レジェンズZ-Aの記事:レジェンズZA自動化 カテゴリーの記事一覧
ポケモンFRLGの記事:ポケモンFRLG自動化 カテゴリーの記事一覧
YouTubeチャンネル:ますたーの忘備録 - YouTube
www.youtube.com