【レジェンズアルセウス】ピートブロック・くろのきせきを自動収集【ガチグマライド】

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

 

今回は、レジェンズアルセウスガチグマライド(道具掘り)を自動化しました。

リングマやストライクの進化に使う「ピートブロック」「くろのきせき」を完全放置で集めることができます。

 

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

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

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

 

概要

天冠の山麓で、ガチグマでの宝掘り(宝探し)を自動で行います。実績値として、12時間放置で「ピートブロック」13個、「つきのいし」12個、「くろのきせき」9個が手に入りました。特に「ピートブロック」はガチグマライドでしか手に入らないので、ぜひともお役立てください。

f:id:tangential_star:20220319111216g:plain

穴掘りポイント5箇所をチェックし、天冠の山麓とコトブキムラを往復してくれる

f:id:tangential_star:20220319023016g:plain

12時間完全放置でガチグマライド242試行。ピートブロックが13個も手に入った(実績値)

 

目次です。今回はガチグマ宝探しの解説記事っぽくなりました。

ソースコードだけほしいという方は→ソースコードまで読み飛ばす

 

ガチグマの進化のために「ピートブロック」がほしい!

まずは、レジェンズアルセウスで追加された進化アイテム「ピートブロック」について紹介です。

ピートブロックは「リングマ」が「ガチグマ」に進化するために使うアイテムです。満月の日にリングマに「ピートブロック」を与えることで進化するという、稀有な進化条件を持ちます。肝心の「ピートブロック」は、+ボタンで呼び出せるライドポケモンの「ガチグマ」による「宝探し」でのみ入手できます*1

f:id:tangential_star:20220319151617p:plain
f:id:tangential_star:20220319152953g:plain
満月の日にリングマに「ピートブロック」を与えると、ガチグマに進化する

 

ピートブロックは天冠の山麓で掘り出せる

ガチグマは、近くにあるお宝の匂いを感知し、その方向をプレイヤーに教えてくれます。今までのシリーズで言う、ダウジングマシンですね。

天冠の山麓では、ガチグマライドで低確率ながら、ピートブロックを掘り起こすことができます。他にも「つきのいし」「くろのきせき」などの進化アイテムもランダムで掘り出すことができます。確率は、それぞれ約5%です*2

なお、掘り起こせる場所(ポイント)は、コトブキムラから天冠の山麓に向かうたびにランダムに決まるため、根気よく探す必要があります。

f:id:tangential_star:20220319163047p:plain

ピートブロックは天冠の山麓で、約5%の確率で掘り出せる


宝を掘り出せる場所はランダム5パターン

ガチグマライドは、コトブキムラから出入りする度に、宝探しで掘り出せるアイテムの種類はもちろん、掘り出せる場所もランダムで変わることが挙げられます。すなわち、アイテムを掘り出した場所を覚えておいて、コトブキムラに一度帰ってからその場所にもう一度向かっても、同じ場所で掘り出せない場合がある、ということです。

そこで、場所も完全にランダムなのかを検証すべく「コトブキムラに戻る」「山頂ベースすぐの宝を掘る」という一連の動作を242試行繰り返しました。結果、筆者にて検証を行い、おそらく5パターンでランダムに変わっていることが確認できました。

したがって、コトブキムラから出入りした後、これら5パターンを見て回れば、宝掘りを見逃さずに済みます。

f:id:tangential_star:20220319225556p:plain

天冠の山麓「山頂ベース」最寄りの、ガチグマ宝掘りポイント5パターン
コトブキムラから出入りする度に、これらの中からランダムに場所が決まっている

f:id:tangential_star:20220319111216g:plain

これら5パターンを見て回れば、どこかで確実に宝を掘り当てることができる。
2パターン目と3パターン目は非常に近いので一緒に確認すれば、4往復で済む


天冠の山麓で掘り出せるアイテムは12種類!

さて、宝掘りができる位置が5パターンでランダムになることは前述の通りですが、アイテムとしては何が拾えるのか、という点も要確認です。

