【Arduino自動化09ex】「カレーのあかし」持ちポケモンの完全自動厳選【キャンプでカレー】

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

 

今回は、ポケモンキャンプで「カレー」を自動で調理し、時々遊びに来る「カレーのあかし」を持ったポケモンを自動で集め続けるArduino自動化です。

前回記事(Arduino自動化09)の改良版となります。もちろん、本記事だけでも読めるように書きますが、前回記事も個人的に気に入っている記事なのでそちらも合わせて是非読んでほしいです。

 

なお、Arduino Leonardo自動化の導入と、機材構成については導入記事をご覧ください。

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

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

 

概要

本記事では、ポケモン剣盾の「ポケモンキャンプ」の「カレー」づくりを自動で行います。さらに、調理後には左右を確認します。より具体的には、「クラボのみ」を6個ずつ消費(食材不要)して、マホミル級のカレーを作りカレー調理後には広場にいるポケモンに話しかけてくれますこれらを完全放置で行えます

すなわち、自動で「カレーのあかし」を持ったポケモンを仲間にしてくれます。 

f:id:tangential_star:20210608214015g:plain

カレーの調理~匂いに釣られたポケモンを仲間に加えるまですべてを完全自動化

 

目次です。ソースコードのみ欲しいという方は⇒読み飛ばす

 

カレーのあかしを持ったポケモンについて

まずは、カレーを自動で調理する目的についてのおさらいです。詳細は前回記事(Arduino自動化09)に載っていますが、こちらでも改めて説明します。

ポケモンキャンプでカレーを作ると時々、野生ポケモンがキャンプに遊びに来ることがあります。遊びに来たポケモンに話しかけると仲間にすることができます。

f:id:tangential_star:20210608220406p:plain
f:id:tangential_star:20210608220449p:plain
カレーを作ると時々野生のポケモンが遊びにくる。話しかけると仲間にできるぞ

ポケモンキャンプに来たポケモンは「カレーのあかし」というリボンを確定で持っており、このリボンを選択することで「カレーずきな」という二つ名を付けることができます。従来の野生ポケモン(あかしを持つ確率は2%~4%)と異なり、キャンプで仲間になるポケモンは確定でリボンを持っていることから、いわゆる「証厳選」の中でも比較的簡単な部類と言われています。

f:id:tangential_star:20210102011021p:plain
f:id:tangential_star:20210102011451g:plain
「カレーのあかし」を持ったポケモンは、登場時に「カレーずきな」という二つ名が付く

なお、ポケモンキャンプでカレー作りをすれば、どこでも野生ポケモンが遊びに来てくれるわけではありません。出現するポケモンの種類・場所はあらかじめ決まっています。

具体的には、ワイルドエリア・DLCの島などを除く、道路・ダンジョン(ルミナスメイズのもり・ガラルこうざんなど)で出会うことができます。また、出会えるポケモンは、その場所でランダム出現するポケモン(シンボルとして出現しているポケモンではなく「!」のマークが出て出現するポケモン)です。

出現ポケモンと場所については前回記事(Arduino自動化09)でも紹介した通り、だま氏がまとめた画像(下記参照)などで確認ができます。

f:id:tangential_star:20210102134430p:plain
f:id:tangential_star:20210102133513j:plain
「カレーのあかし」を持ったポケモンの出現場所について
左:「ポケモン徹底攻略」より画像引用・改変     右:だま氏のTwitter投稿@monst_dama)より画像引用

なお、手持ちの「なかよし度」と、作ったカレーの出来栄え(ソーナンス級・マホミル級など)によって、カレー調理後に野生ポケモンの遊びに来てくれる確率が変動します

最も効率的な組み合わせは、「手持ち6匹のなかよし度がMAX」かつ「カレーのグレードが『マホミル級』」の2つを満たした時で、その確率は「1/7(≒14.28%)」です。

f:id:tangential_star:20210102102016p:plain
f:id:tangential_star:20210102120251p:plain
「マホミル級」のカレーを作ると野生のポケモンが来やすい。確率は最大で1/7ほど

 

プログラムの使い方(事前準備)

早速プログラムの使い方の紹介です。ソースコード後述します

まずは、準備として下記を確認してください。

  1. 手持ちが6匹埋まっている
  2. 充分な量の「きのみ(クラボのみ999個など)」がリュックの一番上にある
  3. 食材を1つ以上持っている(一切消費しませんが、食材欄が空っぽだとうまく動きません)
  4. 充分な量の「モンスターボール」「スーパーボール」「ハイパーボール」いずれかを持っている(これらのいずれかにしか入りません。原則としてモンスターボールが優先されます)
  5. ボックスが空いている

