ポケモンのPT選定AIを作ろう!【Part2】

さて、Part1ではShowdownのローカルサーバーを構築しました。
次は、自動対戦システムのプロトタイプを作っていきましょう。これで、強制的に戦績を測れるというわけです。

実はShowdownには、poke-envというPythonでバトルAIの実権ができる便利ライブラリが存在します。

さて、今回からは本格的にプログラムを触っていきます。
ここからPCの性能がそれなりに必要となって来るので、メインPCで動作していきましょう。こちらはWindows11を使用します。

Pythonのバージョンは3.10を事前に用意しておいてください。
メインPCで使うフォルダを作成し、そのフォルダに移動します。普段使ってるエクスプローラ(Windowsのフォルダ管理用としてデフォルトで入ってるあれ)のパス(C: > user > desktop みたいなの)が表示されているところをクリックし、“cmd“ と入力してそのディレクトリに移動済みのコマンドプロンプトを表示させます。
ちなみに、私はDドライブ直下にPokemonAIというフォルダで行います。

py -3.10 -m venv venv

と入力し、3.10の仮想環境を作成しましょう。
完了したら

.\venv\Scripts\activate

で、作成した仮想環境を起動します。

(venv) D:\PokemonAI>python --version
Python 3.10.11

となれば成功です。

今後の開発環境(コーディングする環境)の起動方法

  • 作成したディレクトリに移動(D:\PokemonAI)
  • コマンドプロンプトを表示(パスの表示されているところに “cmd”)
  • 仮想環境の起動(.\venv\Scripts\activate)

これが必須となります。

早速コードを書こう!の前に、必要なパッケージのインストールを行いましょう。

pip install --upgrade pip
pip install poke-env

で、最低限使うためのパッケージがインストールされます。
次に接続テスト用のスクリプト(Pythonにおけるプログラムコードのこと)を用意しましょう。

表示から「拡張子を表示」をONにした状態で、テキストドキュメントを新規作成し、”poke_test.py”というファイル名および拡張子にしてください。
その後、下記のスクリプトを書き込み、保存します。

import json
import asyncio
import os
from datetime import datetime

from poke_env.player import Player
from poke_env.ps_client.server_configuration import ServerConfiguration
from poke_env import AccountConfiguration

# ローカルShowdownサーバーのWebSocket URL
ws_url = "ws://192.168.0.193:8058/showdown/websocket" # ←ちゃんとIPアドレスをローカルの物に変更してください。
server_config = ServerConfiguration(ws_url, ws_url)

account1 = AccountConfiguration("bot1", None)
account2 = AccountConfiguration("bot2", None)

# ログファイルの保存パスを生成
def get_log_path(username):
    os.makedirs("battle_log", exist_ok=True)
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    return f"battle_log/{username}_{timestamp}.json"

# ログ記録付きボット
class LoggingBot(Player):
    def __init__(self, log_path, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.log_path = log_path
        self.battle_data = []

    def choose_move(self, battle):
        self.battle_data.append({
            "turn": battle.turn,
            "opponent": battle.opponent_username,
            "active_pokemon": {
                "species": battle.active_pokemon.species,
                "hp": battle.active_pokemon.current_hp,
                "status": str(battle.active_pokemon.status)
            },
            "available_moves": [m.id for m in battle.available_moves],
            "opponent_hp": battle.opponent_active_pokemon.current_hp,
        })
        return self.choose_random_move(battle)

    async def save_log(self):
        with open(self.log_path, "w", encoding="utf-8") as f:
            json.dump(self.battle_data, f, indent=2, ensure_ascii=False)

async def main():
    log1 = get_log_path("bot1")
    log2 = get_log_path("bot2")

    bot1 = LoggingBot(log1, account_configuration=account1, server_configuration=server_config)
    bot2 = LoggingBot(log2, account_configuration=account2, server_configuration=server_config)

    await bot1.battle_against(bot2, n_battles=3)

    await bot1.save_log()
    await bot2.save_log()

    print(f"{bot1.username} won {bot1.n_won_battles}/3")
    print("ログ保存先:")
    print(f"  - {log1}")
    print(f"  - {log2}")

if __name__ == "__main__":
    asyncio.run(main())

サーバー側のPCで、Showdownサーバーが既に起動している場合停止し、

node pokemon-showdown start --no-security

を使って、再度起動します。
これにより、ログインが不要となり、ちゃんとbotが対戦できるようになります。

仮想環境を起動中のコマンドプロンプトで、”python poke_test.py”を実行し、実際に勝負をさせましょう!

コメントを残す

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