筆者にて12時間(233試行)で掘り出したアイテムを集計したところ、下記12種類となりました。括弧内の数字はアイテムの個数です。

  • たまいし(280個)
  • てつのかけら(260個)
  • どろだんご(260個)
  • そらいろたまいし(200個)
  • くろいろたまいし(200個)
  • ごりごりミネラル(165個)
  • スイートトリュフ(81個)
  • ほしのかけら(20個)
  • ピートブロック(13個)
  • つきのいし(12個)
  • くろのきせき(9個)
  • たいようのいし(7個)

f:id:tangential_star:20220320011939p:plain

12時間(233試行)で掘り出したアイテムの一覧。沢山のアイテムが拾えたぞ

興味深いことに、ガチグマが掘り出す確率が最も高いのは「どろだんご」でしたが、集めたアイテムの個数が多くなったのは「たまいし」でした。設定確率と比して、1回あたりに拾ってくる個数により体感できる入手効率が大きく異なるといえます。また、今回の目玉である「ピートブロック」は13個も入手することができました。すなわち、単純計算で1時間あたり1個入手できることになります

他にも、「くろのきせき」や「たいようのいし」「つきのいし」などの貴重な進化アイテムも複数入手できました。ガチグマライドによるピートブロック集めは、副次的にも「美味しい」と言えます。

 

自動化の準備

さて、おまたせしました。自動化の準備です。

本自動化では、ガチグマに乗り降りするので、ライドポケモンのカーソルをガチグマに合わせた状態にしておいてください。事前の準備としてはそのくらいです。また、場所は「天冠の山麓」マップ内なら、基本的には不問です。

注意すべき点は「-ボタン」でマップを開いてXボタンから移動(ファストトラベル)を行うので、ポケモンに索敵されていない状態でArduino Leonardoを差し込む、ということです(マップから移動ができなくなるため)。

f:id:tangential_star:20220319233600p:plain

天冠の山麓で「ガチグマ」にカーソルをあわせた状態でArduinoを挿し込めばOKだ

 

ソースコード

今回は「天冠の山麓」でのガチグマライドの自動化です。

天冠の山麓の内部で、ライドポケモンの選択カーソルがガチグマに合っている状態でArduinoを挿せば自動で「山頂ベース」まで移動してガチグマに乗って収集を始めてくれます。5箇所を巡って確認し終わったら自動でコトブキムラに戻って周回してくれます。

/* 
 *  ★ポケモンレジェンズアルセウス ガチグマライドで色々掘ろう@天冠の山麓 山頂ベース★
 *  天冠の山麓の山頂ベースでArduinoを挿すとスタート。
 *  ライドポケモンは、「ガチグマ」にカーソルがあっている状態で使うこと!(重要)
 *  
 * 
 * 実測値で、12時間放置で242ループ。下記が手に入りました。
 * ・ピートブロック:13個
 * ・クスリソウ:242個
 * ・ごりごりミネラル:404個
 * ・スイートトリュフ:81個
 * ・どろだんご:260個
 * ・ほしのかけら:20個
 * ・つきのいし:12個
 * ・そらいろたまいし:200個
 * ・たいようのいし:7個
 * ・くろのきせき:9個
 *  
 *  設定
 *  ・はなしのはやさ:はやい
 *  
 *  (c) 2022 ますたーの忘備録
 *  https://tangential-star.hatenablog.jp/
*/

#include <SwitchControlLibrary.h>

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

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

// 【天冠の山麓】マップでXを押したときに「山頂ベース」が上から何番目か?(山麓ベース=0・山中=1・山頂=2・迎月の戦場=3・やめる)
const int SANROKU = 0; // 山麓ベース
const int SANCHU  = 1; // 山中ベース
const int SANCHO  = 2; // 山頂ベース
const int GEIGETSU= 3; // 迎月の戦場

// 【コトブキムラ】マップでXを押したときに「表門前」が何番目か?
const int HOMBU    = 0; // 本部前
const int OMOTEMON = 1; // 表門前
const int YAGAI    = 2; // 野外訓練場
const int NOUJO    = 3; // 農場前 
const int KUNRENJO = 4; // 訓練場前

