Automatic Plan

自动规划模块

在完成了基本的升级和填充能量之后,需要考虑的首要问题就是建造问题了。

在我上一版 Lucy 的 AI 当中,就已经写了一个自动规划模块。但是那个比较复杂,在 Apollo 的 AI 当中,我准备基于上次写的自动规划模块,进行一些精简。首先,最重要的就是定义接口,即我们希望怎么使用自动规划模块。

需要注意的是,建筑地是可以被踩的,所以最好是一次只建造一个地方。而自动规划模块应当支持对于房间内的规划,以及路径连接这两个功能。

对外,自动规划的功能应当仅仅是规划,不考虑怎么建造,以及什么时候建造。即,输入规划的请求,返回规划的位置或者说路径什么的。

而规划具体的建筑是以Unit为单元。Unit可以是非常具体的一系列建筑群,或者是某些单个的建筑,例如:Tower。Unit有许多可以配置的地方,例如选址等。而且,自动规划也应当考虑到不同建筑单元之间的关系,即某些建筑单元的选址依赖于尚未建造的另外的建筑单元。

因此,接口可以被定义为:

interface PlanModuleRegisterUnitOpts {
    /** 指定根据距离判定选址位置的参照对象 (到) */
    distanceReferencesTo? : ( StructureConstant | 'sources' | 'mineral' )[]
    /** 指定根据距离判定选址位置的参照对象 (从) */
    distanceReferencesFrom? : StructureConstant[]
    /** 与路径的位置关系 - 沿着路径 | 避免与路径重叠 */
    roadRelationship? : 'along' | 'avoid'
    /** 规划的本建筑单元数量 */
    amount? : number
    /** 可视化时文本 */
    visualizePinText? : string
    /** 可视化时颜色 */
    visualizeStrokeColor? : string
}

/** 自动规划模块 */
interface PlanModule {
    /** 注册建筑单元 - 按照注册顺序进行规划 */
    register(token: 'unit', unitName: string, unit: Unit, opts?: PlanModuleRegisterUnitOpts)
    /** 连接建筑单元 - 按照注册顺序进行规划 */
    register(token: 'road', roadName: string, unitNameU: string, unitNameV: string)
    /** 连接建筑单元和位置 - 按照注册顺序进行规划 */
    register(token: 'road', roadName: string, unitName: string, pos: RoomPosition)
    /** 连接位置 - 按照注册顺序进行规划 */
    register(token: 'road', roadName: string, posU: RoomPosition, posV: RoomPosition)
    /** 设定某房间建筑单元位置 (即非自动规划, 手动指定) */
    setUnitPos(roomName: string, unitName: string, pos: RoomPosition)
    /** 规划某房间的建筑单位或连接路径 */
    plan(roomName: string, token: 'unit' | 'road', name: string): { [structureType in StructureConstant]? : RoomPosition[] }
    /** 判定位置是否 已有/规划 了建筑 - 可用于一些不利用自动规划模块的建筑规划 */
    isAvailable(pos: RoomPosition): boolean
    /** 可视化 */
    visualize()
}

最后的效果如图:

Last updated