これらを満たしたら、メニューから「ポケモンキャンプ」を開いてください。

そして、ポケモンキャンプが開いたら、手動で一度Xボタンを押し、カーソルを「料理」に合わせてからBボタンでメニューを閉じてください(重要)。

上記5つを満たしていれば、準備OKです。Arduinoにプログラムを書き込んでSwitchに差し込むだけでカレーづくり&調理後キョロキョロ見回しながら話しかけて野生ポケモンを仲間に加えてくれます。

f:id:tangential_star:20210102141132p:plain
f:id:tangential_star:20210102141141p:plain
事前準備の上、目的の道路に着いたら「ポケモンキャンプ」を開こう
f:id:tangential_star:20210102141454p:plain
f:id:tangential_star:20210102141503p:plain
キャンプでXボタンを押した時に、カーソルが「料理」に合う状態にしてからBを押そう

ちなみに、手持ちポケモンがなかよし度MAXだと、野生ポケモンが遊びに来てくれる確率が上がりますが、なかよし度はカレーを作ることで自動的に上がっていきますのでご安心ください。つまり、初めてカレー作りに挑戦する人や、「カレーのあかし」厳選初心者の方については、きのみとボールを準備して何も考えずに手持ち6匹埋めてキャンプするだけでOKです。

 

動作検証:15時間以上破綻なくプログラムが稼働しました! 

ここで1つ動作報告です。読み飛ばしOKです⇒読み飛ばす

作ったプログラムのデバッグ作業も兼ねて、リュックに「クラボのみ」「オレンのみ」「カゴのみ」「モモンのみ」をそれぞれ999個ずつ詰め込み、耐久デバッグ(SwitchにArduinoを挿して動作が止まるまでひたすら放置)をしました。

結果、実に15時間49分もの間、一切のループ破綻なく、カレーを作り続けることができました(画面録画の動画容量はなんと19.2GB!)。

※検証のため、プログラム中の定数「CHERI_BERRY」は「(999*3)」に書き換えて定義しています。一応、プログラムでの想定では999を上限にしていましたが、きちんと動きました

f:id:tangential_star:20210608224732p:plain
f:id:tangential_star:20210608224113p:plain
Arduinoを挿すと同時に録画スタート。15時間31分連続稼働している(右下注目)

この検証のために使用したきのみは合計2940個、仲間になったポケモンは61匹でした。

すなわち、期待値として、1時間あたり3.85匹と仲間になれることが分かります。なお、手持ちのきのみは先頭4行を999個で埋めて、手持ちポケモンは6匹ともなかよし度MAXにしてあります。また、1回の調理に使うきのみは6個にしました。

f:id:tangential_star:20210608225846g:plain

検証の結果、15時間40分の放置で「カレーのあかし」を持ったポケモン61匹が仲間に

 

注意すべき点として、コーディングの都合上、一部、プログラム上では「B」ボタンを使用しています

稀(15匹くらいに1匹くらいの割合?)に遊びに来たポケモンを仲間に加えなかったり、極稀(筆者環境では述べ50時間の検証中1回だけ発生)に途中でキャンプを終了してしまったりすることがあり得ます。

あくまでも、決められたキー操作を自動で繰り返しているだけ、という点には重々承知の上、自己責任にてご利用くださいませ。

f:id:tangential_star:20210608231721g:plain
f:id:tangential_star:20210608231741g:plain
極稀にタイミングがずれるなどで、仲間にし損なったりキャンプを終了したりすることも

 

プログラムのソースコード

前回(Arduino自動化09)のソースコードと同様、ポケモンキャンプでカーソルが「料理」に合う状態でメニューを閉じてからArduinoを挿すだけの簡単設計です。

2箇所、あらかじめプログラムを必要に応じて書き換えてください。上限とする「きのみの数(1~999)」と、1回の「調理で消費するきのみの量(1~10)」をそれぞれ「CHERI_BERRY」「USING_BERRY」で指定することができます。

#define CHERI_BERRY (999) // 「クラボのみ」の所有数
#define USING_BERRY (6) // 1回の調理で何個のきのみを利用するか

