【BDSP自動化05】地下大洞窟でディグダ探し【ポケモンの石像✨】

お久しぶりです。ますたーです。

 

今回は、BDSPの地下大洞窟での「ディグダ」探しを自動化しました。

ダイパリメイク自動化の記事、第5弾になります。3月最初の記事です。

 

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

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

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

 

概要

キッサキシティの地下大洞窟で、ディグダを探し続けてくれる自動化です。40匹見つけて突入するボーナスタイムまでの放置にピッタリですね。一応、ソロだと15分ほど放置で、ディグダゲージが40まで溜まりました。オンラインに繋いだり、ローカルで複数台で自動化すると、より早くゲージが溜まります。

f:id:tangential_star:20220127231503g:plain
f:id:tangential_star:20220127231634p:plain
キッサキシティの地下大洞窟(右側の「吹雪の空洞」のL字通路)でディグダを探し続ける
ソロだと約15分放置でディグダゲージが40溜まるぞ

目次です。今回は超あっさりです。

ソースコードが欲しい方は、どうぞ→ ソースコードまで読み飛ばす

 

色違いの石像を置くと、そのタイプのポケモンが出やすくなる

さて、まずは目的の整理です。ポケモンBDSP(ダイパリメイク)の一番の目玉といって過言でもないコンテンツが「地下大洞窟」です。

今作では、地上で「たんけんセット」を使うことで地下に潜ることができ、「大空洞」で野生のポケモンを捕まえたり、化石掘りを楽しんだり、自分の「ひみつきち」を作って石像を飾れたりできます。

f:id:tangential_star:20220128000217p:plain

自分の「ひみつきち」に石像を置くと、置いたタイプのポケモンが出現しやすくなる!
「色違いの石像」だと、アップ率がさらに高くなる!1つのタイプで埋め尽くそう!

前述の通り、地下大洞窟の「ひみつきち」では、ポケモンの石像を配置することができます。この石像をひみつきちに配置することで、地下空洞で出会えるポケモンの出現確率を変化させることができます。より具体的には、配置したポケモンの「タイプ」に該当するポケモンの出現割合が上昇します。

中でも、色違いの石像(全体的に緑色のもの)は、そのタイプの出現確率の上昇値が高くなるため、積極的に配置していきたいものになります。

 

ディグダゲージMAXだと「豪華な石の箱」の入手確率が大幅にアップ

ひみつきちで飾ることのできる石像の入手方法ですが、化石掘りで「きれいな いしのはこ」「ごうかな いしのはこ」を掘り出すことで手に入ります。後者の「ごうかな いしのはこ」は極稀に出土し、普段はなかなか入手が困難です。

ところが、左上のディグダゲージが40溜まり、いわゆるボーナスタイム(ディグダバーストとかゲージマックスとか呼び名は色々ありますが)に入ると「ごうかな いしのはこ」の出現確率は大きく跳ね上がります

時間中なら、体感でも5~6個は安定して掘り出せるため、まさにボーナスタイムとなります

f:id:tangential_star:20220128123200p:plain
f:id:tangential_star:20220127233639g:plain
左上のディグダゲージが40溜まるとボーナスタイム。「豪華な石の箱」が出現しやすいぞ

おまけ:ディグダゲージMAXだと、野生ポケモンの色違い確率も倍に

余談ですが、ディグダゲージがMAXになると、地下大洞窟の部屋で出現するポケモンの色違いの出現確率が2倍になる、という報告もあります。通常の出現確率が1/4096なので、1/2048となる計算です。

ただし、ボーナスタイムはわずか4分しか継続しないため、地下大洞窟でポケモンの色違い厳選は、あまり効率的とは言えません。あくまでもおまけですかね。私はこの方法で色違い厳選をしたいとはあまり思えません。

どうしてもこの方法で色違い厳選をする場合は、先に石像を秘密基地において、狙いのポケモンの出現確率を底上げしてからなので、いずれにしても「色違いの石像」を集めるところからスタートだと思います。

 

