サンプル Bot
シンプルなものから複雑なものまで 4 つのサンプル。どれもそのまま動き、各ロジックが SDK の機能に対応しています。完全なリファレンスブレインもあります。
サンプルはすべて brains/examples/ にあります。後のサンプルは前のサンプルを継承し、新しい部分だけを追加しています。順番に読むことをおすすめします。
| サンプル | 学べること | 実行方法 |
|---|---|---|
hello_bot.py | 採集(1 鉱山に 5 人、満員なら伐採へ)、ワーカーの生産(キューは 1 体だけ)、人口建物の建設、建設が止まった建物の再開。4 種族すべてで動きます | python tools/play.py --bot brains/examples/hello_bot.py |
rush_bot.py | 兵舎と祭壇(なければ build_near で建てる)、ヒーロー優先(死んだら蘇生)、スキルポイントがあれば習得、1 波分たまったらアタックムーブ | … --bot brains/examples/rush_bot.py |
macro_bot.py | ビルドオーダー + 建て終えたら自分で鉱山に戻る(Shift)、人口で詰まったら即座に補充、兵舎のキューは 1 体、攻撃/防御アップグレード、ティアアップと上位ユニット、地上の実際の移動距離で目標を選んで経路をたどる | … --bot brains/examples/macro_bot.py --speed 200 |
micro_bot.py | 内政の上に戦闘の制御を追加:最も早く倒せる敵に集中攻撃、瀕死のユニットを後退、ヒーローの生存、夜は勝てるクリープキャンプを選ぶ、敵が本拠地まで来たら防衛に戻る。1 ティックのコマンドは 1 バッチで送信 | … --bot brains/examples/micro_bot.py --fair |
hello_bot と rush_bot のコメントには、実機で踏んだ落とし穴が記録されています。たとえば「毎回最初のワーカーを選んで家を建てさせたら、ファーム 3 つがすべて建設途中のまま放置された」「ハードコードした兵舎の座標がちょうど森の中で、3 分経っても 1 つも建たなかった」など。コードよりもコメントを読むほうが得るものは多いはずです。
hello_bot:経済
# 種族 -> (ワーカー, タウンホール群, 人口建物)
RACES = {
"h": ("hpea", {"htow", "hkee", "hcas"}, "hhou"),
"o": ("opeo", {"ogre", "ostr", "ofrt"}, "otrb"),
"u": ("uaco", {"unpl", "unp1", "unp2"}, "uzig"),
"e": ("ewsp", {"etol", "etoa", "etoe"}, "emow"),
}
MINE_CAP = 5 # 1 鉱山あたり最大 5 人(それ以上は収入が増えない)
LUMBER_CREW = 5 # 伐採の人数:各鉱山の採金 5 人 + この人数 = ワーカーの目標数
やることは 3 つです。暇なワーカーに金を採掘させる(鉱山ごとの人数は自分で記録し、満員なら伐採へ)。ワーカーが足りなければ生産する(キューには 1 体だけ)。人口が上限に近づいたら、建設中でないワーカーを選んでタウンホールの近くに人口建物を建てる(ヒューマンとオークは、建設が止まった建物にワーカーを送って建設を再開させます)。
rush_bot:出兵と出撃
hello_bot に 3 つを追加しています。兵舎と祭壇がなければ建てる。祭壇でヒーローを出し(死んだらまず蘇生。ヒーローは唯一)、スキルポイントがあれば習得する。兵が 8 体たまったら全員で敵のタウンホールへアタックムーブし、大きく削られたら帰還して再びためる。ティックごとに戦闘を中断しないよう、命令は暇な兵にだけ出します。
macro_bot:内政の基本
TECH = {
"h": dict(order=["halt", "hbar", "hbla", "hlum"], altar="halt", hero="Hamg", skills=["AHwe", "AHbz", "AHab"],
barracks="hbar", soldiers=["hfoo", "hrif", "hkni"], smith="hbla", upgrades=["Rhme", "Rhar", "Rhra", "Rhla"],
tiers=["hkee", "hcas"]),
...
}
プロプレイヤーが毎試合やっていることで、それぞれが SDK の機能に対応しています。ビルドオーダー表 + gather(..., queue="after") で建設後に鉱山へ戻る。production().blocked で人口の詰まりを検出する。g.queue で兵舎のキューを 1 体に保つ。can_do で次のレベルの攻撃/防御アップグレードを研究できるかエンジンに問い合わせる。ティアアップと上位ユニット(実機での教訓:ずっとティア 1 のままでいたら、23 分でティア 3 のナイトとグリフォンライダーに押し切られた)。path_distance で目標を選び、path() で経由点をたどる。
micro_bot:戦闘が始まったら
def _fight(self, g, army, foes, home, now):
...
visible = [e for e in foes if e.visible_to(me)] # 見えない目標は拒否される(1001)
atk = [s for s in (g.stats(u) for u in fighters) if s]
target = min(visible, key=lambda e: _ttk(g, atk, e)) # 最も近い敵ではなく、最も早く倒せる敵
idle_or_other = [u for u in fighters if g.current_target(u) is None
or g.current_target(u).handle != target.handle]
if idle_or_other:
g.attack(idle_or_other, target)
実機:5 分間で 1497 ティック、3023 コマンド、エラー 0。
リファレンスブレイン:完全な AI
brains/xwar3/ は拡張、クリーピング、出撃をこなす完全な AI で、3 層で構成されています。
| 層 | 場所 | 周期 | 役割 |
|---|---|---|---|
| 戦略層 | strategy/ | 秒単位 | AMAI 式の複数戦略の選択と切り替え、ビルド表、カウンターユニット、ヒーロー選択。オプションでLLM 戦略アドバイザー |
| リフレックス層 | reflex/(4 つの独立プロセス) | 100 ms 単位 | 生存、スペル使用、集中攻撃、アイテム拾い |
| 勝率モデル | worldmodel/ | — | 勝てるかどうか(推論サブセット) |
複数のプロセスはクレームテーブルでユニットを共有し、優先度によって誰が制御するかを決めます。手動操作 95 > 生存 90 > スキル回避 85 > スペル使用 80 > アイテム拾い 70 > … > 戦略 50 > ワーカー割り当て 45。あなたの Bot はテーブル上では bot として扱われ、デフォルトの優先度は 50 です。
リファレンスブレインは SDK の低レベル層(w3cmd / act)を直接使い、マップ全体の情報に大きく依存しています。「考え方」の参考には向いていますが、LLM にそのまま真似させることはおすすめしません。AMAI のデータが必要です。start.bat が初回のデプロイ時に AMAI の公開リポジトリから取得して生成します(AMAI は独自ライセンスのため、生成物は git に含めません。うまくいかなかった場合は start.bat setup で再試行します)。
リファレンスブレインを起動する最も簡単な方法は Farsight コンソール です。「インスタンスと開始設定」ページでインスタンス番号にチェックを入れ、「テスト開始」をクリックします。