文档 工具

AI 方案

一个方案就是一套完整的 AI。在远见里一键切换,正在打的这一局也能立刻换人接管;导出 zip 分享给别人,导入别人的方案来测,每个方案的战绩自动统计。

一个方案 = 一套完整的 AI:一个文件夹 + 一份说明书 scheme.json + 代码。每个游戏实例选一个方案;在远见里一键切换,正在打的这一局也能立刻换人接管。

别人分享的方案导入进来是单独的一块,和你自己的方案互不影响;想改就「复制到我的」。

schemes/
  mine/<id>/          我的方案:自己写的,或从别的方案复制来改的(随便改,下一局生效)
  installed/<id>/     已安装:别人分享的 zip 解开在这里(第一次运行前要确认信任)
brains/xwar3/         内置:参考大脑(完整 AI)
brains/examples/      内置:四个教学示例 hello / rush / macro / micro,玩伴示例 buddy,两个玩法模组(英雄肉鸽、无尽守城)

方案不一定是替你打的 AI:kind: mod 的方案是一套玩法规则,你自己玩,它出题,见 玩法模组。

在远见里用

「AI 方案」页(左边栏「系统 → AI 方案」):

操作做什么
导入方案(zip)装进 installed/;同一个 id 已经装过会问要不要替换(替换后要重新确认信任)
用到实例…选实例 +「立刻生效」(停掉当前 AI,新方案接管这一局)或「下次开始测试生效」
复制到我的拷一份到 mine/,作者记成「我」、版本 0.1.0,并记下复制自哪个方案的哪个版本
导出 zip打包成 <id>-<版本>.zip,发给别人就是分享
打开文件夹在资源管理器里打开方案目录,直接改代码
信任别人的方案第一次运行前必须点(见下文「信任和安全」)
最近战绩这个方案每一局的胜负、时长、结束原因
删除只能删「我的」和「已安装」;有实例正在用的不让删

实例卡片上也多了一行「AI 方案」:下拉选方案 →「切换(立刻生效)」。实例没在跑时按钮叫「选定」,下次「开始测试」就按它起 AI。

说明书 scheme.json

{
  "format": 1,
  "id": "fast-rush",
  "name": "三分钟速攻",
  "version": "1.2.0",
  "author": "某某",
  "description": "一句话说明这个 AI 打什么路子",
  "entry": "rush_bot.py",
  "class": "RushBot",
  "fair": true,
  "hz": 5,
  "races": ["human", "orc"],
  "license": "MIT"
}
字段必填说明
id✔小写字母、数字、-、_,2 ~ 41 个字符
entry✔方案目录里的一个 .py 文件(不许绝对路径,不许 ..)
kind默认 bot(openwar3.Bot 的子类,替你打);mod = 玩法模组(openwar3.Mod 的子类,固定不走公平模式、不按对战规则判胜负)
class入口文件里的 Bot(或 Mod)子类名;不写就取入口文件里最后一个 openwar3.Bot 子类
fair默认 true:只看得见视野里的东西,和对战平台同一个规则。false = 全图可见,也才能用 JASS 通道(玩伴需要)
judge默认 true:按对战规则判胜负。RPG / 玩伴方案写 false
hzon_tick 每秒调几次,默认 5
format说明书格式版本,现在是 1;比本机 OpenWar3 新的会被拒绝并提示更新
其余name、version、author、description、races、license、homepage、forked_from 只用于展示

方案目录会加进 Python 的模块搜索路径,入口文件可以 import 同目录下的其他文件。第三方包(numpy、torch……)不会自动安装 —— 在 description 里写清楚需要什么。

最小的方案,两个文件就够:

# my_bot.py
from openwar3 import Bot

class MyBot(Bot):
    def on_tick(self, g):
        for w in g.idle_workers():
            mine = g.nearest(g.gold_mines(), w)
            if mine:
                g.gather(w, mine)
{"id": "my-first", "name": "我的第一个 AI", "entry": "my_bot.py"}

放进 schemes/mine/my-first/,远见刷新一下就能看见。更省事的起点:在「内置」里挑一个示例,点「复制到我的」。

运行方式和战绩

方案由方案运行器跑(远见的「开始测试 / 切换」起的就是它):

python tools/run_scheme.py --inst 20 --scheme builtin/micro --hours 6
  • 每个实例一个常驻的监督进程,每一局起一个子进程跑方案:方案代码崩了不连累监督进程;「我的方案」改了代码,下一局自动用新的。
  • 每局结束记一行战绩:方案、版本、作者、胜负、原因、游戏时长、出错次数。远见里的胜率就从这里统计。

胜负怎么判:

情况记成
对面建筑全没了胜
我方建筑全没了(兵还活着也算 —— 对战就是这么判负的)负
我方单位全没了负
在远见里手动结束 / 停止未定
切换时这局已经打了 60 游戏秒以上(半路接手)单独计数,不进胜率
游戏时钟长时间不走未定

分出胜负后运行器会关掉结算画面,按「下一局设置」开下一局,方案接着接管 —— 可以挂一整夜攒战绩。暂停不算结束:暂停期间 Bot 照常运行,只有游戏时钟停住。

信任和安全

方案就是代码,运行时拥有和你本人一样的权限(能读写文件、能联网)。所以:

  • installed/ 里的方案默认不被信任,远见和运行器都拒绝运行,直到你点「信任」;
  • 替换安装同一个 id 的方案会重置信任(新版本等于新代码);
  • 导入时会检查:zip 不超过 50 MB、不超过 2000 个文件;不许绝对路径和 ..(防止写到方案目录外面);说明书不合法或入口文件不存在直接拒绝。

信任之前先「打开文件夹」读一遍代码。只从你信得过的人那里拿方案。

接口(给脚本用)

接口说明
GET /api/schemes方案列表 + 战绩 + 各实例选的、正在跑的方案
GET /api/schemes/results?ref=一个方案最近 30 局
POST /api/schemes/import导入 zip
GET /api/schemes/export?ref=下载 zip
POST /api/schemes/fork复制到我的
POST /api/schemes/trust信任
DELETE /api/schemes?ref=删除(有实例在用时拒绝)
POST /api/instances/{n}/scheme给实例换方案:立刻接管这一局,或下次开始测试生效

Python 里直接用库:from openwar3 import schemes(list_schemes、install_zip、export_zip、fork、trust、stats……)。

以后:方案网站

导出的 zip 就是分享的单位,网站只需要在外面加一层:在远见里一键上传;在网站上下载,走和「导入方案」完全相同的检查、同样要确认信任;可以选择上报战绩,网站按版本汇总胜率。远见里「分享到方案网站」的按钮已经留好了位置。进度见 路线图。