残りの量が消費予定量を上回った場合にプログラムは自動で止まるように設計しています。なお、非推奨ですが、耐久デバッグのためにCHERI_BERRYを(999*3)で利用し、15時間稼働させた実績もあるので、きのみ3~4種類をそれぞれ999個ずつお持ちであれば、そういった長時間前提の利用も可能かと思います。

いずれにしても、自己責任にて利用ください。

/* 
 *  全自動カレー作り&ポケモン捕獲c⌒っ.ω.)っ 
 *  自動でポケモンを捕まえます!_(:3 ⌒゙)_
 *  (c) 2021 ますたーの忘備録
 *  https://tangential-star.hatenablog.jp/
*/

#include <SwitchControlLibrary.h>

#define HOLDTIME (95) // 1回のキー入力の長押し時間
#define KAKIMAZE_CYCLE (435) // かき混ぜ時周期(1回転の必要ミリ秒)
#define RENDA_CYCLE (150) // 連打のサイクル(1回仰ぐのにかかるミリ秒)
#define CHERI_BERRY (999) // 「クラボのみ」の所有数(これをオーバーしないように止まります)
#define USING_BERRY (6) // 1回の調理で何個のきのみを利用するか
 // ↑6,7,10で「マホミル級」検証済。1,5は「ソーナンス級」検証済。
 // メモ:6個の時、極稀にソーナンス級になることがあった。理由は不明。心配な人は10で。
#define AIJO_BASETIME 3200 // 愛情を込めるタイミング(どうしてもソーナンス級が続く場合にはここの数字を調整してみてください)
#define AIJO_OFFSET 60 // きのみの数でズレる単位時間(ミリ秒)

#define HANASHIKAKE_CYCLE (125) // 最後の連打のサイクル(ポケモンに呼びかけ)

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

int CheriBerryNum = 0;

void setup() {
  // コントローラーとして認識されるためにRLを7回ほどカチャカチャする
  for(int i=0;i<7;i++)PushRL(300);
  delay(1000);
  CheriBerryNum = CHERI_BERRY;
}