通路の交差点・曲がり角で出現するディグダは部屋の出入りで復活

さて、ディグダゲージを貯める方法ですが、ちかだいどうくつに隠れているディグダまたはダグトリオを見つけることで増えていきます。肝心のディグダの居場所は、部屋の入退室の度に抽選で場所が決まります。より詳しくは、交差点・曲がり角の中からランダムで場所が決まる、というものです。

大事なのは、部屋から出入りする度に場所が変わるため、通路をひたすら縦横無尽に走り回るのではなく、ディグダがでなくなったら部屋に入って場所を更新する必要があるということです。

そのため、ディグダゲージを貯める最適解としては、曲がり角が多い直線の通路をひたすら往復し、部屋を出入りすることとなります。したがって、部屋の出入り口付近で往復することが効率的といえます。

f:id:tangential_star:20220228230633g:plain

ディグダを効率よく探すには、曲がり角がたくさんある直線で部屋の出入りと往復だ


ディグダ探しはキッサキシティの右側の直線が最適解

前述の通り、ディグダは通路の曲がり角や交差点・T字路部分に出現するため、道に沿って一筆書きに走り続けることが重要です。したがって、効率的・楽に周回する場合、画面からある程度目を離して作業をするためには、往復運動、それもT字路が多い道での直線が望ましいです。また、ディグダは部屋への出入りによって復活するため、始点または終点が部屋への出入り口になっている必要があります。

実は、上記2つの条件を満たす道が、キッサキシティ地下の東側(右側)にあります。より具体的には「出入り口と直結の直線」でありながら「5つのT字路」と面している、という誂え向きな場所なのです。この場所であれば、上下に移動し続ける簡単操作だけで、5箇所の交差点を経由できます。手動での周回作業も、非常にはかどります。

この場所へのアクセスは簡単で、キッサキシティポケモンセンター前から地下に降りて、道なりにひたすら右へ右へ進んでいくだけです。

f:id:tangential_star:20220228234715g:plain

ディグダゲージ最効率!?な通路に行くには、
キッサキシティから地下に潜ったらひたすら東(右側)へ進むだけだ!

f:id:tangential_star:20220228233930p:plain

ディグダ集めに最適な直線路が、キッサキシティ地下の東側にあるぞ!
ポケモン徹底攻略様より画像引用・筆者にて改変)

Arduino自動化の準備

今回のプログラムはひたすら往復をするだけのシンプルなプログラムなので、準備も非常に簡単です。簡単に紹介しますが、分かる人は読み飛ばしOKです→ ソースコードまで読み飛ばす

ゲーム側の準備:吹雪の空洞の入口に移動するだけ

前述の通り、キッサキシティ地下の東側(右側)にて、最効率のディグダポイントがあることがわかりましたが、今回のArduino自動化でも、それに倣います。

具体的には、「ふぶきのくうどう」の下側の出入り口のマスに立って準備完了となります。簡単ですね。あとは、Arduinoにプログラムを書き込んでSwitchに差し込めば自動で部屋を往復してくれます。

f:id:tangential_star:20220228234715g:plain
f:id:tangential_star:20220301220206j:plain
キッサキシティ地下の右側「吹雪の空洞」の出入り口に立ったら準備完了だ

プログラムの準備:Arduinoに書き込んでSwitchに挿すだけ

今回のプログラムは特段準備は不要です。シンプルに、プログラムを書き込んでSwitchに挿し込めば、たちまち主人公がダッシュして通路をひたすら往復してくれますディグダゲージが40溜まったらArduinoを抜いて、手動で化石を掘り起こしましょう。

なお、プログラムでは、単純な往復よりも効率を上げるために、下まで走ったら左に曲がって別の部屋に入って往復する度にディグダを復活させるようにしています。

f:id:tangential_star:20220127231503g:plain

SwitchにArduinoを挿すと、ひたすら主人公が走ってディグダを探して往復してくれる

 

ソースコード