// 【入り口】マップでカーソルを外してから「↓」キーで「天冠の山麓」が何番目か?
const int KOTOBUKI = 1; // コトブキムラ
const int KOKUYO   = 2; // 黒曜の原野
const int GUREN    = 3; // 紅蓮の湿地
const int GUNJO    = 4; // 群青の海岸
const int TENGAN   = 5; // 天冠の山麓
const int JUMPAKU  = 6; // 純白の糖度
const int INISHIE  = 7; // 古の隠れ里

// ★修正ここまで★-----------------

bool isFirstLoop = true;

void PushRL(int delay_time_ms);
int PushKey(char* keyname, int holdtime, int delaytime);
void TiltLeftStick(int direction_deg, double power,unsigned long int holdtime, unsigned long int delaytime);
void Die(void);

void JumpTo(int destination){
  // destination: cursor where you want to go in map (ArceusPhone).
  int i=0;
  PushKey("-", HOLDTIME, 1200);
  PushKey("X", HOLDTIME, 1000);
  for(i=0; i<destination; i++)PushKey("down", HOLDTIME, 250);
  PushKey("A", HOLDTIME, 3300);
  return;
}
void Turn(int degree){
  TiltLeftStick( degree, 0.3, 140, 300);
  PushKey("ZL", HOLDTIME, 1000);
  return; 
}
void Dash(double second){
  TiltLeftStick( 0, 1.0, second*1000UL, 300);
  return;
}
void Dash(double second, double second_interruptA){
  TiltLeftStick( 0, 1.0, 0, second_interruptA*1000UL); // 傾けて
  PushKey("A", HOLDTIME, (second - second_interruptA)*1000UL );
  TiltLeftStick( 0, 0.0, 0, 300); // 傾きをもどす
  return;
}

void PokeThrow(int delaytime=300, int holdingballtime = 250){
  // ボールを構えて
  SwitchControlLibrary().PressButtonZR(); delay(holdingballtime);
  // ボールを投げる
  SwitchControlLibrary().ReleaseButtonZR(); delay(delaytime);
  return;
}
void RidePoke(void){
  PushKey("+", HOLDTIME, 1200);
  return;
}

void Dig(void){
  PushKey("Y", HOLDTIME, 400);
  return;
}

void DashBack(void){ // call this function after Dig()
  TiltLeftStick( 180, 1.0, 3500, 300);
  PushKey("B", HOLDTIME, 300);
  return;
}

void BackToJubilifeVillage(void){
  // 山頂ベースに飛んで
  JumpTo(SANCHO);

  // 博士に話しかける
  TiltLeftStick( 48, 1.0, 900, 300);
  PushKey("A", HOLDTIME, 900);    // 報告できることは 特にないようですね ▼
  PushKey("A", HOLDTIME, 700);    // これから どうするのですか? ▼
  PushKey("A", HOLDTIME, 700);    // →調査を続ける
  PushKey("down", HOLDTIME, 350); // →ムラに戻る
  PushKey("A", HOLDTIME, 1200);   // では コトブキムラに戻りましょう 大丈夫です 警備隊も一緒ですよ ▼
  PushKey("A", HOLDTIME, 12000);  // 移動中… 
  return;
}

void GotoCoronetHighlands(void){
  int i=0;
  // 表門前に飛んで
  JumpTo(OMOTEMON);

  // デンスケに話しかける
  TiltLeftStick( 23, 1.0, 2000, 500); // 外に出るのか?気をつけてな or ポケモン大大大発生の 報告があったらしいぞ! 気をつけてな
  PushKey("A", HOLDTIME, 1200); // マップを開く
  if(isFirstLoop){
    TiltLeftStick( 0, 1.0, 1700, 500); // カーソルを外にはずして
    for(i=0; i<TENGAN; i++)PushKey("down", HOLDTIME, 250); // 「天冠の山麓」にカーソルをあわせる
  }
  PushKey("A", HOLDTIME, 600); // 「天冠の山麓」を選択

  for(i=0; i<SANCHO ; i++)PushKey("down", HOLDTIME, 250); // 「山頂ベース」を選択
  PushKey("A", HOLDTIME, 12000); // 移動中…

  return;  
}

void setup() {
   for(int i=0; i < 5 ; i++)PushKey("B", HOLDTIME, 700);
}

