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.
Files changed (115) hide show
  1. jpoke-0.1.0/LICENSE +21 -0
  2. jpoke-0.1.0/MANIFEST.in +5 -0
  3. jpoke-0.1.0/PKG-INFO +226 -0
  4. jpoke-0.1.0/README.md +200 -0
  5. jpoke-0.1.0/pyproject.toml +92 -0
  6. jpoke-0.1.0/setup.cfg +4 -0
  7. jpoke-0.1.0/src/jpoke/__init__.py +22 -0
  8. jpoke-0.1.0/src/jpoke/core/__init__.py +12 -0
  9. jpoke-0.1.0/src/jpoke/core/ability_manager.py +167 -0
  10. jpoke-0.1.0/src/jpoke/core/ailment_manager.py +181 -0
  11. jpoke-0.1.0/src/jpoke/core/battle.py +934 -0
  12. jpoke-0.1.0/src/jpoke/core/command_manager.py +237 -0
  13. jpoke-0.1.0/src/jpoke/core/context.py +112 -0
  14. jpoke-0.1.0/src/jpoke/core/damage.py +395 -0
  15. jpoke-0.1.0/src/jpoke/core/event_logger.py +283 -0
  16. jpoke-0.1.0/src/jpoke/core/event_manager.py +212 -0
  17. jpoke-0.1.0/src/jpoke/core/field_manager.py +411 -0
  18. jpoke-0.1.0/src/jpoke/core/handler.py +117 -0
  19. jpoke-0.1.0/src/jpoke/core/item_manager.py +317 -0
  20. jpoke-0.1.0/src/jpoke/core/lethal.py +476 -0
  21. jpoke-0.1.0/src/jpoke/core/log_payload.py +172 -0
  22. jpoke-0.1.0/src/jpoke/core/move_executor.py +609 -0
  23. jpoke-0.1.0/src/jpoke/core/observation_builder.py +185 -0
  24. jpoke-0.1.0/src/jpoke/core/player.py +127 -0
  25. jpoke-0.1.0/src/jpoke/core/player_state.py +107 -0
  26. jpoke-0.1.0/src/jpoke/core/query.py +264 -0
  27. jpoke-0.1.0/src/jpoke/core/replay.py +127 -0
  28. jpoke-0.1.0/src/jpoke/core/speed_calculator.py +216 -0
  29. jpoke-0.1.0/src/jpoke/core/status_manager.py +163 -0
  30. jpoke-0.1.0/src/jpoke/core/switch_manager.py +321 -0
  31. jpoke-0.1.0/src/jpoke/core/turn_controller.py +354 -0
  32. jpoke-0.1.0/src/jpoke/core/volatile_manager.py +172 -0
  33. jpoke-0.1.0/src/jpoke/data/__init__.py +11 -0
  34. jpoke-0.1.0/src/jpoke/data/ability.py +3326 -0
  35. jpoke-0.1.0/src/jpoke/data/ailment.py +109 -0
  36. jpoke-0.1.0/src/jpoke/data/field/__init__.py +7 -0
  37. jpoke-0.1.0/src/jpoke/data/field/field.py +23 -0
  38. jpoke-0.1.0/src/jpoke/data/field/global_field.py +87 -0
  39. jpoke-0.1.0/src/jpoke/data/field/side_field.py +180 -0
  40. jpoke-0.1.0/src/jpoke/data/field/terrain.py +95 -0
  41. jpoke-0.1.0/src/jpoke/data/field/weather.py +125 -0
  42. jpoke-0.1.0/src/jpoke/data/item.py +2072 -0
  43. jpoke-0.1.0/src/jpoke/data/megaevol.py +98 -0
  44. jpoke-0.1.0/src/jpoke/data/models.py +93 -0
  45. jpoke-0.1.0/src/jpoke/data/move.py +54 -0
  46. jpoke-0.1.0/src/jpoke/data/moves/__init__.py +0 -0
  47. jpoke-0.1.0/src/jpoke/data/moves/move_a.py +1355 -0
  48. jpoke-0.1.0/src/jpoke/data/moves/move_ha.py +1731 -0
  49. jpoke-0.1.0/src/jpoke/data/moves/move_ka.py +1411 -0
  50. jpoke-0.1.0/src/jpoke/data/moves/move_ma.py +844 -0
  51. jpoke-0.1.0/src/jpoke/data/moves/move_na.py +547 -0
  52. jpoke-0.1.0/src/jpoke/data/moves/move_ra.py +374 -0
  53. jpoke-0.1.0/src/jpoke/data/moves/move_sa.py +1385 -0
  54. jpoke-0.1.0/src/jpoke/data/moves/move_symbol.py +126 -0
  55. jpoke-0.1.0/src/jpoke/data/moves/move_ta.py +1668 -0
  56. jpoke-0.1.0/src/jpoke/data/moves/move_wa.py +120 -0
  57. jpoke-0.1.0/src/jpoke/data/moves/move_ya.py +152 -0
  58. jpoke-0.1.0/src/jpoke/data/nature.py +29 -0
  59. jpoke-0.1.0/src/jpoke/data/pokedex.json +21864 -0
  60. jpoke-0.1.0/src/jpoke/data/pokedex.py +21 -0
  61. jpoke-0.1.0/src/jpoke/data/signature_items.py +41 -0
  62. jpoke-0.1.0/src/jpoke/data/type_chart.py +443 -0
  63. jpoke-0.1.0/src/jpoke/data/volatile.py +989 -0
  64. jpoke-0.1.0/src/jpoke/enums/__init__.py +18 -0
  65. jpoke-0.1.0/src/jpoke/enums/command.py +234 -0
  66. jpoke-0.1.0/src/jpoke/enums/event.py +450 -0
  67. jpoke-0.1.0/src/jpoke/enums/interrupt.py +67 -0
  68. jpoke-0.1.0/src/jpoke/enums/logcode.py +64 -0
  69. jpoke-0.1.0/src/jpoke/exceptions.py +28 -0
  70. jpoke-0.1.0/src/jpoke/handlers/__init__.py +0 -0
  71. jpoke-0.1.0/src/jpoke/handlers/ability.py +3564 -0
  72. jpoke-0.1.0/src/jpoke/handlers/ability_paradox.py +130 -0
  73. jpoke-0.1.0/src/jpoke/handlers/ailment.py +165 -0
  74. jpoke-0.1.0/src/jpoke/handlers/field.py +611 -0
  75. jpoke-0.1.0/src/jpoke/handlers/item.py +2009 -0
  76. jpoke-0.1.0/src/jpoke/handlers/lethal.py +761 -0
  77. jpoke-0.1.0/src/jpoke/handlers/move.py +192 -0
  78. jpoke-0.1.0/src/jpoke/handlers/move_attack.py +3665 -0
  79. jpoke-0.1.0/src/jpoke/handlers/move_status.py +3046 -0
  80. jpoke-0.1.0/src/jpoke/handlers/volatile.py +1432 -0
  81. jpoke-0.1.0/src/jpoke/model/__init__.py +7 -0
  82. jpoke-0.1.0/src/jpoke/model/ability.py +77 -0
  83. jpoke-0.1.0/src/jpoke/model/ailment.py +70 -0
  84. jpoke-0.1.0/src/jpoke/model/effect.py +153 -0
  85. jpoke-0.1.0/src/jpoke/model/field.py +76 -0
  86. jpoke-0.1.0/src/jpoke/model/item.py +69 -0
  87. jpoke-0.1.0/src/jpoke/model/move.py +169 -0
  88. jpoke-0.1.0/src/jpoke/model/pokemon.py +1128 -0
  89. jpoke-0.1.0/src/jpoke/model/stats.py +47 -0
  90. jpoke-0.1.0/src/jpoke/model/volatile.py +59 -0
  91. jpoke-0.1.0/src/jpoke/players/__init__.py +9 -0
  92. jpoke-0.1.0/src/jpoke/players/tree_search_player.py +298 -0
  93. jpoke-0.1.0/src/jpoke/py.typed +0 -0
  94. jpoke-0.1.0/src/jpoke/types/__init__.py +73 -0
  95. jpoke-0.1.0/src/jpoke/types/ability.py +317 -0
  96. jpoke-0.1.0/src/jpoke/types/ailment.py +4 -0
  97. jpoke-0.1.0/src/jpoke/types/global_field.py +4 -0
  98. jpoke-0.1.0/src/jpoke/types/item.py +270 -0
  99. jpoke-0.1.0/src/jpoke/types/literals.py +136 -0
  100. jpoke-0.1.0/src/jpoke/types/move.py +722 -0
  101. jpoke-0.1.0/src/jpoke/types/poke_env.py +107 -0
  102. jpoke-0.1.0/src/jpoke/types/pokemon.py +1292 -0
  103. jpoke-0.1.0/src/jpoke/types/side_field.py +4 -0
  104. jpoke-0.1.0/src/jpoke/types/terrain.py +4 -0
  105. jpoke-0.1.0/src/jpoke/types/volatile.py +78 -0
  106. jpoke-0.1.0/src/jpoke/types/weather.py +4 -0
  107. jpoke-0.1.0/src/jpoke/utils/__init__.py +8 -0
  108. jpoke-0.1.0/src/jpoke/utils/constants.py +20 -0
  109. jpoke-0.1.0/src/jpoke/utils/copy_utils.py +45 -0
  110. jpoke-0.1.0/src/jpoke/utils/lethal_dist.py +105 -0
  111. jpoke-0.1.0/src/jpoke/utils/math.py +41 -0
  112. jpoke-0.1.0/src/jpoke.egg-info/PKG-INFO +226 -0
  113. jpoke-0.1.0/src/jpoke.egg-info/SOURCES.txt +113 -0
  114. jpoke-0.1.0/src/jpoke.egg-info/dependency_links.txt +1 -0
  115. 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.
@@ -0,0 +1,5 @@
1
+ prune tests
2
+ prune docs
3
+ prune scripts
4
+ prune .claude
5
+ prune .loop
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,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -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