likes
comments
collection
share

Screeps工程化之数量控制模块

作者站长头像
站长
· 阅读数 28

前言

将Screeps的代码进行模块化后,可以将各个功能进行分离,互相不影响,本文将会介绍Screeps中如何进行creep的数量控制来维持房间资源的平衡和发展。本文仅为作者本人的游戏思路,并不是最佳实践,如有更好的实现方法可在评论区提出。

如何抽取配置项可以看专栏的文章《Screeps工程化之配置化》

Screeps工程化之数量控制模块

核心实现逻辑

/**
 * @module creep数量控制模块
 */
import {BUILDER, DEFENDER} from "../constant/roleConstant.js";
import {creatCreep, creepNum, getSortedRolesByWeight} from "../config/creepNum/creepNumCore.js";
import {countOccurrences} from "../utils.js";


/**
 * @description creep数量控制器
 */
export const creepNumController = (roomKey) => {
    deleteDeadCreep()
    const spawns = Memory.Rooms[roomKey].spawns.map((id) => Game.getObjectById(id))
    for (const spawn of spawns) {
        // const spawn = Game.spawns[name]
        if (!spawn.spawning) {
            creepNumJudge(spawn, roomKey)
        }
    }

}
/**
 * 生成creep核心判断逻辑
 * @param {StructureSpawn} spawn
 * @param {string} roomKey
 */
const creepNumJudge = (spawn, roomKey) => {
    //1.根据权重信息组成role的列表通过权重排序
    const role_list = getSortedRolesByWeight(roomKey, DEFENDER)
    //2.遍历新组装的角色信息
    for (const role of role_list) {
        //针对builder的特殊判断条件
        if (role === BUILDER) {
            if (judge(role, roomKey) && Game.rooms[roomKey].find(FIND_CONSTRUCTION_SITES).length !== 0) {
                creatCreep(spawn, roomKey, role)
                return;
            }
        } else {
            if (judge(role, roomKey)) {
                creatCreep(spawn, roomKey, role)
                return;
            }
        }
    }
}
/**
 * @description 判断数量是否满足生成creep的条件
 * @param {string} role
 * @param {string} roomKey
 * @returns {boolean}
 */
export const judge = (role, roomKey) => {
    return countOccurrences(getRoleList(roomKey), role) < creepNum(role, roomKey)
}

/**
 *@description 删除内存中死亡的creep
 */
const deleteDeadCreep = () => {
    for (let name in Memory.creeps) {
        if (!Game.creeps[name]) {
            delete Memory.creeps[name]
        }
    }
}

/**
 * @description 获取内存中存活的creep的角色
 * @returns {string[]}
 */
const getRoleList = (roomKey) => {
    deleteDeadCreep()
    /**
     * @description 角色列表
     * @type {string[]}
     */
    const roleList = []
    for (const creep of Game.rooms[roomKey].find(FIND_MY_CREEPS)) {
        roleList.push(creep.memory.role)
    }

    return roleList
}

详细介绍:

  1. deleteDeadCreep方法:在每次一进入该模块中就会删除一次已死亡的creep的内存。
  2. getRoleList方法:获取该房间内存活的creep并将其creep的role存入一个列表然后返回。
  3. judge方法:判断该房间,指定角色的creep是否为配置文件中的数量
  4. creepNumJudge方法:数量控制的核心逻辑,其中,getSortedRolesByWeight方法会返回一个以权重排序过后的角色列表,遍历返回的角色列表,符合条件就生成creep,其中角色为建筑者的creep还有额外的判断条件,本房间内存在建筑工地才生成。

所有的creep生成的数量都根据配置文件中的number字段决定,当该房间中的某一个角色的creep少于指定的值,就会生成一个creep,一直生成到指定数量。

比如这个房间内的upgrader(专门给控制器升级的creep)就需要3个

"upgrader": {
    role: UPGRADER,
    bodys: Array(7).fill(WORK)
        .concat(Array(7).fill(CARRY))
        .concat(Array(7).fill(MOVE)),
    number: 3,
    weight: 2,
    func: upgraderRun,
    sourcesIndex: 1
}

实现效果

Screeps工程化之数量控制模块

Screeps工程化之数量控制模块

转载自:https://juejin.cn/post/7367174168599298058
评论
请登录