void loop() {

  // 振り返ってガチグマライド掘り起こしポイントへ


  // 超左バージョン
  if(isFirstLoop)JumpTo(SANCHO);
  Turn(169); 
  Dash(15.8, 9.63); // クスリソウを拾う
  RidePoke();
  Dig();
  DashBack();

  // 左バージョン
  JumpTo(SANCHO);
  Turn(177); 
  Dash(16.9);
  RidePoke();
  Dig();
  TiltLeftStick( 180, 1.0, 1600, 300); // ここにもずれることがある
  Dig();
  DashBack();
  
  // 真ん中バージョン
  JumpTo(SANCHO);
  Turn(189); 
  Dash(18.4, 16.64); // ごりごりミネラル を拾う
  RidePoke();
  Dig();
  DashBack();

  // 右バージョン
  JumpTo(SANCHO);
  Turn(202); 
  Dash(15.2);
  RidePoke();
  Dig();
  TiltLeftStick( 180, 1.0, 13000, 2800); // 一番右は、まれにドータクン・ドーミラーに索敵されるので走って基地側へ

  // Die(); // debug


  // コトブキムラに戻る
  BackToJubilifeVillage();

  // 天冠の山麓(山頂ベース)に戻る
  GotoCoronetHighlands();

  isFirstLoop = false;
}

void PushRL(int delay_time_ms){
  SwitchControlLibrary().PressButtonR();
  SwitchControlLibrary().PressButtonL();
  delay(HOLDTIME);
  SwitchControlLibrary().ReleaseButtonR();
  SwitchControlLibrary().ReleaseButtonL();
  delay(delay_time_ms);
  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);
}
void TiltLeftStick(int direction_deg, double power,unsigned long int holdtime, unsigned long 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 Die(void){
  for(;;)delay(100);
}

 

f:id:tangential_star:20220320021125p:plain

12時間放置の戦利品(実測値)。ちなみに全部売却すると193,810円になるはず。
※「ごりごりミネラル」「クスリソウ」は道中で拾うため、純粋な宝探しの個数ではない

 

あとがき

お久しぶりですね!!(20日ぶり)

今回は、レジェンズアルセウスの自動化にチャレンジしてみました。今回は自動化の第1弾として「ガチグマライドによる宝探し」を題材にしてみました。

もともと「ピートブロック」など、入手方法が限られており、かつ、その確率も低く設定されているこれらについては、手動では「周回作業」としての側面が拭えず、これを自動化した次第です。結果として、シンプルながらも非常にパワフルな自動化になったのではないか、と考えます。

また、世の中的にも、ガチグマライドを攻略・解説した記事はほとんど無く、詳しい掘り出しポイント・確率についても自分で調べて、結構やりがいがありました(笑)

個人的に、やっぱり自動化のソースコードだけじゃなく、こういう雑談的な基礎研究的な部分も入れていきたいなと思ってしまいます(凝り性ですかね)。

このブログも、マイペースながらも、自分が「楽しい」と思えたことを交えてこれからも更新していけたらと思いますので、引き続きよろしくお願いいたします。

 

 

それにしても、レジェンズアルセウスは本当に神ゲーですね。総じて「ポケモンの世界そのもの」を体感できる素晴らしいゲームで、ついつい時間を忘れて没頭して楽しんでしまいます。

私自身、もともとオープンワールド系のゲームは馴染みがなく、楽しめるかが不安だったのですが、まさかこれほどハマるとは、自分でも予想できなかったです。

第9世代(ポケモンSV)もまさかのオープンワールド形式とのことでしたし、これが2022年度内に発売される、というのは本当に驚きと喜びと期待でいっぱいです。

スマホ用ゲーム「ポケモンマスターズEX」も2.5周年を迎えてますます勢いづいて来ましたし、BDSPではシェイミアルセウスイベントの解禁も来ましたし、本当にポケモンをこうして楽しめることを嬉しく思います。

 

これからも引き続きポケモンと永く遊んでいけたらと思いますし、その折、本ブログも更新していけたらと思います。

これからもどうぞよろしくお願いいたします。

 

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

 

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

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

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

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

---

*1:ピートブロックは、フィールド探索以外の入手方法として、無料追加アップデートの「勝ち抜き道」でランダム入手ができるとの報告もあります

*2:筆者による233試行の実測値から計算