void loop() {
  int i=0;
  unsigned long int current_time=0;
  unsigned long int start_time=0;
  unsigned long int temp_time=0;
  float holdA = 0;
  int isholding = 0;
  float temp_deg = 0;
  int isfirsttime =0;
  int aijo_kome = AIJO_BASETIME+AIJO_OFFSET*USING_BERRY;

  if(CheriBerryNum < USING_BERRY){
    // 残りの「クラボのみ」がUSING_BERRY個未満ならプログラムをストップ
    for(;;) delay(1000);  
  }
  
  // メニューを開く
  PushKey("X",    HOLDTIME, 1000);
  // 料理を選択
  PushKey("A",    HOLDTIME, 750);
  // 「料理を始める」
  PushKey("A",    HOLDTIME, 2500);
  // 食材⇒いれない
  PushKey("A",    HOLDTIME, 350); // 空白のA
  PushKey("+",    HOLDTIME, 550);
  PushKey("A",    HOLDTIME, 350); // 空白のA
  // きのみ⇒「クラボのみ(一番上)」USING_BERRY個
  #if(USING_BERRY == 10)
    PushKey("A",    HOLDTIME, 550);
    PushKey("Down", HOLDTIME, 550);
    PushKey("A",    HOLDTIME, 1500); // クラボのみが10個まな板の上に乗るのを待つ
  #else
    PushKey("A", HOLDTIME, 550);
    for(i=0;i<USING_BERRY-1;i++)PushKey("UP",HOLDTIME, 150);
    PushKey("A", HOLDTIME, 180*USING_BERRY);
    PushKey("+", HOLDTIME, 350); // +で材料を決定
  #endif
  // A押してから確実に5秒ジャストで引き渡し
  for( start_time=millis(), current_time=start_time,isfirsttime=1 ; current_time - start_time < 5000 ; current_time=millis() ){
    // ループ初回のみAを押す
    if(isfirsttime){
      // 選んだきのみで始めますか?⇒はい
      PushKey("A", 100, 300);
      isfirsttime=0;
    }
  }
  // 火起こし「21秒」
  for( start_time=millis(), current_time=start_time, isholding=0 ; current_time - start_time < 21000 ; current_time=millis() ){

     // RENDA_CYCLEミリ秒ごとにAを押す
     temp_time = (current_time - start_time) % (RENDA_CYCLE+1); // 経過ミリ秒のRENDA_CYCLE剰余を計算
     holdA = (float)temp_time / (float)RENDA_CYCLE * 100.0; // 剰余から100%に変換
     if( holdA <= 35.0 ){ // RENDA_CYCLEの3.5割の時間はA押し、それ以外はAを離す
       if(!isholding){
         SwitchControlLibrary().PressButtonA();
         isholding = 1;
       }
     }else{
       if(isholding){
         SwitchControlLibrary().ReleaseButtonA();
         isholding = 0;
       }
     }
  }
  if(isholding) SwitchControlLibrary().ReleaseButtonA();

  // かき混ぜ「18秒」
  for( start_time=millis(), current_time=start_time ; current_time - start_time < 18000 ; current_time=millis() ){
     // KAKIMAZE_CYCLEミリ秒ごとに1周スティック回転
     temp_time = (current_time - start_time) % (KAKIMAZE_CYCLE+1); // 経過ミリ秒のKAKIMAZE_CYCLE剰余を計算
     temp_deg = (float)temp_time / (float)KAKIMAZE_CYCLE * 360.0; // 剰余から360°角度に変換
     TiltLeftStick( (int)temp_deg, 1.0, 0, 0); // 経過時間とKAKIMAZE_CYCLEの周期に応じた角度に倒す
  }
  TiltLeftStick( 0, 0.0, 0, 0); // スティックを初期位置に戻す

  // 愛情込め~配膳「20秒」
  for( start_time=millis(), current_time=start_time,isfirsttime=1 ; current_time - start_time < 20000 ; current_time=millis() ){
    // 愛情込めは3.8秒
    temp_time = (current_time - start_time);
    if( temp_time > aijo_kome && isfirsttime==1){ // aijo_komeミリ秒を超えたタイミングで愛情込め
      if(isfirsttime) PushKey("A", 100, 300); // 愛情込め
      isfirsttime=0;
    }
  }
  PushKey("A", 100, 300); // 配膳されたカレーを眺めた後のA
  // もぐもぐ~マホミル級のおいしさ「13秒」
  delay(13000); // カレー実食中・・・
  PushKey("A", 100, 1500); // フィールドに戻る


  // 2021/06/06 改善
  // あたりを見回してカレー好きのポケモンがいないか確認(目視確認から、自動A連打キョロキョロで手持ち加えるまで自動化をする)
  TiltLeftStick( 270, 1.0, 2000, 0); // 左端までカメラを倒す
  
  // キョロキョロしている間、A連打してくれる
  TiltLeftStick( 90, 0.9, 0, 0); // 右側スティック入力
  for( start_time=millis(), current_time=start_time, isholding=0 ; current_time - start_time < 2.5*1000UL ; current_time=millis() ){
     // HANASHIKAKE_CYCLEミリ秒ごとにAを押す
     temp_time = (current_time - start_time) % (HANASHIKAKE_CYCLE+1); // 経過ミリ秒のHANASHIKAKE_CYCLE剰余を計算
     holdA = (float)temp_time / (float)HANASHIKAKE_CYCLE * 100.0; // 剰余から100%に変換
     if( holdA <= 35.0 ){ // HANASHIKAKE_CYCLE3.5割の時間はA押し、それ以外はAを離す
       if(!isholding){
         SwitchControlLibrary().PressButtonA();
         isholding = 1;
       }
     }else{
       if(isholding){
         SwitchControlLibrary().ReleaseButtonA();
         isholding = 0;
       }
     }
  }
  if(isholding) SwitchControlLibrary().ReleaseButtonA();
  TiltLeftStick( 0, 0, 0, 0); // スティック位置を戻す

  // 自分のポケモンに話しかけている場合は、会話キャンセル
  // 野生のポケモンの場合は「↓」Key 2回なので「はい」
  delay(1000);
  PushKey("A",    HOLDTIME, 1100); // →もっときかせて!loop or 仲間に加えてあげますか?→はい
  PushKey("Down", HOLDTIME, 700); // →遊んでおいで or →いいえ
  PushKey("Down", HOLDTIME, 700); // →なんでもない or →はい
  PushKey("A",    HOLDTIME, 1200); // →クリック


  // ここまでで左端から探索は完了
  // ※万が一途中で話しかけてしまいカメラが止まっても、ここからで
  // 右端から探索をかけて野生ポケモンを探す

  TiltLeftStick( 90, 1.0, 2000, 0); // 右端までカメラを倒す

  TiltLeftStick( 270, 0.9, 0, 0); // 左側スティック入力
  for( start_time=millis(), current_time=start_time, isholding=0 ; current_time - start_time < 2.5*1000UL ; current_time=millis() ){
     // HANASHIKAKE_CYCLEミリ秒ごとにAを押す
     temp_time = (current_time - start_time) % (HANASHIKAKE_CYCLE+1); // 経過ミリ秒のHANASHIKAKE_CYCLE剰余を計算
     holdA = (float)temp_time / (float)HANASHIKAKE_CYCLE * 100.0; // 剰余から100%に変換
     if( holdA <= 35.0 ){ // HANASHIKAKE_CYCLE3.5割の時間はA押し、それ以外はAを離す
       if(!isholding){
         SwitchControlLibrary().PressButtonA();
         isholding = 1;
       }
     }else{
       if(isholding){
         SwitchControlLibrary().ReleaseButtonA();
         isholding = 0;
       }
     }
  }
  if(isholding) SwitchControlLibrary().ReleaseButtonA();
  TiltLeftStick( 0, 0, 0, 0); // スティック位置を戻す

  PushKey("A",    HOLDTIME, 150); 
  PushKey("A",    HOLDTIME, 150); 
  PushKey("A",    HOLDTIME, 150); 
  PushKey("A",    HOLDTIME, 150); 
  PushKey("A",    HOLDTIME, 150); 
  
  // 自分のポケモンに話しかけている場合は、会話キャンセル
  // 野生のポケモンの場合は「↓」Key 2回なので「はい」
  delay(1000);
  PushKey("A",    HOLDTIME, 1100); // →もっときかせて!loop or 仲間に加えてあげますか?→はい
  PushKey("Down", HOLDTIME, 700); // →遊んでおいで or →いいえ
  PushKey("Down", HOLDTIME, 700); // →なんでもない or →はい
  PushKey("A",    HOLDTIME, 1600); // →クリック

  // ちょっと待機
  delay(1600);
  // 仮に話しかけていてもBボタンを2回(0.5秒くらいの間隔)だと1回分
  // Bを2回なので、キャンプ終了にはならない。
  PushKey("B",    HOLDTIME, 500); // キャンプを終了しますか?
  PushKey("B",    HOLDTIME, 500); // いいえ

  // 次のカレーを作ります。
  delay(2000);
  CheriBerryNum -= USING_BERRY; // 手持ちの「クラボのみ」個数をUSING_BERRY個減らす

}

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, 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){ // holdtime=0のときは押しっぱなし。
    delay(holdtime);
    SwitchControlLibrary().MoveLeftStick(128,128); // 傾きを直す
  }
  if(delaytime>0) delay(delaytime);
  return;
}

 

