ジムバトルの討伐時間の自動取得!ジムバトルDB作成プログラムを紹介!【ポケモンGO】【ジム防衛】

ごごちと申します。

これまでジムバトルの最適パーティを
考えてきました。

攻撃側の最適化
【ポケモンGO】ジムバトルにおける最適パーティを最短経路問題で考えます【バトルチーム】

防衛側の最適化
最適ジム防衛パーティを最短経路問題で考察しました!【ポケモンGO】【ジム防衛】


攻撃側と防衛側がお互いに最適化を行うことで
どのような組合せに行き着くのかを
知りたいと思っています。

今回はポケマピ様のダメージ計算ツールから
攻撃側ポケモンと防衛側ポケモンを指定すると
撃破時間を自動取得するプログラムを作成
したので紹介したいと思います。

DB自動取得プログラム実行の様子

ポケマピ様のダメージ計算ツールに対して、
撃破時間を自動で取得する
Pythonプログラムを作成しました。
コードは後ほど記載します。

ダメージ計算ツールにポケモンの情報を入力し、
撃破時間を取得するプログラムになっています。

  1. 自分ポケモン入力
  2. 敵ポケモン入力
  3. 自分Lv入力
  4. 敵Lv入力
  5. 「計算する」ボタン押下
  6. 指定した技組合せの撃破時間を取得

実行後に生成される撃破時間DB

プログラム実行後には上の様なテーブルが生成され
.xlsx形式で保存されます。
各セルには
攻撃側のポケモン、
ノーマルアタック、
スペシャルアタック
に対応する防衛ポケモンへの
討伐時間が記載されています。

攻撃側候補ポケモンと
防衛側候補ポケモンを増やすと
さらに広大なテーブルデータになります。

DB自動取得プログラムの背景

これまで紹介したページでは、
攻撃側も防衛側も、
候補ポケモンの数や技の組合せが
限定されていました。
以下の2点がその理由です。

  1. 撃破時間DB作成が手作業で時間がかかる
  2. 組合せで計算量が爆発的に増えてしまう

今回は1.「撃破時間DB作成」を
自動化することにしました。

上の図の様に、
攻撃側と防衛側のポケモンの組合せの数だけ
撃破時間を取得する必要があります。
攻撃側候補が18匹、
防衛側候補が18匹とすると、
18×18 = 324 通り
の撃破時間が必要になります。

ポケマピ様のダメージ計算ツール
1組当たり撃破時間を取得し、
excelなどに転記するのにかかる時間が
平均20秒とすると、
324通りの時間を入力するのに
108分=2時間弱かかります。
追加で候補ポケモンを増やしたい場合などには
後から作業が増えてしまいます。

さらに技の組合せなどを変えたも
一から作業をやり直す必要があります。
しかし、データ取得を自動化することで、
技の組合せが異なる場合でも
同様にデータ取得することができます。

まとめると、
DB自動取得プログラムを作成することで
以下の様なメリットがあります。

  • DB作成の自動化(放置でDB作成)
  • DB作成の効率化(手作業に比べ10倍以上の速度で取得可能)
  • データの幅がひろがる(異なる技の組合せでも取得可能)

DB自動取得プログラム

import numpy as np
import pandas as pd
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.webdriver import ActionChains

#chromeでアクセス
options = webdriver.ChromeOptions()
################################################################################################################################################################
# chromedriver.exeの場所を指定
service = webdriver.chrome.service.Service(executable_path = 'C:\\Users\\xxxxxxxx\\Desktop\\PokemonGo_project\\20230607_scraping\\chromedriver.exe')
################################################################################################################################################################
driver = webdriver.Chrome(service=service, options=options)
driver.get('https://pokemongo-get.com/damagecal/')
time.sleep(10)

select_list_A = driver.find_element(By.XPATH, '//*[@id="app"]/div[1]/div[1]/div/div[3]/div[4]/select')
# Selectオブジェクトを作成
dropdownA = Select(select_list_A)
# 選択肢を選択
dropdownA.select_by_visible_text('50')

select_list_B = driver.find_element(By.XPATH, '//*[@id="app"]/div[1]/div[2]/div/div[3]/div[4]/select')
# Selectオブジェクトを作成
dropdownB = Select(select_list_B)
# 選択肢を選択
dropdownB.select_by_visible_text('50')

#シャドウポケモンON
#shadow_button = driver.find_element(By.XPATH, '//*[@id="app"]/div[1]/div[1]/div/table/tbody/tr/td[2]')
#shadow_button.click()

# 検索欄取得
search_box_A = driver.find_element(By.XPATH, '//*[@id="app"]/div[1]/div[1]/div/input')
search_box_B = driver.find_element(By.XPATH, '//*[@id="app"]/div[1]/div[2]/div/input')

# ポケモンを受け取ったら撃破時間を取得する関数