プログラムのソースコードです。キッサキシティの右側の「吹雪の空洞」の下側出入り口に立ってArduino Leonardoを挿せば動きます。ディグダゲージが溜まるまでの無益な15分を自動化してくれます

ディグダゲージが溜まったらArduinoを抜いて化石掘りをお楽しみください(手動)。

/* 
 *  ★ポケモンBDSP 地下大洞窟で上下に移動し続けてディグダを発生させるだけ★
 *  キッサキシティから右に行った「吹雪の空洞」の下の一本道で、L字のに曲げて移動するだけ
 *  
 *  
 *  設定
 *  ・はなしのはやさ:はやい
 *  ・もじモード:ひらがな
 *  ・せんとうアニメ:みない
 *  
 *  (c) 2020-2022 ますたーの忘備録
 *  https://tangential-star.hatenablog.jp/
*/

#include <SwitchControlLibrary.h>

#define HOLDTIME (95)     // 1回のキー入力の長押し時間

// ★修正ここから★-----------------

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() {
  // コントローラーとして認識されるためにRを7回ほどカチャカチャ(地下なので探索するだけ)
  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 current_time=0;
  // unsigned long int start_time=0;
  // unsigned long int temp_time=0;

  unsigned long int dash_msec = (unsigned long)second*1000UL;


  SwitchControlLibrary().PressButtonB(); // Bを押しながら…
  
  switch(keyname[0]){ // 方向キーを入力
    case 'r': case 'R': // right
      SwitchControlLibrary().MoveHat(2);
    break;
    case 'l': case 'L': // left
      SwitchControlLibrary().MoveHat(6);
    break;
    case 'u': case 'U': // up
      SwitchControlLibrary().MoveHat(0);
    break;
    case 'd': case 'D': // down
      SwitchControlLibrary().MoveHat(4);
    break;
    case 'H': case 'h': // Home
      SwitchControlLibrary().PressButtonHome();
    default:
    break;  
  }

  // 入力された方向キーを押し続ける。
  delay(dash_msec);
  // for( start_time=millis(), current_time=start_time ; current_time - start_time < dash_msec ; current_time=millis() );

  SwitchControlLibrary().ReleaseButtonB(); // Bを離す
  SwitchControlLibrary().MoveHat(8);       // 入力された方向キーを離す

  delay(100);

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

 

あとがき

いやー皆さま、お久しぶりです。気づけは3月になっていました。2月は日数が少ないですね。2月はひたすら仕事とレジェンズアルセウスで過ごした1ヶ月でした。

 

さて、今回は、ダイパリメイク自動化の記事、第5弾として「地下大洞窟のディグダ探し」を自動化しました。

BDSPの地下大洞窟は、体感として少し過疎気味です。また、地下大洞窟は、どちらかというと、ハマナスパークでの石版集めのための「化石掘り」がメインで、ディグダを探す人は少ないため、放置でゲージが溜まることはあまり期待できません(むしろ直立不動のオンラインユーザーはあまり好ましくないですね)。

また、様々な理由からBDSPを最新バージョンにしないユーザも一定数いるため、オンラインの人口は減りがちです。現在は、ポケモン剣盾での公式大会予選もあるため、輪をかけてBDSPのオンライン人口は減っていると思います。

そこで、これら諸々の課題を解決し、1人でもオンラインでも「ディグダゲージ」を貯める作業が自動でできるように、今回のプログラムを作ったという次第です。これなら誰にも迷惑がかかりません(むしろ貢献できます)し、Switchが2台あるなら、ローカルで片方をこのプログラムをつないで放置、とかもできますしね。

いずれにしても、BDSPでの自動化としてシンプルながらも有意義なものができたと考えます。

 

これからもマイペースに本ブログが更新できればと思いますので、引き続き本ブログをよろしくお願いいたします!

 

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

 

前回記事:【BDSP自動化04】特性「ものひろい」自動化【ふしぎなアメ・ぎんのおうかん】

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

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

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

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

---