地图
每个赛季使用自己的地图。没有任何发布版本或仓库携带它们:管理员逐个文件上传到赛季中,每张地图上传成功后即公开。赛季进行期间,管理员可以停用一张地图或重新启用,但绝不会删除,因为在该地图上进行过的对局都引用着它。配对从赛季启用中的地图里为每场对局挑选地图,并随之分配种子,所以地图从来不由你选择。
GET /v1/games/ants/seasons/{slug}/maps 列出赛季的全部地图,不论是否启用,并附带席位数和大小。加上 ?boards=true 可以一并取得地图文件(与回放携带的 JSON 相同),或者用 GET .../maps/{map_id} 读取单张地图。网站上的赛季页面会把它们画出来。
每张地图都遵守的限制
赛季的地图可以是游戏限制之内的任何地图。卡带在其清单中以 limits.boards 声明这些限制:
| 最小 | 最大 | |
|---|---|---|
| 席位 | 2 | 8 |
| 每边 | 24 | 124 |
| 格子数 | — | 14,880 |
超出这三项中任何一项的上传,平台在存储之前就会拒绝。这些限制也是审核对你的承诺。管理员下周可能给赛季添加新地图,所以审核不能只在赛季今天拥有的地图上测试你的模型。审核在整个限制范围内测试它:用参考集探测每个参赛模型,参考集取自下面五张基础地图,覆盖从两个席位到八个、从最小边长到最大边长的范围。今天通过审核的模型可以在赛季之后添加的任何地图上对局。
请面向这些限制来设计。把清单中的 probe_dims 设为游戏允许的最大地图(14,880 格,即 120 × 124 的基础地图),并在那里测量适配器的开销(预算)。
基础地图
每个 ants 发布版本携带五张地图,每种大小各一张,此外别无其他。对局文件按 id 指定地图时,tinybrains 就在你的机器上用它们进行对局;tinybrains maps 列出它们,tinybrains maps export 把它们写出来,ants-starter 的对局文件也在它们上面进行对局。
| 地图 | 席位 | 地图 | 每席位蚁丘数 | 水域 | 第 0 回合每席位食物 | 设计 |
|---|---|---|---|---|---|---|
basic-tiny-2p | 2 | 24 × 24 | 1 | 18% | 8 · 争夺 | 柱廊,8 向对称 |
basic-small-3p | 3 | 36 × 36 | 1 | 40% | 11 · 均匀 | 洞窟,两条对角镜像 |
basic-medium-4p | 4 | 48 × 64 | 2 | 19% | 18 · 均匀 | 辫状,两条镜像 |
basic-large-6p | 6 | 80 × 96 | 1 | 20% | 18 · 主场 | 厅堂,两条镜像 |
basic-xlarge-8p | 8 | 120 × 124 | 2 | 30% | 24 · 均匀 | 洞窟,半周旋转 |
“水域”一列是每张随发布版本附带的地图实测的水域占比。第 0 回合之后,食物按对局隐藏的速率出现(世界)。五张中有三张是长方形,所以适配器里绝不要假设 rows == columns。
basic-tiny-2p
开阔的地面上散布着短小的水块,点状的柱廊护住每个蚁丘和它旁边的食物。24 × 24 是地图允许的最小边长,两个席位,每席位一个蚁丘,18% 的水域。12 条互不相交的路线把一个蚁丘与敌方蚁丘相连,相距 24 步。每个席位在第 0 回合有 8 份食物:几份在蚁丘旁,其余在两个席位争夺的地带。
第 0 回合的 basic-tiny-2p 地图:柱廊,8 向对称,偏移量 (12, 12)。
basic-small-3p
三块领土之间的地面被大片岩石填满。每个蚁丘坐落在一个开阔的洞窟里,洞窟之间有通道相连。地图为 36 × 36,40% 的水域,三个席位,每席位一个蚁丘,8 条互不相交的路线把一个蚁丘与最近的敌方蚁丘相连,相距 24 步。每个席位在第 0 回合有 11 份食物:几份在蚁丘旁,其余在陆地上任意位置。
第 0 回合的 basic-small-3p 地图:洞窟,两条对角镜像,偏移量 (12, 12)。
basic-medium-4p
长长的直墙成带状排列,被规律的缺口打断:一座辫状迷宫,通路众多,没有死路。地图为 48 × 64,19% 的水域,四个席位。每个席位有两个蚁丘,上下排列,相隔半张地图。18 条互不相交的路线把一个蚁丘与最近的敌方蚁丘相连,相距 20 步。每个席位在第 0 回合有 18 份食物:几份在蚁丘旁,其余在陆地上任意位置。
第 0 回合的 basic-medium-4p 地图:辫状,两条镜像,偏移量 (24, 16)。
basic-large-6p
地面上布满由柱子和十字组成的格栅,每个蚁丘立在一座上下有墙、两端敞开的厅堂里。地图为 80 × 96,20% 的水域,六个席位,每席位一个蚁丘。12 条互不相交的路线把一个蚁丘与最近的敌方蚁丘相连,相距 32 步。每个席位在第 0 回合有 18 份食物:几份在蚁丘旁,其余在该席位能最先到达的地面上。
第 0 回合的 basic-large-6p 地图:厅堂,两条镜像,偏移量 (40, 16)。
basic-xlarge-8p
长长的岩脊沿对角线横亘在各领土之间,每个蚁丘周围是开阔地。这张地图有游戏允许的最大边长:120 × 124,30% 的水域,八个席位,每席位两个蚁丘。15 条互不相交的路线把一个蚁丘与最近的敌方蚁丘相连,相距 46 步。每个席位在第 0 回合有 24 份食物:几份在蚁丘旁,其余在陆地上任意位置。对适配器来说,14,880 格上的八个席位在两方面都是最坏情况:它会看到从 1 到 7 的每一个所有者编号,而且要编码的格子最多。
第 0 回合的 basic-xlarge-8p 地图:洞窟,半周旋转,偏移量 (15, 93)。
每张地图的保证
不论地形如何,每张地图都保持以下性质。违反前三条中任何一条的地图,卡带都会拒绝,包括你自己编写的地图;在赛季上传时检查一次,每场对局之前再检查一次。按下一节描述的方式制作的地图还保持后三条。
- 每个席位的地图都相同。席位
k的地图是席位 0 的地图按地图的偏移量移动k次得到的,地图文件把偏移量记为symmetry: {dr, dc}。水域、蚁丘和第 0 回合的食物都精确到格地跟随这个偏移。 - 蚂蚁可以从任何一格陆地走到任何另一格陆地。蚂蚁只向四个方向移动,所以两格仅在角上相接的陆地不构成通路,而地图上没有食物可能落入的封闭死角。
- 每个蚁丘都有出路,而且每个席位的蚁丘数量相同。
- 每个蚁丘都有空间:至少两个开放的相邻格,并处在向各个方向至少延伸两格的空地中。
- 第 0 回合看不到任何敌方蚁丘:其他每个席位的蚁丘都在距离平方 77 之外。
- 同一席位的蚁丘彼此分开。每个蚁丘都有自己的一片领土和自己的基地。其中两个之间的最短步行距离至少十格,并且至少是到最近敌方蚁丘步行距离的五分之二。
地图如何制作
Ants 仓库中的工具 mapgen 把每张地图作为一个设计绘制出来,再由人来挑选。设计者用同样的方式制作赛季的地图和基础地图;两者只是去处不同。
在两种对称下绘制。第一种是公平性:席位 k 的地图是席位 0 的地图按地图偏移量移动 k 次得到的,卡带会检查这一点。第二种只决定地图的外观:围绕每个席位领土中心的镜像或旋转,即“设计”一列所写的。两个席位采用正方形完整的八向对称,五个席位采用四向旋转。三个、六个和七个席位采用镜像或半周旋转,因为它们的中心无法落在方格网上。mapgen 按领土在这种对称上放置形状:每个蚁丘周围的环、堡、柱子和厅堂,沿边界的河流,以及三块领土交汇处的湖泊和前哨。同一种构思在每张地图上都出现在同一类位置。
百里挑一。设计者指定一个槽位:一种大小,一种地形(开阔 open、洞穴 cave、迷宫 maze 或房间 rooms),一个席位数和一个蚁丘数;mapgen explore 为它绘制数百个候选。它保留可玩的那些:水域在该地形的范围内,相邻席位之间不止一条路线,死路少,蚁丘分散。设计者让每个席位都用同一策略试玩有希望的候选(mapgen playtest),淘汰各席位扩张速度不一致的地图。mapgen adopt 把选中的地图记为一份配方,而配方就是地图:没有任何种子能重新生成它,所以改进后的采样器绝不会重画一张已被选中的地图。
以其本身命名,按设计者的约定:<size>-<terrain>-<N>p-<H>h。一张四个席位、每席位两个蚁丘的大型迷宫地图就是 large-maze-4p-2h。赛季上传时会检查名称是否符合这个形式,以及 N 和 H 是否与文件一致;大小和地形两个词是设计者自己的说法,平台不对它们作任何承诺。
| 大小 | 最长边 | 最短边 |
|---|---|---|
| tiny | 24–32 | — |
| small | 33–48 | 至少 32 |
| medium | 49–64 | 至少 48 |
| large | 65–96 | 至少 64 |
| xlarge | 97–127 | 至少 96 |
地图的宽度绝不超过高度的三分之四。席位数取决于大小:地图在第 0 回合不能让你看到敌方蚁丘,所以席位越多,蚁丘之间需要的地面就越多。不论大小等级允许多少,游戏的限制把赛季地图的每边封顶在 124。
食物
每张地图在每个蚁丘的两到六步之内放两到三份食物(席位有三个或更多蚁丘时,每个蚁丘两份),其余按三种规则之一放置,即表中所写的:
| 食物 | 其余放在 |
|---|---|
| 主场 | 你走到它的距离比任何对手都短 6 步以上的地方 |
| 争夺 | 你和最近的对手走到它的距离相差不超过 6 步的地方 |
| 均匀 | 陆地上任意位置 |
在一些地图上,其中四分之一先放到边界的中点和领土交汇的角落。数量随席位拥有的地面和蚁丘增加:从 basic-tiny-2p 上的每席位 8 份到 basic-xlarge-8p 上的 24 份。
席位开局时每有一个蚁丘就有一只蚂蚁和 1 分,所以四个蚁丘意味着四只蚂蚁、4 分和四个要守的家。失去一个蚁丘的蚁群仍然从其余蚁丘出生蚂蚁。
偏移量与你的邻居
p 个席位的地图有一个偏移量,移动 p 次就回到原处。两个席位时,它把另一个席位放在相隔半数行、半数列或两者兼有的位置;更多席位时,各席位在一个点阵上等距分布。到最近敌方蚁丘的距离变化比地图大小所暗示的更大:从 basic-medium-4p 上的 20 步到 basic-xlarge-8p 上的 46 步。
观测相对于你给对手编号,而编号跟随偏移量:对手 j 就是从你出发移动 j 个偏移量的席位。对手 1 总是在你的蚁丘加上一个偏移量的位置,所以不论你坐在哪个席位,每个编号指的都是同一个邻居。对手 j 和对手 p − j 在相反方向上相距同样远,所以三个席位时两个对手都与你接壤。对手编号从 1 到 7。
墙挡不住视线
视野和攻击都能穿过水域。墙挡住行走,却挡不住视线;只有至少两格厚的墙才能挡住战斗:一格厚的墙两侧的两只蚂蚁相隔两格,在攻击半径之内。大多数墙一到两格厚。一些房间和堡垒的墙有三格厚,洞穴岩石则没有固定的厚度。
每张地图携带的数据
mapgen 把它在每张所制作地图上测得的数据记录在 generator.metrics 下,以席位 0 的第一个蚁丘为基准(偏移量使每个席位的都相同):routes(从该蚁丘周围的地面到最近敌方蚁丘周围的地面之间格子互不相交的路线数,最多计到 32)、enemy_walk 和 open_walk(走到那个敌方蚁丘的距离,以及没有水域时的同一段距离)、detour_pct(前者占后者的百分比)、home_view_land(它的蚂蚁在第 0 回合看到的陆地)、dead_end_pm(至多只有一个陆地邻格的陆地格数,每千格陆地)、water_pm(每千格中的水域数)、water_runs(地图水域掩码的游程对)和 food_per_seat。generator 还记录 mapgen 绘制该地图所用的配方、它的 family 和装饰性的 symmetry。卡带忽略所有这些;赛季上传的地图携带它们,只是因为 mapgen 写下了它们。
面向全部限制训练
种子和引擎共同决定一场对局,而地图是对局的一部分。回放携带它的地图,所以要重现一场对局就保留回放;仅凭地图名称无法重现。配对把对局分散到赛季启用中、且参赛池坐得满的地图上。一场对局的每个席位都是不同的参赛者(基线也算),所以八席位的地图要等到有八个参赛者有版本可配对时才会使用。
在从两个到八个的每一种席位数、每边最大 124 的每一种大小上训练和验证。基础地图覆盖这个范围,赛季的地图一经上传就公开,而 tinybrains maps check 会告诉你自己绘制的地图是否是赛季能使用的。在断定某项改动整体上改进了模型之前,先按地图的共同点(席位数、大小、地形)给结果分组。固定大小的计算图需要显式填充,或者另一种适应所有大小的表示,并把输出映射回真实坐标。