お久しぶりです。ますたーです。
今回は、BDSPの地下大洞窟での「ディグダ」探しを自動化しました。
ダイパリメイク自動化の記事、第5弾になります。3月最初の記事です。
なお、Arduino Leonardo自動化の導入・機材構成については導入記事を参考にしてください。
導入記事:【Arduino自動化01】Arduino開発環境の導入
※本ブログに初めてお越しの方は「本ブログについて」もぜひ、ご覧ください。
概要
キッサキシティの地下大洞窟で、ディグダを探し続けてくれる自動化です。40匹見つけて突入するボーナスタイムまでの放置にピッタリですね。一応、ソロだと15分ほど放置で、ディグダゲージが40まで溜まりました。オンラインに繋いだり、ローカルで複数台で自動化すると、より早くゲージが溜まります。
目次です。今回は超あっさりです。
ソースコードが欲しい方は、どうぞ→ ソースコードまで読み飛ばす。
色違いの石像を置くと、そのタイプのポケモンが出やすくなる
さて、まずは目的の整理です。ポケモンBDSP(ダイパリメイク)の一番の目玉といって過言でもないコンテンツが「地下大洞窟」です。
今作では、地上で「たんけんセット」を使うことで地下に潜ることができ、「大空洞」で野生のポケモンを捕まえたり、化石掘りを楽しんだり、自分の「ひみつきち」を作って石像を飾れたりできます。
前述の通り、地下大洞窟の「ひみつきち」では、ポケモンの石像を配置することができます。この石像をひみつきちに配置することで、地下空洞で出会えるポケモンの出現確率を変化させることができます。より具体的には、配置したポケモンの「タイプ」に該当するポケモンの出現割合が上昇します。
中でも、色違いの石像(全体的に緑色のもの)は、そのタイプの出現確率の上昇値が高くなるため、積極的に配置していきたいものになります。
ディグダゲージMAXだと「豪華な石の箱」の入手確率が大幅にアップ
ひみつきちで飾ることのできる石像の入手方法ですが、化石掘りで「きれいな いしのはこ」「ごうかな いしのはこ」を掘り出すことで手に入ります。後者の「ごうかな いしのはこ」は極稀に出土し、普段はなかなか入手が困難です。
ところが、左上のディグダゲージが40溜まり、いわゆるボーナスタイム(ディグダバーストとかゲージマックスとか呼び名は色々ありますが)に入ると「ごうかな いしのはこ」の出現確率は大きく跳ね上がります。
時間中なら、体感でも5~6個は安定して掘り出せるため、まさにボーナスタイムとなります。
おまけ:ディグダゲージMAXだと、野生ポケモンの色違い確率も倍に
余談ですが、ディグダゲージがMAXになると、地下大洞窟の部屋で出現するポケモンの色違いの出現確率が2倍になる、という報告もあります。通常の出現確率が1/4096なので、1/2048となる計算です。
ただし、ボーナスタイムはわずか4分しか継続しないため、地下大洞窟でポケモンの色違い厳選は、あまり効率的とは言えません。あくまでもおまけですかね。私はこの方法で色違い厳選をしたいとはあまり思えません。
どうしてもこの方法で色違い厳選をする場合は、先に石像を秘密基地において、狙いのポケモンの出現確率を底上げしてからなので、いずれにしても「色違いの石像」を集めるところからスタートだと思います。
通路の交差点・曲がり角で出現するディグダは部屋の出入りで復活
さて、ディグダゲージを貯める方法ですが、ちかだいどうくつに隠れているディグダまたはダグトリオを見つけることで増えていきます。肝心のディグダの居場所は、部屋の入退室の度に抽選で場所が決まります。より詳しくは、交差点・曲がり角の中からランダムで場所が決まる、というものです。
大事なのは、部屋から出入りする度に場所が変わるため、通路をひたすら縦横無尽に走り回るのではなく、ディグダがでなくなったら部屋に入って場所を更新する必要があるということです。
そのため、ディグダゲージを貯める最適解としては、曲がり角が多い直線の通路をひたすら往復し、部屋を出入りすることとなります。したがって、部屋の出入り口付近で往復することが効率的といえます。
前述の通り、ディグダは通路の曲がり角や交差点・T字路部分に出現するため、道に沿って一筆書きに走り続けることが重要です。したがって、効率的・楽に周回する場合、画面からある程度目を離して作業をするためには、往復運動、それもT字路が多い道での直線が望ましいです。また、ディグダは部屋への出入りによって復活するため、始点または終点が部屋への出入り口になっている必要があります。
実は、上記2つの条件を満たす道が、キッサキシティ地下の東側(右側)にあります。より具体的には「出入り口と直結の直線」でありながら「5つのT字路」と面している、という誂え向きな場所なのです。この場所であれば、上下に移動し続ける簡単操作だけで、5箇所の交差点を経由できます。手動での周回作業も、非常にはかどります。
この場所へのアクセスは簡単で、キッサキシティのポケモンセンター前から地下に降りて、道なりにひたすら右へ右へ進んでいくだけです。
今回のプログラムはひたすら往復をするだけのシンプルなプログラムなので、準備も非常に簡単です。簡単に紹介しますが、分かる人は読み飛ばしOKです→ ソースコードまで読み飛ばす。
ゲーム側の準備:吹雪の空洞の入口に移動するだけ
前述の通り、キッサキシティ地下の東側(右側)にて、最効率のディグダポイントがあることがわかりましたが、今回のArduino自動化でも、それに倣います。
具体的には、「ふぶきのくうどう」の下側の出入り口のマスに立って準備完了となります。簡単ですね。あとは、Arduinoにプログラムを書き込んでSwitchに差し込めば自動で部屋を往復してくれます。
プログラムの準備:Arduinoに書き込んでSwitchに挿すだけ
今回のプログラムは特段準備は不要です。シンプルに、プログラムを書き込んでSwitchに挿し込めば、たちまち主人公がダッシュして通路をひたすら往復してくれます。ディグダゲージが40溜まったらArduinoを抜いて、手動で化石を掘り起こしましょう。
なお、プログラムでは、単純な往復よりも効率を上げるために、下まで走ったら左に曲がって別の部屋に入って往復する度にディグダを復活させるようにしています。
プログラムのソースコードです。キッサキシティの右側の「吹雪の空洞」の下側出入り口に立ってArduino Leonardoを挿せば動きます。ディグダゲージが溜まるまでの無益な15分を自動化してくれます。
ディグダゲージが溜まったらArduinoを抜いて化石掘りをお楽しみください(手動)。
#include <SwitchControlLibrary.h>
#define HOLDTIME (95)
const double HORIZONTAL_DASH_ELAPSED_TIME = (13.4);
const double VERTICAL_DASH_ELAPSED_TIME = (4.50);
const double INTERVAL_TIME = (3.5);
int PushKey(char* keyname, int holdtime, int delaytime);
void dash(double second, char *keyname);
void setup() {
for(int i=0;i<7;i++){
SwitchControlLibrary().PressButtonR();delay(300);
SwitchControlLibrary().ReleaseButtonR();delay(300);
}
}
void loop() {
PushKey("down", 300, 300);
delay(INTERVAL_TIME*1000UL);
dash( (double)HORIZONTAL_DASH_ELAPSED_TIME, "DOWN" );
PushKey("left", 300, 500);
PushKey("down", 300, 500);
dash( (double)VERTICAL_DASH_ELAPSED_TIME, "LEFT" );
PushKey("left", 300, 300);
delay(INTERVAL_TIME*1000UL);
PushKey("right", 300, 300);
delay(INTERVAL_TIME*1000UL);
dash( (double)VERTICAL_DASH_ELAPSED_TIME, "RIGHT" );
PushKey("up", 300, 500);
PushKey("right", 300, 500);
dash( (double)HORIZONTAL_DASH_ELAPSED_TIME, "UP" );
PushKey("up", 300, 300);
delay(INTERVAL_TIME*1000UL);
}
void dash(double second, char *keyname){
unsigned long int dash_msec = (unsigned long)second*1000UL;
SwitchControlLibrary().PressButtonB();
switch(keyname[0]){
case 'r': case 'R':
SwitchControlLibrary().MoveHat(2);
break;
case 'l': case 'L':
SwitchControlLibrary().MoveHat(6);
break;
case 'u': case 'U':
SwitchControlLibrary().MoveHat(0);
break;
case 'd': case 'D':
SwitchControlLibrary().MoveHat(4);
break;
case 'H': case 'h':
SwitchControlLibrary().PressButtonHome();
default:
break;
}
delay(dash_msec);
SwitchControlLibrary().ReleaseButtonB();
SwitchControlLibrary().MoveHat(8);
delay(100);
return;
}
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);
}
あとがき
いやー皆さま、お久しぶりです。気づけは3月になっていました。2月は日数が少ないですね。2月はひたすら仕事とレジェンズアルセウスで過ごした1ヶ月でした。
さて、今回は、ダイパリメイク自動化の記事、第5弾として「地下大洞窟のディグダ探し」を自動化しました。
BDSPの地下大洞窟は、体感として少し過疎気味です。また、地下大洞窟は、どちらかというと、ハマナスパークでの石版集めのための「化石掘り」がメインで、ディグダを探す人は少ないため、放置でゲージが溜まることはあまり期待できません(むしろ直立不動のオンラインユーザーはあまり好ましくないですね)。
また、様々な理由からBDSPを最新バージョンにしないユーザも一定数いるため、オンラインの人口は減りがちです。現在は、ポケモン剣盾での公式大会予選もあるため、輪をかけてBDSPのオンライン人口は減っていると思います。
そこで、これら諸々の課題を解決し、1人でもオンラインでも「ディグダゲージ」を貯める作業が自動でできるように、今回のプログラムを作ったという次第です。これなら誰にも迷惑がかかりません(むしろ貢献できます)し、Switchが2台あるなら、ローカルで片方をこのプログラムをつないで放置、とかもできますしね。
いずれにしても、BDSPでの自動化としてシンプルながらも有意義なものができたと考えます。
これからもマイペースに本ブログが更新できればと思いますので、引き続き本ブログをよろしくお願いいたします!
ではではc⌒っ.ω.)っ
前回記事:【BDSP自動化04】特性「ものひろい」自動化【ふしぎなアメ・ぎんのおうかん】
導入記事:【Arduino自動化01】Arduino開発環境の導入
ポケモン剣盾の記事:ポケモン剣盾Arduino自動化 カテゴリーの記事一覧
ポケモンBDSPの記事:ダイパリメイクArduino自動化 カテゴリーの記事一覧
YouTubeチャンネル:ますたーの忘備録 - YouTube
---