あとがき

今回の記事では、前回記事(Arduino自動化09)の改良版として、ポケモンキャンプでのカレー作りの自動化に、遊びに来たポケモンを仲間に加える機能を追加しました。

実は、「カレー自動調理」の記事がこのブログの中で執筆当初より根強い人気を誇る記事の一つだったこと、個人的にも本ブログの執筆記事で特に気に入っているものだったこともあり、「いつか絶対、『完全』自動化できるように改良しよう!」と意気込んでいたのでした。2021年1月2日の執筆から約半年後の本日6月9日に、ついにその夢を実現させ、完全自動化に成功しました。

やっぱり、Arduinoを使ったSwitch操作の自動化を考えたときに、スティック操作もボタン操作も余すこと無く活用している本プログラムは、動作する様子を眺めていて楽しいです。

ただ、今回のプログラムは、ポケモンが遊びに来る確率が最大でも1/7と低く、1試行にも2分ほどかかるという超長時間のデバッグを要するため、結構たいへんでした。

とはいえ、このプログラムの実装ができたことで、「『カレーのあかし』持ち色違い厳選」が現実的なものになりました。要するに、「証持ち色違い」という今までのポケモンの厳選の、さらにその上を行く難易度の厳選作業に、完全放置可能というアシストを付けて、足を踏み入れることができます

 

このプログラムを使って「カレーのあかし持ち色違いポケモンを捕まえることができた」という人が現れることを願って、あるいは、私がそれに出会えることを願って、本記事を公開させていただきます。

 

もし、この記事や本ブログが参考になっているよ!という方がいらっしゃいましたら、是非ともコメントやはてなスターを残してもらえると、私自身のやる気とモチベに繋がりますので、引き続きよろしくお願いいたします。

 

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

 

前回記事:【Arduino自動化09】ポケモンキャンプでカレー自動調理【カレーのあかし】

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

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

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