def get_defeat_time(attack_pokemon, defence_pokemon):

    keyword_A=attack_pokemon[0]
    keyword_B=defence_pokemon

    search_box_A.clear()
    search_box_B.clear()

    search_box_A.send_keys(keyword_A)
    search_box_B.send_keys(keyword_B)

    result_button = driver.find_element(By.XPATH, '//*[@id="app"]/button[2]')
    result_button.click()

    time.sleep(2)

    # result_tableの要素を取得
    result_table = driver.find_element(By.XPATH, '//*[@id="app"]/div[3]/div[6]/table/tbody')
    # result_tableから<tr>要素を取得
    tr_elements = result_table.find_elements(By.TAG_NAME, 'tr')
    
    

    # 取得した<tr>要素を処理する
    for tr in tr_elements[1:]:
        figures = tr.find_elements(By.XPATH, './/*[contains(@class,"text-center")]')
        rank=figures[0].text
        defeat_time = float(figures[1].text)
        moves = tr.find_elements(By.XPATH, './/*[contains(@class,"flex-list-auto")]')
        fast_move = moves[0].text
        special_move = moves[1].text
        if (attack_pokemon[1] in fast_move) and (attack_pokemon[2] in special_move):
            print(keyword_A, ' vs ', keyword_B)
            print(rank)
            print(fast_move,special_move)
            print(defeat_time)
            return defeat_time
            
attack_pokemons = [
                   ["カミツルギ","はっぱカッター","リーフブレード"],
                   ["レシラム","ほのおのキバ","クロスフレイム"],
                   ["カイオーガ","たきのぼり","こんげんのはどう"],
                   ["デンジュモク","でんきショック","ほうでん"],
                   ["マンムー","こなゆき","ゆきなだれ"],
                   ["ルカリオ","カウンター","はどうだん"],
                   ["ウツロイド","どくづき","ヘドロばくだん"],
                   ["グラードン","マッドショット","だんがいのつるぎ"],
                   ["ファイヤー","つばさでうつ","ゴッドバード"],
                   ["ミュウツー","サイコカッター","サイコブレイク"],
                   ["フェローチェ","むしくい","むしのさざめき"],
                   ["ラムパルド","うちおとす","いわなだれ"],
                   ["ゲンガー","したでなめる","シャドーボール"],
                   ["パルキア","ドラゴンテール","りゅうせいぐん"],
                   ["ダークライ","バークアウト","あくのはどう"],
                   ["メタグロス","バレットパンチ","コメットパンチ"],
                   ["サーナイト","あまえる","マジカルシャイン"],
                   ["ポリゴンZ","ロックオン","はかいこうせん"],
                   ]
    
defence_pokemons = ["ハピナス",
                    "ソーナンス",
                    "ラッキー",
                    "トゲキッス",
                    "メタグロス",
                    "カイリュー",
                    "ベトベトン",
                    "ベトベトン(アローラ)",
                    "ヤドキング(ガラル)",
                    "デスカーン",
                    "デスバーン",
                    "ミカルゲ",
                    "ヌメルゴン",
                    "ミロカロス",
                    "カビゴン",
                    "ラグラージ",
                    "パンプジン(とくだい)",
                    "サーフゴー",
                    ]

# 動作確認&デモ用
attack_pokemons=attack_pokemons[:3]
defence_pokemons=defence_pokemons[:2]

df_time = pd.DataFrame(index=np.arange(len(attack_pokemons)),columns=["attack_pokemon","fast_move","special_move"])

for i,attack_pokemon in enumerate(attack_pokemons):
    df_time.loc[i,"attack_pokemon"]=attack_pokemon[0]
    df_time.loc[i,"fast_move"]=attack_pokemon[1]
    df_time.loc[i,"special_move"]=attack_pokemon[2]
    for j,defence_pokemon in enumerate(defence_pokemons):
        defeat_time = get_defeat_time(attack_pokemon,defence_pokemon)
        df_time.loc[i,defence_pokemon]=defeat_time
        
df_time.to_excel("check_demo.xlsx")
        
#いったん停止
time.sleep(2)

driver.quit()

chromedriverを使ってポケマピ様の
ダメージ計算ツールに対して
自動で検索&データ取得を行い
結果をexcelファイルに格納しています。

chromedriverを使った
スクレイピングについては、
こちらをご参照ください
DebankのPythonスクレイピングプログラムの環境構築!chromedriverまで解説!

今後について

ポケマピ様のダメージ計算ツールから効率的に
撃破時間テーブルを作成するプログラムを
紹介しました!

先ほども書いたように、
単なる効率化だけではなく、
データの幅が広がるのが魅力です。
例えば、
スペシャルアタック2に別タイプの技を設定し、
撃破時間が短くなる場合も
考えることができます。

これでデータ取得の効率化はできたので、
あとは最適化の計算量を減らす方法について
学びたいと思います!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA