jpoke 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jpoke-0.1.0/LICENSE +21 -0
- jpoke-0.1.0/MANIFEST.in +5 -0
- jpoke-0.1.0/PKG-INFO +226 -0
- jpoke-0.1.0/README.md +200 -0
- jpoke-0.1.0/pyproject.toml +92 -0
- jpoke-0.1.0/setup.cfg +4 -0
- jpoke-0.1.0/src/jpoke/__init__.py +22 -0
- jpoke-0.1.0/src/jpoke/core/__init__.py +12 -0
- jpoke-0.1.0/src/jpoke/core/ability_manager.py +167 -0
- jpoke-0.1.0/src/jpoke/core/ailment_manager.py +181 -0
- jpoke-0.1.0/src/jpoke/core/battle.py +934 -0
- jpoke-0.1.0/src/jpoke/core/command_manager.py +237 -0
- jpoke-0.1.0/src/jpoke/core/context.py +112 -0
- jpoke-0.1.0/src/jpoke/core/damage.py +395 -0
- jpoke-0.1.0/src/jpoke/core/event_logger.py +283 -0
- jpoke-0.1.0/src/jpoke/core/event_manager.py +212 -0
- jpoke-0.1.0/src/jpoke/core/field_manager.py +411 -0
- jpoke-0.1.0/src/jpoke/core/handler.py +117 -0
- jpoke-0.1.0/src/jpoke/core/item_manager.py +317 -0
- jpoke-0.1.0/src/jpoke/core/lethal.py +476 -0
- jpoke-0.1.0/src/jpoke/core/log_payload.py +172 -0
- jpoke-0.1.0/src/jpoke/core/move_executor.py +609 -0
- jpoke-0.1.0/src/jpoke/core/observation_builder.py +185 -0
- jpoke-0.1.0/src/jpoke/core/player.py +127 -0
- jpoke-0.1.0/src/jpoke/core/player_state.py +107 -0
- jpoke-0.1.0/src/jpoke/core/query.py +264 -0
- jpoke-0.1.0/src/jpoke/core/replay.py +127 -0
- jpoke-0.1.0/src/jpoke/core/speed_calculator.py +216 -0
- jpoke-0.1.0/src/jpoke/core/status_manager.py +163 -0
- jpoke-0.1.0/src/jpoke/core/switch_manager.py +321 -0
- jpoke-0.1.0/src/jpoke/core/turn_controller.py +354 -0
- jpoke-0.1.0/src/jpoke/core/volatile_manager.py +172 -0
- jpoke-0.1.0/src/jpoke/data/__init__.py +11 -0
- jpoke-0.1.0/src/jpoke/data/ability.py +3326 -0
- jpoke-0.1.0/src/jpoke/data/ailment.py +109 -0
- jpoke-0.1.0/src/jpoke/data/field/__init__.py +7 -0
- jpoke-0.1.0/src/jpoke/data/field/field.py +23 -0
- jpoke-0.1.0/src/jpoke/data/field/global_field.py +87 -0
- jpoke-0.1.0/src/jpoke/data/field/side_field.py +180 -0
- jpoke-0.1.0/src/jpoke/data/field/terrain.py +95 -0
- jpoke-0.1.0/src/jpoke/data/field/weather.py +125 -0
- jpoke-0.1.0/src/jpoke/data/item.py +2072 -0
- jpoke-0.1.0/src/jpoke/data/megaevol.py +98 -0
- jpoke-0.1.0/src/jpoke/data/models.py +93 -0
- jpoke-0.1.0/src/jpoke/data/move.py +54 -0
- jpoke-0.1.0/src/jpoke/data/moves/__init__.py +0 -0
- jpoke-0.1.0/src/jpoke/data/moves/move_a.py +1355 -0
- jpoke-0.1.0/src/jpoke/data/moves/move_ha.py +1731 -0
- jpoke-0.1.0/src/jpoke/data/moves/move_ka.py +1411 -0
- jpoke-0.1.0/src/jpoke/data/moves/move_ma.py +844 -0
- jpoke-0.1.0/src/jpoke/data/moves/move_na.py +547 -0
- jpoke-0.1.0/src/jpoke/data/moves/move_ra.py +374 -0
- jpoke-0.1.0/src/jpoke/data/moves/move_sa.py +1385 -0
- jpoke-0.1.0/src/jpoke/data/moves/move_symbol.py +126 -0
- jpoke-0.1.0/src/jpoke/data/moves/move_ta.py +1668 -0
- jpoke-0.1.0/src/jpoke/data/moves/move_wa.py +120 -0
- jpoke-0.1.0/src/jpoke/data/moves/move_ya.py +152 -0
- jpoke-0.1.0/src/jpoke/data/nature.py +29 -0
- jpoke-0.1.0/src/jpoke/data/pokedex.json +21864 -0
- jpoke-0.1.0/src/jpoke/data/pokedex.py +21 -0
- jpoke-0.1.0/src/jpoke/data/signature_items.py +41 -0
- jpoke-0.1.0/src/jpoke/data/type_chart.py +443 -0
- jpoke-0.1.0/src/jpoke/data/volatile.py +989 -0
- jpoke-0.1.0/src/jpoke/enums/__init__.py +18 -0
- jpoke-0.1.0/src/jpoke/enums/command.py +234 -0
- jpoke-0.1.0/src/jpoke/enums/event.py +450 -0
- jpoke-0.1.0/src/jpoke/enums/interrupt.py +67 -0
- jpoke-0.1.0/src/jpoke/enums/logcode.py +64 -0
- jpoke-0.1.0/src/jpoke/exceptions.py +28 -0
- jpoke-0.1.0/src/jpoke/handlers/__init__.py +0 -0
- jpoke-0.1.0/src/jpoke/handlers/ability.py +3564 -0
- jpoke-0.1.0/src/jpoke/handlers/ability_paradox.py +130 -0
- jpoke-0.1.0/src/jpoke/handlers/ailment.py +165 -0
- jpoke-0.1.0/src/jpoke/handlers/field.py +611 -0
- jpoke-0.1.0/src/jpoke/handlers/item.py +2009 -0
- jpoke-0.1.0/src/jpoke/handlers/lethal.py +761 -0
- jpoke-0.1.0/src/jpoke/handlers/move.py +192 -0
- jpoke-0.1.0/src/jpoke/handlers/move_attack.py +3665 -0
- jpoke-0.1.0/src/jpoke/handlers/move_status.py +3046 -0
- jpoke-0.1.0/src/jpoke/handlers/volatile.py +1432 -0
- jpoke-0.1.0/src/jpoke/model/__init__.py +7 -0
- jpoke-0.1.0/src/jpoke/model/ability.py +77 -0
- jpoke-0.1.0/src/jpoke/model/ailment.py +70 -0
- jpoke-0.1.0/src/jpoke/model/effect.py +153 -0
- jpoke-0.1.0/src/jpoke/model/field.py +76 -0
- jpoke-0.1.0/src/jpoke/model/item.py +69 -0
- jpoke-0.1.0/src/jpoke/model/move.py +169 -0
- jpoke-0.1.0/src/jpoke/model/pokemon.py +1128 -0
- jpoke-0.1.0/src/jpoke/model/stats.py +47 -0
- jpoke-0.1.0/src/jpoke/model/volatile.py +59 -0
- jpoke-0.1.0/src/jpoke/players/__init__.py +9 -0
- jpoke-0.1.0/src/jpoke/players/tree_search_player.py +298 -0
- jpoke-0.1.0/src/jpoke/py.typed +0 -0
- jpoke-0.1.0/src/jpoke/types/__init__.py +73 -0
- jpoke-0.1.0/src/jpoke/types/ability.py +317 -0
- jpoke-0.1.0/src/jpoke/types/ailment.py +4 -0
- jpoke-0.1.0/src/jpoke/types/global_field.py +4 -0
- jpoke-0.1.0/src/jpoke/types/item.py +270 -0
- jpoke-0.1.0/src/jpoke/types/literals.py +136 -0
- jpoke-0.1.0/src/jpoke/types/move.py +722 -0
- jpoke-0.1.0/src/jpoke/types/poke_env.py +107 -0
- jpoke-0.1.0/src/jpoke/types/pokemon.py +1292 -0
- jpoke-0.1.0/src/jpoke/types/side_field.py +4 -0
- jpoke-0.1.0/src/jpoke/types/terrain.py +4 -0
- jpoke-0.1.0/src/jpoke/types/volatile.py +78 -0
- jpoke-0.1.0/src/jpoke/types/weather.py +4 -0
- jpoke-0.1.0/src/jpoke/utils/__init__.py +8 -0
- jpoke-0.1.0/src/jpoke/utils/constants.py +20 -0
- jpoke-0.1.0/src/jpoke/utils/copy_utils.py +45 -0
- jpoke-0.1.0/src/jpoke/utils/lethal_dist.py +105 -0
- jpoke-0.1.0/src/jpoke/utils/math.py +41 -0
- jpoke-0.1.0/src/jpoke.egg-info/PKG-INFO +226 -0
- jpoke-0.1.0/src/jpoke.egg-info/SOURCES.txt +113 -0
- jpoke-0.1.0/src/jpoke.egg-info/dependency_links.txt +1 -0
- jpoke-0.1.0/src/jpoke.egg-info/top_level.txt +1 -0
jpoke-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 tmwork1
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
jpoke-0.1.0/MANIFEST.in
ADDED
jpoke-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: jpoke
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Event-driven Pokemon Champions single-battle simulation library (unofficial)
|
|
5
|
+
Author-email: Tomoo Mari <tmtm.holmes@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/tmwork1/jpoke
|
|
8
|
+
Project-URL: Repository, https://github.com/tmwork1/jpoke
|
|
9
|
+
Project-URL: Issues, https://github.com/tmwork1/jpoke/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/tmwork1/jpoke/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: pokemon,battle,simulator,bot
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Topic :: Games/Entertainment :: Turn Based Strategy
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Classifier: Natural Language :: Japanese
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# jpoke
|
|
28
|
+
|
|
29
|
+
ポケモンバトルシミュレーション開発用の Python ライブラリ。イベント駆動でポケモンの技・特性・アイテム・
|
|
30
|
+
状態異常・場の効果などを再現し、bot 開発や乱数調整・ダメージ計算・木探索などの用途に使う。
|
|
31
|
+
|
|
32
|
+
jpoke is an event-driven Python library for simulating Pokémon Champions single battles, reproducing
|
|
33
|
+
moves, abilities, items, status conditions, and field effects. It targets bot development, RNG tuning,
|
|
34
|
+
damage calculation, and tree search.
|
|
35
|
+
|
|
36
|
+
> 本プロジェクトは株式会社ポケモン・任天堂・株式会社ゲームフリークとは無関係の非公式(fan-made)
|
|
37
|
+
> プロジェクトです。
|
|
38
|
+
> This is an unofficial, fan-made project and is not affiliated with, endorsed by, or sponsored by
|
|
39
|
+
> Nintendo, Game Freak, or The Pokémon Company.
|
|
40
|
+
|
|
41
|
+
## 対象範囲
|
|
42
|
+
|
|
43
|
+
- **対象はポケモンチャンピオンズのシングルバトルのみ**(ダブルバトル等は対象外)
|
|
44
|
+
- 技・特性・アイテム・ポケモンなどの仕様ソースは **第9世代(スカーレット・バイオレット)** を基本とし、
|
|
45
|
+
ポケモンチャンピオンズ側でルールが異なる場合はそちらを優先する
|
|
46
|
+
- 第9世代で実装されていない技・アイテム・特性・ポケモンなどは実装しない
|
|
47
|
+
|
|
48
|
+
このプロジェクトの規約・アーキテクチャの詳細は
|
|
49
|
+
[CLAUDE.md](https://github.com/tmwork1/jpoke/blob/main/CLAUDE.md) を参照(この README の対象範囲の
|
|
50
|
+
定義を正とし、CLAUDE.md 側はこの記述を参照する)。
|
|
51
|
+
|
|
52
|
+
## インストール
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install jpoke
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`requires-python = ">=3.10"`。型アノテーションは Python 3.10+ の構文(`X | Y`, `list[X]`)を使用する。
|
|
59
|
+
|
|
60
|
+
バージョニングは [Semantic Versioning](https://semver.org/lang/ja/) に準拠するが、0.x 系の間は
|
|
61
|
+
minor バージョンの更新(例: 0.1.0 → 0.2.0)でも破壊的変更が入る場合がある。変更履歴は
|
|
62
|
+
[CHANGELOG.md](https://github.com/tmwork1/jpoke/blob/main/CHANGELOG.md) を参照。
|
|
63
|
+
|
|
64
|
+
## クイックスタート
|
|
65
|
+
|
|
66
|
+
もっとも低レベルな API(`Battle` / `Player` / `Pokemon`)だけを使った最小例:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from jpoke import Battle, Player, Pokemon
|
|
70
|
+
|
|
71
|
+
player1 = Player("Player 1")
|
|
72
|
+
player1.team.append(Pokemon("ピカチュウ", move_names=["でんこうせっか"]))
|
|
73
|
+
player2 = Player("Player 2")
|
|
74
|
+
player2.team.append(Pokemon("フシギダネ", move_names=["たいあたり"]))
|
|
75
|
+
|
|
76
|
+
# n_selected: 選出数(チームが1匹だけの場合は1にする。デフォルトは3)
|
|
77
|
+
battle = Battle((player1, player2), n_selected=1)
|
|
78
|
+
battle.start()
|
|
79
|
+
|
|
80
|
+
while battle.judge_winner() is None and battle.turn < 100:
|
|
81
|
+
# commands=None の場合は各 Player.choose_command() が使われる
|
|
82
|
+
# (デフォルト実装は利用可能な最初のコマンドを選ぶだけの単純なプレイヤー)
|
|
83
|
+
battle.step()
|
|
84
|
+
|
|
85
|
+
print(battle.judge_winner().username) # 勝者の名前
|
|
86
|
+
battle.print_logs() # このターンのログを表示
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## アーキテクチャ
|
|
90
|
+
|
|
91
|
+
イベント駆動モデルを採用している:
|
|
92
|
+
|
|
93
|
+
1. バトルロジックが `Event` を発火する
|
|
94
|
+
2. `EventManager` が登録済み `Handler` を優先度順に呼び出す
|
|
95
|
+
3. 各 `Handler` は `HandlerReturn(value, stop_event)` を返す
|
|
96
|
+
4. ハンドラの登録は `data/ability.py`, `data/item.py`, `data/move.py` などで行う
|
|
97
|
+
|
|
98
|
+
| クラス/モジュール | 役割 |
|
|
99
|
+
|---|---|
|
|
100
|
+
| `core/battle.py` `Battle` | バトル全体の状態管理・ターン進行 |
|
|
101
|
+
| `core/turn_controller.py` | ターン順・行動順の制御 |
|
|
102
|
+
| `core/event_manager.py` | イベント発火・ハンドラ呼び出し |
|
|
103
|
+
| `core/handler.py` `Handler` | ハンドラ定義(subject, subject_spec, 関数) |
|
|
104
|
+
| `core/context.py` `BaseContext` / `EventContext` / `AttackContext` | ハンドラに渡すイベントコンテキスト(攻撃フローは `AttackContext`、それ以外は `EventContext`) |
|
|
105
|
+
| `model/` | `Pokemon`, `Move`, `Field` などのモデル |
|
|
106
|
+
| `data/` | `ability.py`, `move.py`, `item.py` など — 各エンティティのデータ定義とハンドラ登録 |
|
|
107
|
+
| `handlers/` | `ability.py`, `ability_paradox.py`, `ailment.py`, `field.py`, `item.py`, `lethal.py`, `move.py`, `move_attack.py`, `move_status.py`, `volatile.py` など — ハンドラ実装 |
|
|
108
|
+
| `enums/` | `Event`, `Command`, `Interrupt`, `LogCode` |
|
|
109
|
+
| `types/` | `Stat`, `Type`, `AilmentName`, `VolatileName` など Literal 型の定義 |
|
|
110
|
+
|
|
111
|
+
技データ(`data/move.py`)は五十音の行ごとに `data/moves/move_<行>.py` へ分割されている
|
|
112
|
+
(`data/move.py` はそれらを統合する薄いファイル)。
|
|
113
|
+
|
|
114
|
+
## ドキュメント
|
|
115
|
+
|
|
116
|
+
| ディレクトリ | 役割 |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `docs/spec/` | 技・アイテム・特性・場の効果の挙動仕様 |
|
|
119
|
+
| `docs/plan/` | 実行計画と優先順位 |
|
|
120
|
+
| `docs/progress/` | カテゴリ別の実装追跡(`ability.md`, `item.md`, `move.md` 等) |
|
|
121
|
+
| `docs/tests/` | テスト一覧(`scripts/generate_test_list.py` で生成) |
|
|
122
|
+
|
|
123
|
+
## 実装状況
|
|
124
|
+
|
|
125
|
+
`docs/progress/*.md` に基づく件数(データ定義済みの実数、内部用の空エントリ等を除く):
|
|
126
|
+
|
|
127
|
+
| カテゴリ | 件数 |
|
|
128
|
+
|---|---|
|
|
129
|
+
| 特性(ability) | 310 |
|
|
130
|
+
| アイテム(item) | 247 |
|
|
131
|
+
| 技(move) | 733 |
|
|
132
|
+
| 揮発性状態(volatile) | 66 |
|
|
133
|
+
| 状態異常(ailment) | 7 |
|
|
134
|
+
| 場の効果(field: 天候・地形・グローバル・サイド) | 31 |
|
|
135
|
+
|
|
136
|
+
最新の詳細は `docs/progress/` 配下の各ファイルを参照。
|
|
137
|
+
|
|
138
|
+
## 開発(clone 前提)
|
|
139
|
+
|
|
140
|
+
ソースを直接編集する場合や、テストヘルパーを使ってピンポイントな状態検証をしたい場合は
|
|
141
|
+
リポジトリを clone してセットアップする。
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
git clone https://github.com/tmwork1/jpoke.git
|
|
145
|
+
cd jpoke
|
|
146
|
+
pip install -e .
|
|
147
|
+
|
|
148
|
+
# 開発(テスト・lint・型チェック)に必要な依存を含める場合
|
|
149
|
+
pip install -e . pytest pytest-cov ruff mypy
|
|
150
|
+
# または uv を使う場合
|
|
151
|
+
uv sync
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### テストヘルパーを使った検証
|
|
155
|
+
|
|
156
|
+
任意ターンでのピンポイントな状態検証や技の実行など、クイックスタートより細かい制御をしたい場合は
|
|
157
|
+
`tests/test_utils.py` のヘルパー(`start_battle` / `run_move` / `run_switch` 等)が便利。
|
|
158
|
+
これはテスト用のヘルパーだが、プロジェクトルートから実行すれば(`tests/` が import できる状態)
|
|
159
|
+
通常のスクリプトからも使える。詳細な使い方は
|
|
160
|
+
[tests/CLAUDE.md](https://github.com/tmwork1/jpoke/blob/main/tests/CLAUDE.md) を参照:
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
# プロジェクトルートから実行する想定(tests/ が import できる状態)
|
|
164
|
+
from jpoke import Pokemon
|
|
165
|
+
from tests import test_utils as t
|
|
166
|
+
|
|
167
|
+
battle = t.start_battle(
|
|
168
|
+
team0=[Pokemon("ピカチュウ", ability_name="せいでんき", move_names=["でんこうせっか"])],
|
|
169
|
+
team1=[Pokemon("カビゴン", move_names=["たいあたり"])],
|
|
170
|
+
accuracy=100, # 命中率を固定して再現性を上げる
|
|
171
|
+
)
|
|
172
|
+
t.run_move(battle, atk_idx=0, move_idx=0)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## テストの実行
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# 全テスト
|
|
179
|
+
python -m pytest tests/ -v
|
|
180
|
+
|
|
181
|
+
# カテゴリ別
|
|
182
|
+
python -m pytest tests/abilities/ -v
|
|
183
|
+
python -m pytest tests/items/ -v
|
|
184
|
+
python -m pytest tests/moves_attack/ -v
|
|
185
|
+
python -m pytest tests/moves_status/ -v
|
|
186
|
+
python -m pytest tests/volatiles/ -v
|
|
187
|
+
|
|
188
|
+
# 特定ファイル
|
|
189
|
+
python -m pytest tests/abilities/test_ability_ka.py -v
|
|
190
|
+
|
|
191
|
+
# 特定テスト関数(日本語関数名も可)
|
|
192
|
+
python -m pytest tests/abilities/ -k "ARシステム" -v
|
|
193
|
+
|
|
194
|
+
# カバレッジ付き
|
|
195
|
+
python -m pytest tests/ -q --cov=jpoke --cov-report=term
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
テストは `tests/` 直下(`test_ailment.py`, `test_copy.py`, `test_damage.py`, `test_field.py`,
|
|
199
|
+
`test_lethal.py` など)とサブディレクトリ(`abilities/`, `items/`, `moves_attack/`,
|
|
200
|
+
`moves_status/`, `volatiles/`)に分かれている。`tests/test_utils.py` はテストヘルパー(テスト対象外)。
|
|
201
|
+
|
|
202
|
+
## 開発ツール
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# lint
|
|
206
|
+
python -m ruff check src/ tests/ scripts/
|
|
207
|
+
|
|
208
|
+
# 型チェック(src/jpoke/core のみを対象に段階導入中)
|
|
209
|
+
python -m mypy
|
|
210
|
+
|
|
211
|
+
# 五十音順の維持・データ整合性チェック(--check は変更せず確認のみ)
|
|
212
|
+
python scripts/sort_handlers.py --check
|
|
213
|
+
python scripts/sort_data/sort_abilities.py --check
|
|
214
|
+
python scripts/sort_data/sort_items.py --check
|
|
215
|
+
python scripts/sort_data/sort_moves.py --check
|
|
216
|
+
python scripts/sort_tests.py --check tests/**/test_*.py
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
CI(`.github/workflows/test.yml`)で push/PR ごとに Windows + Linux × Python 3.10/3.12 のマトリクスで
|
|
220
|
+
テスト・lint・型チェックを実行する。`.github/workflows/nightly-fuzz.yml` が毎日 `scripts/fuzz_battle.py`
|
|
221
|
+
を random / tree_search の両プレイヤーモデル(`--player`)で実行し、回帰シードを検出する。`.pre-commit-config.yaml` を使うと
|
|
222
|
+
コミット前にこれらのチェック(の一部)をローカルで実行できる。
|
|
223
|
+
|
|
224
|
+
## ライセンス
|
|
225
|
+
|
|
226
|
+
MIT License
|
jpoke-0.1.0/README.md
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# jpoke
|
|
2
|
+
|
|
3
|
+
ポケモンバトルシミュレーション開発用の Python ライブラリ。イベント駆動でポケモンの技・特性・アイテム・
|
|
4
|
+
状態異常・場の効果などを再現し、bot 開発や乱数調整・ダメージ計算・木探索などの用途に使う。
|
|
5
|
+
|
|
6
|
+
jpoke is an event-driven Python library for simulating Pokémon Champions single battles, reproducing
|
|
7
|
+
moves, abilities, items, status conditions, and field effects. It targets bot development, RNG tuning,
|
|
8
|
+
damage calculation, and tree search.
|
|
9
|
+
|
|
10
|
+
> 本プロジェクトは株式会社ポケモン・任天堂・株式会社ゲームフリークとは無関係の非公式(fan-made)
|
|
11
|
+
> プロジェクトです。
|
|
12
|
+
> This is an unofficial, fan-made project and is not affiliated with, endorsed by, or sponsored by
|
|
13
|
+
> Nintendo, Game Freak, or The Pokémon Company.
|
|
14
|
+
|
|
15
|
+
## 対象範囲
|
|
16
|
+
|
|
17
|
+
- **対象はポケモンチャンピオンズのシングルバトルのみ**(ダブルバトル等は対象外)
|
|
18
|
+
- 技・特性・アイテム・ポケモンなどの仕様ソースは **第9世代(スカーレット・バイオレット)** を基本とし、
|
|
19
|
+
ポケモンチャンピオンズ側でルールが異なる場合はそちらを優先する
|
|
20
|
+
- 第9世代で実装されていない技・アイテム・特性・ポケモンなどは実装しない
|
|
21
|
+
|
|
22
|
+
このプロジェクトの規約・アーキテクチャの詳細は
|
|
23
|
+
[CLAUDE.md](https://github.com/tmwork1/jpoke/blob/main/CLAUDE.md) を参照(この README の対象範囲の
|
|
24
|
+
定義を正とし、CLAUDE.md 側はこの記述を参照する)。
|
|
25
|
+
|
|
26
|
+
## インストール
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install jpoke
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`requires-python = ">=3.10"`。型アノテーションは Python 3.10+ の構文(`X | Y`, `list[X]`)を使用する。
|
|
33
|
+
|
|
34
|
+
バージョニングは [Semantic Versioning](https://semver.org/lang/ja/) に準拠するが、0.x 系の間は
|
|
35
|
+
minor バージョンの更新(例: 0.1.0 → 0.2.0)でも破壊的変更が入る場合がある。変更履歴は
|
|
36
|
+
[CHANGELOG.md](https://github.com/tmwork1/jpoke/blob/main/CHANGELOG.md) を参照。
|
|
37
|
+
|
|
38
|
+
## クイックスタート
|
|
39
|
+
|
|
40
|
+
もっとも低レベルな API(`Battle` / `Player` / `Pokemon`)だけを使った最小例:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from jpoke import Battle, Player, Pokemon
|
|
44
|
+
|
|
45
|
+
player1 = Player("Player 1")
|
|
46
|
+
player1.team.append(Pokemon("ピカチュウ", move_names=["でんこうせっか"]))
|
|
47
|
+
player2 = Player("Player 2")
|
|
48
|
+
player2.team.append(Pokemon("フシギダネ", move_names=["たいあたり"]))
|
|
49
|
+
|
|
50
|
+
# n_selected: 選出数(チームが1匹だけの場合は1にする。デフォルトは3)
|
|
51
|
+
battle = Battle((player1, player2), n_selected=1)
|
|
52
|
+
battle.start()
|
|
53
|
+
|
|
54
|
+
while battle.judge_winner() is None and battle.turn < 100:
|
|
55
|
+
# commands=None の場合は各 Player.choose_command() が使われる
|
|
56
|
+
# (デフォルト実装は利用可能な最初のコマンドを選ぶだけの単純なプレイヤー)
|
|
57
|
+
battle.step()
|
|
58
|
+
|
|
59
|
+
print(battle.judge_winner().username) # 勝者の名前
|
|
60
|
+
battle.print_logs() # このターンのログを表示
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## アーキテクチャ
|
|
64
|
+
|
|
65
|
+
イベント駆動モデルを採用している:
|
|
66
|
+
|
|
67
|
+
1. バトルロジックが `Event` を発火する
|
|
68
|
+
2. `EventManager` が登録済み `Handler` を優先度順に呼び出す
|
|
69
|
+
3. 各 `Handler` は `HandlerReturn(value, stop_event)` を返す
|
|
70
|
+
4. ハンドラの登録は `data/ability.py`, `data/item.py`, `data/move.py` などで行う
|
|
71
|
+
|
|
72
|
+
| クラス/モジュール | 役割 |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `core/battle.py` `Battle` | バトル全体の状態管理・ターン進行 |
|
|
75
|
+
| `core/turn_controller.py` | ターン順・行動順の制御 |
|
|
76
|
+
| `core/event_manager.py` | イベント発火・ハンドラ呼び出し |
|
|
77
|
+
| `core/handler.py` `Handler` | ハンドラ定義(subject, subject_spec, 関数) |
|
|
78
|
+
| `core/context.py` `BaseContext` / `EventContext` / `AttackContext` | ハンドラに渡すイベントコンテキスト(攻撃フローは `AttackContext`、それ以外は `EventContext`) |
|
|
79
|
+
| `model/` | `Pokemon`, `Move`, `Field` などのモデル |
|
|
80
|
+
| `data/` | `ability.py`, `move.py`, `item.py` など — 各エンティティのデータ定義とハンドラ登録 |
|
|
81
|
+
| `handlers/` | `ability.py`, `ability_paradox.py`, `ailment.py`, `field.py`, `item.py`, `lethal.py`, `move.py`, `move_attack.py`, `move_status.py`, `volatile.py` など — ハンドラ実装 |
|
|
82
|
+
| `enums/` | `Event`, `Command`, `Interrupt`, `LogCode` |
|
|
83
|
+
| `types/` | `Stat`, `Type`, `AilmentName`, `VolatileName` など Literal 型の定義 |
|
|
84
|
+
|
|
85
|
+
技データ(`data/move.py`)は五十音の行ごとに `data/moves/move_<行>.py` へ分割されている
|
|
86
|
+
(`data/move.py` はそれらを統合する薄いファイル)。
|
|
87
|
+
|
|
88
|
+
## ドキュメント
|
|
89
|
+
|
|
90
|
+
| ディレクトリ | 役割 |
|
|
91
|
+
|---|---|
|
|
92
|
+
| `docs/spec/` | 技・アイテム・特性・場の効果の挙動仕様 |
|
|
93
|
+
| `docs/plan/` | 実行計画と優先順位 |
|
|
94
|
+
| `docs/progress/` | カテゴリ別の実装追跡(`ability.md`, `item.md`, `move.md` 等) |
|
|
95
|
+
| `docs/tests/` | テスト一覧(`scripts/generate_test_list.py` で生成) |
|
|
96
|
+
|
|
97
|
+
## 実装状況
|
|
98
|
+
|
|
99
|
+
`docs/progress/*.md` に基づく件数(データ定義済みの実数、内部用の空エントリ等を除く):
|
|
100
|
+
|
|
101
|
+
| カテゴリ | 件数 |
|
|
102
|
+
|---|---|
|
|
103
|
+
| 特性(ability) | 310 |
|
|
104
|
+
| アイテム(item) | 247 |
|
|
105
|
+
| 技(move) | 733 |
|
|
106
|
+
| 揮発性状態(volatile) | 66 |
|
|
107
|
+
| 状態異常(ailment) | 7 |
|
|
108
|
+
| 場の効果(field: 天候・地形・グローバル・サイド) | 31 |
|
|
109
|
+
|
|
110
|
+
最新の詳細は `docs/progress/` 配下の各ファイルを参照。
|
|
111
|
+
|
|
112
|
+
## 開発(clone 前提)
|
|
113
|
+
|
|
114
|
+
ソースを直接編集する場合や、テストヘルパーを使ってピンポイントな状態検証をしたい場合は
|
|
115
|
+
リポジトリを clone してセットアップする。
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
git clone https://github.com/tmwork1/jpoke.git
|
|
119
|
+
cd jpoke
|
|
120
|
+
pip install -e .
|
|
121
|
+
|
|
122
|
+
# 開発(テスト・lint・型チェック)に必要な依存を含める場合
|
|
123
|
+
pip install -e . pytest pytest-cov ruff mypy
|
|
124
|
+
# または uv を使う場合
|
|
125
|
+
uv sync
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### テストヘルパーを使った検証
|
|
129
|
+
|
|
130
|
+
任意ターンでのピンポイントな状態検証や技の実行など、クイックスタートより細かい制御をしたい場合は
|
|
131
|
+
`tests/test_utils.py` のヘルパー(`start_battle` / `run_move` / `run_switch` 等)が便利。
|
|
132
|
+
これはテスト用のヘルパーだが、プロジェクトルートから実行すれば(`tests/` が import できる状態)
|
|
133
|
+
通常のスクリプトからも使える。詳細な使い方は
|
|
134
|
+
[tests/CLAUDE.md](https://github.com/tmwork1/jpoke/blob/main/tests/CLAUDE.md) を参照:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
# プロジェクトルートから実行する想定(tests/ が import できる状態)
|
|
138
|
+
from jpoke import Pokemon
|
|
139
|
+
from tests import test_utils as t
|
|
140
|
+
|
|
141
|
+
battle = t.start_battle(
|
|
142
|
+
team0=[Pokemon("ピカチュウ", ability_name="せいでんき", move_names=["でんこうせっか"])],
|
|
143
|
+
team1=[Pokemon("カビゴン", move_names=["たいあたり"])],
|
|
144
|
+
accuracy=100, # 命中率を固定して再現性を上げる
|
|
145
|
+
)
|
|
146
|
+
t.run_move(battle, atk_idx=0, move_idx=0)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## テストの実行
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# 全テスト
|
|
153
|
+
python -m pytest tests/ -v
|
|
154
|
+
|
|
155
|
+
# カテゴリ別
|
|
156
|
+
python -m pytest tests/abilities/ -v
|
|
157
|
+
python -m pytest tests/items/ -v
|
|
158
|
+
python -m pytest tests/moves_attack/ -v
|
|
159
|
+
python -m pytest tests/moves_status/ -v
|
|
160
|
+
python -m pytest tests/volatiles/ -v
|
|
161
|
+
|
|
162
|
+
# 特定ファイル
|
|
163
|
+
python -m pytest tests/abilities/test_ability_ka.py -v
|
|
164
|
+
|
|
165
|
+
# 特定テスト関数(日本語関数名も可)
|
|
166
|
+
python -m pytest tests/abilities/ -k "ARシステム" -v
|
|
167
|
+
|
|
168
|
+
# カバレッジ付き
|
|
169
|
+
python -m pytest tests/ -q --cov=jpoke --cov-report=term
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
テストは `tests/` 直下(`test_ailment.py`, `test_copy.py`, `test_damage.py`, `test_field.py`,
|
|
173
|
+
`test_lethal.py` など)とサブディレクトリ(`abilities/`, `items/`, `moves_attack/`,
|
|
174
|
+
`moves_status/`, `volatiles/`)に分かれている。`tests/test_utils.py` はテストヘルパー(テスト対象外)。
|
|
175
|
+
|
|
176
|
+
## 開発ツール
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# lint
|
|
180
|
+
python -m ruff check src/ tests/ scripts/
|
|
181
|
+
|
|
182
|
+
# 型チェック(src/jpoke/core のみを対象に段階導入中)
|
|
183
|
+
python -m mypy
|
|
184
|
+
|
|
185
|
+
# 五十音順の維持・データ整合性チェック(--check は変更せず確認のみ)
|
|
186
|
+
python scripts/sort_handlers.py --check
|
|
187
|
+
python scripts/sort_data/sort_abilities.py --check
|
|
188
|
+
python scripts/sort_data/sort_items.py --check
|
|
189
|
+
python scripts/sort_data/sort_moves.py --check
|
|
190
|
+
python scripts/sort_tests.py --check tests/**/test_*.py
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
CI(`.github/workflows/test.yml`)で push/PR ごとに Windows + Linux × Python 3.10/3.12 のマトリクスで
|
|
194
|
+
テスト・lint・型チェックを実行する。`.github/workflows/nightly-fuzz.yml` が毎日 `scripts/fuzz_battle.py`
|
|
195
|
+
を random / tree_search の両プレイヤーモデル(`--player`)で実行し、回帰シードを検出する。`.pre-commit-config.yaml` を使うと
|
|
196
|
+
コミット前にこれらのチェック(の一部)をローカルで実行できる。
|
|
197
|
+
|
|
198
|
+
## ライセンス
|
|
199
|
+
|
|
200
|
+
MIT License
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "jpoke"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Event-driven Pokemon Champions single-battle simulation library (unofficial)"
|
|
5
|
+
authors = [
|
|
6
|
+
{ name = "Tomoo Mari", email = "tmtm.holmes@gmail.com" }
|
|
7
|
+
]
|
|
8
|
+
license = "MIT"
|
|
9
|
+
license-files = ["LICENSE"]
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
dependencies = []
|
|
13
|
+
keywords = ["pokemon", "battle", "simulator", "bot"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Topic :: Games/Entertainment :: Turn Based Strategy",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
23
|
+
"Natural Language :: Japanese",
|
|
24
|
+
"Typing :: Typed",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
Homepage = "https://github.com/tmwork1/jpoke"
|
|
29
|
+
Repository = "https://github.com/tmwork1/jpoke"
|
|
30
|
+
Issues = "https://github.com/tmwork1/jpoke/issues"
|
|
31
|
+
Changelog = "https://github.com/tmwork1/jpoke/blob/main/CHANGELOG.md"
|
|
32
|
+
|
|
33
|
+
[dependency-groups]
|
|
34
|
+
dev = [
|
|
35
|
+
"pytest>=8.0",
|
|
36
|
+
"pytest-cov>=5.0",
|
|
37
|
+
"ruff>=0.5",
|
|
38
|
+
"mypy>=1.10",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[build-system]
|
|
42
|
+
requires = ["setuptools>=61.0"]
|
|
43
|
+
build-backend = "setuptools.build_meta"
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.packages.find]
|
|
46
|
+
where = ["src"]
|
|
47
|
+
|
|
48
|
+
[tool.setuptools.package-data]
|
|
49
|
+
jpoke = ["py.typed"]
|
|
50
|
+
"jpoke.data" = ["*.json"]
|
|
51
|
+
|
|
52
|
+
[tool.pytest.ini_options]
|
|
53
|
+
testpaths = ["tests"]
|
|
54
|
+
pythonpath = ["src"]
|
|
55
|
+
|
|
56
|
+
[tool.ruff]
|
|
57
|
+
line-length = 200
|
|
58
|
+
target-version = "py310"
|
|
59
|
+
src = ["src"]
|
|
60
|
+
|
|
61
|
+
[tool.ruff.lint]
|
|
62
|
+
# E/W: pycodestyle, F: pyflakes, B: flake8-bugbear(B006 が可変デフォルト引数を検出する)
|
|
63
|
+
select = ["E", "F", "W", "B"]
|
|
64
|
+
ignore = [
|
|
65
|
+
"E741", # あいまいな変数名 l: data/move.py が handlers.lethal を l として import している
|
|
66
|
+
"B905", # zip(strict=) は挙動変更(長さ不一致で例外)を伴うため個別に判断して導入する
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
[tool.ruff.lint.per-file-ignores]
|
|
70
|
+
"**/__init__.py" = ["F401"] # 再エクスポートのための import
|
|
71
|
+
"src/jpoke/types/*.py" = ["E501"] # scripts/generate_literals による自動生成の長行
|
|
72
|
+
"scripts/**" = ["F841"] # 実験用スクリプトの未使用変数は許容
|
|
73
|
+
|
|
74
|
+
[tool.mypy]
|
|
75
|
+
# 段階導入: まず core のみを対象にし、警告を解消しながら対象を広げる
|
|
76
|
+
# follow_imports = "silent" で core が import する core 外モジュール(handlers/model 等)の
|
|
77
|
+
# 型エラーは黙殺する(段階導入の対象外のため)。core 自身のエラーのみ報告させる。
|
|
78
|
+
python_version = "3.10"
|
|
79
|
+
files = ["src/jpoke/core"]
|
|
80
|
+
mypy_path = "src"
|
|
81
|
+
ignore_missing_imports = true
|
|
82
|
+
check_untyped_defs = false
|
|
83
|
+
follow_imports = "silent"
|
|
84
|
+
|
|
85
|
+
[tool.coverage.run]
|
|
86
|
+
source = ["src/jpoke"]
|
|
87
|
+
|
|
88
|
+
[tool.coverage.report]
|
|
89
|
+
exclude_lines = [
|
|
90
|
+
"pragma: no cover",
|
|
91
|
+
"if TYPE_CHECKING:",
|
|
92
|
+
]
|
jpoke-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""jpokeパッケージ - ポケモンバトルシミュレータ。
|
|
2
|
+
|
|
3
|
+
バトル、プレイヤー、ポケモン、技、特性、アイテムなどの主要クラスと、
|
|
4
|
+
ポケモン図鑑データを提供します。
|
|
5
|
+
"""
|
|
6
|
+
from importlib.metadata import version as _version
|
|
7
|
+
|
|
8
|
+
from .core import Battle, Player
|
|
9
|
+
from .model import Pokemon, Ability, Item, Move
|
|
10
|
+
from .data import POKEDEX
|
|
11
|
+
|
|
12
|
+
__version__ = _version("jpoke")
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"Battle",
|
|
16
|
+
"Player",
|
|
17
|
+
"Pokemon",
|
|
18
|
+
"Ability",
|
|
19
|
+
"Item",
|
|
20
|
+
"Move",
|
|
21
|
+
"POKEDEX",
|
|
22
|
+
]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from .handler import Handler, HandlerReturn
|
|
2
|
+
from .lethal import StateDist, LethalHandler, LethalContext
|
|
3
|
+
from .context import BaseContext, EventContext, AttackContext
|
|
4
|
+
from .event_manager import EventManager
|
|
5
|
+
from .battle import Battle
|
|
6
|
+
from .player import Player
|
|
7
|
+
from .player_state import PlayerState
|
|
8
|
+
from .ailment_manager import AilmentManager
|
|
9
|
+
from .volatile_manager import VolatileManager
|
|
10
|
+
from .field_manager import SideFieldManager
|
|
11
|
+
from .status_manager import StatusManager
|
|
12
|
+
from .query import PokemonQuery
|