screep/main.js

416 lines
14 KiB
JavaScript
Raw Permalink Normal View History

2020-10-26 16:15:52 +08:00
/* eslint-disable no-console */
/* eslint-disable no-undef */
/* eslint-disable func-names */
/* eslint-disable camelcase */
const mount = require("./mount");
const init = require("./init");
const util = require("./utils");
2020-10-23 20:55:20 +08:00
function extra() {
2020-10-26 16:45:02 +08:00
// Game.map.visual.circle(Game.getObjectById('5bbcaaeb9099fc012e6326f1').pos)
// console.log(Game.getObjectById('5f953aa1ad1f54190745a9c3').pos)
// Memory.WorkingTarget.CONSTRUCTION_5f952fea10782b5f4ec3690a.working_creep_names=[]
2020-10-24 21:43:36 +08:00
}
2020-10-23 20:55:20 +08:00
function cleanCreeps() {
2020-10-26 16:45:02 +08:00
_.each(Object.keys(Memory.creeps), function (key) {
if (!Game.creeps[key]) {
console.log(`${key} is invalid, removed from Memory.creeps`);
delete Memory.creeps[key];
}
});
2020-10-18 22:00:22 +08:00
}
function cleanInvalidMemoryCreep() {
2020-10-26 16:45:02 +08:00
// 清理Memory中已经不存在的creep
_.each(Memory.WorkingTarget, function (target) {
_.remove(target.working_creep_names, function (creep_name) {
if (!Game.creeps[creep_name]) {
console.log(
`${creep_name} is invalid, removed from working_creep_names`
);
return true;
}
return false;
});
2020-10-26 16:15:52 +08:00
});
}
2020-10-24 15:24:24 +08:00
function cleanTargetMemory() {
2020-10-26 22:03:25 +08:00
_.each(Object.keys(Memory.WorkingTarget), function (target_key) {
const target = Memory.WorkingTarget[target_key];
2020-10-26 16:45:02 +08:00
if (!Game.getObjectById(target.id)) {
console.log(
`target ${target.id} is invalid, removed from Memory.WorkingTarget.Set their creep to idle`
);
_.each(target.working_creep_names, (creep_name) => {
Game.creeps[creep_name].working_target_id = undefined;
});
2020-10-26 22:03:25 +08:00
delete Memory.WorkingTarget[target_key];
2020-10-26 16:45:02 +08:00
}
});
2020-10-23 22:28:40 +08:00
}
2020-10-26 16:15:52 +08:00
function assign_creeps(opt) {
2020-10-26 16:45:02 +08:00
const { memory } = opt;
const { creep_name_to_assign_array } = opt; // 需要分配工作的creeps
_.each(creep_name_to_assign_array, function (creep_name) {
// 先计算每一个target目前有多少个creeps了
const working_creeps_of_target_array = []; // 记录每个target已有的creep数量
_.each(memory, (m) =>
working_creeps_of_target_array.push(m.working_creep_names.length)
);
const target_to_add_creep = _.filter(
memory,
(m) =>
m.working_creep_names.length ===
_.min(working_creeps_of_target_array)
); // 选择目前已有creep最少的对其添加creep
if (target_to_add_creep.length > 0) {
target_to_add_creep[0].working_creep_names.push(creep_name); // target记录自己安排的creep
Game.creeps[creep_name].working_target_id =
target_to_add_creep[0].id; // 将target安排给creep
}
});
2020-10-26 16:15:52 +08:00
}
2020-10-23 20:55:20 +08:00
function assign_transfer(target_memory) {
2020-10-26 16:45:02 +08:00
const NO_IDLE_TRANSFER = -1;
const OK_TRANSFER = 0;
const MEMORY_EMPTY = -2;
if (target_memory.length > 0) {
const idle_transfer = _.filter(
Game.creeps,
(creep) =>
!creep.working_target_id && creep.memory.role === "transfer"
);
if (idle_transfer.length > 0) {
// 一次只安排一个creep
const opt = {
memory: target_memory,
creep_name_to_assign_array: [idle_transfer[0].name],
};
assign_creeps(opt);
return OK_TRANSFER;
}
return NO_IDLE_TRANSFER;
}
2020-10-26 16:45:02 +08:00
return MEMORY_EMPTY;
}
2020-10-26 16:15:52 +08:00
// TODO:应该和assign_transfer_to_builder合并
2020-10-24 21:43:36 +08:00
function assign_transfer_to_harvester() {
2020-10-26 16:45:02 +08:00
// 判断有多少个picker的transfer为0
const harvester_without_creep = _.filter(Game.creeps, function (creep) {
return (
!Memory.WorkingTarget[creep.name] &&
creep.memory.role === "harvester"
); // Memory.WorkingTarget中没有这个harvester目标
});
_.each(harvester_without_creep, function (harvester_creep) {
Memory.WorkingTarget[harvester_creep.name] = {
id: harvester_creep.id,
working_creep_names: [],
cate: "harvester",
}; // 在Memory.WorkingTarget加入需要creep的Picker
});
const harvester_needs_creep_memory = _.filter(
Memory.WorkingTarget,
(memory) =>
memory.working_creep_names.length === 0 &&
memory.cate === "harvester"
); // 需要安排creep的harvester
assign_transfer(harvester_needs_creep_memory);
2020-10-23 20:55:20 +08:00
}
2020-10-18 22:00:22 +08:00
function assign_task() {
2020-10-26 16:45:02 +08:00
_.each(Object.keys(Game.creeps), (creep_name) => {
const creep = Game.creeps[creep_name];
creep.action();
});
2020-10-20 17:09:06 +08:00
}
2020-10-26 16:15:52 +08:00
function createBuilderCreep() {
2020-10-26 16:45:02 +08:00
// create new creep
const new_creep_name = `AUTO_CREATE_Builder_${util.uuid()}`;
const Re_code = Game.spawns.Spawn1.createCreep(
[MOVE, CARRY, WORK],
new_creep_name
);
if (Re_code === new_creep_name) {
Game.creeps[new_creep_name].memory.role = "builder";
console.log(`Create new creep ${new_creep_name}`);
} else {
// console.log(`failed to create builder with code ${Re_code}`);
}
2020-10-26 16:15:52 +08:00
}
function assign_transfer_to_builder() {
2020-10-26 16:45:02 +08:00
// 判断有多少个builder的transfer为0
const builder_without_creep = _.filter(Game.creeps, function (creep) {
return (
!Memory.WorkingTarget[creep.name] && creep.memory.role === "builder"
); // Memory.WorkingTarget中没有这个builder目标
});
_.each(builder_without_creep, function (builder) {
Memory.WorkingTarget[builder.name] = {
id: builder.id,
working_creep_names: [],
cate: "builder",
}; // 在Memory.WorkingTarget加入需要creep的builder
});
const builder_needs_creep_memory = _.filter(
Memory.WorkingTarget,
(memory) =>
memory.working_creep_names.length === 0 && memory.cate === "builder"
); // 需要安排creep的builder
2020-10-26 22:03:25 +08:00
if (builder_needs_creep_memory.length > 0) {
if (assign_transfer(builder_needs_creep_memory) === -1) {
console.log(
`no enough transfer to builder. Try to create a new one autmatically`
);
createBuilderCreep();
}
2020-10-26 16:45:02 +08:00
}
2020-10-23 20:55:20 +08:00
}
function assign_builder_to_construction(construction_id) {
2020-10-26 16:45:02 +08:00
// 检查construction是否已经是target
const constuction_key = `CONSTRUCTION_${construction_id}`;
if (
!_.find(Memory.WorkingTarget, (target) => target.id === construction_id)
) {
Memory.WorkingTarget[constuction_key] = {
id: construction_id,
working_creep_names: [],
cate: "constuction_site",
};
}
// 安排一个builder过去
const builder = _.filter(
Game.creeps,
(creep) => creep.memory.role === "builder" && !creep.working_target_id
2020-10-26 16:15:52 +08:00
);
2020-10-26 16:45:02 +08:00
if (builder.length > 0) {
const opt = {
memory: _.filter(
Memory.WorkingTarget,
(_memory) =>
_memory.working_creep_names.length === 0 &&
_memory.cate === "constuction_site"
),
creep_name_to_assgin_array: [builder[0].name],
};
assign_creeps(opt);
} else {
console.log(
`no enough builder to constuction_site ${construction_id}. Try to create a new one autmatically`
);
createBuilderCreep();
}
2020-10-23 20:55:20 +08:00
}
2020-10-26 22:03:25 +08:00
function assign_harvester_to_energy_source() {
2020-10-26 16:45:02 +08:00
const sources = Game.spawns.Spawn1.room.find(FIND_SOURCES_ACTIVE);
2020-10-26 22:03:25 +08:00
_.each(Object.keys(sources), function (source_key) {
const { id } = sources[source_key];
2020-10-26 16:45:02 +08:00
const key = `Energy_${id}`;
2020-10-26 22:03:25 +08:00
if (!_.find(Memory.WorkingTarget, (target) => target.id === id)) {
2020-10-26 16:45:02 +08:00
Memory.WorkingTarget[key] = {
id,
working_creep_names: [],
cate: "ENERGY_SOURCE",
};
}
});
// 向Memory.WorkingTarget里添加所有的Energy Source
// 寻找Energy Source的Memory
2020-10-26 22:03:25 +08:00
const energy_memory = _.filter(Memory.WorkingTarget, {
cate: "ENERGY_SOURCE",
});
2020-10-26 16:45:02 +08:00
// 寻找creep为0的energy source
const energy_source_need_creep_array = _.filter(
energy_memory,
(m) => m.working_creep_names.length === 0
2020-10-26 16:15:52 +08:00
);
2020-10-26 16:45:02 +08:00
if (energy_source_need_creep_array.length > 0) {
// 找到一个空闲的creep
const available_creep_array = _.filter(
Game.creeps,
(creep) =>
!creep.working_target_id && creep.memory.role === "harvester"
);
if (available_creep_array.length > 0) {
// 每次只安排一个
const opt = {
memory: energy_memory,
creep_name_to_assign_array: [available_creep_array[0].name],
};
assign_creeps(opt);
}
2020-10-26 16:15:52 +08:00
}
2020-10-23 20:55:20 +08:00
}
2020-10-20 17:09:06 +08:00
2020-10-23 20:55:20 +08:00
function assign_builder_to_controller() {
2020-10-26 16:45:02 +08:00
// 如果存在正在建造的construction且没有多余的builder就暂停upgrade controller
if (Game.spawns.Spawn1.room.find(FIND_MY_CONSTRUCTION_SITES).length > 0) {
const working_builder = _.filter(
Game.creeps,
(creep) =>
creep.memory.role === "builder" && !creep.working_target_id
);
if (working_builder.length === 0) {
// 没有可以用的builder了
const controller_id = Game.spawns.Spawn1.room.controller.id;
const controller_memory =
Memory.WorkingTarget[`RoomController_${controller_id}`];
if (controller_memory) {
_.each(controller_memory.working_creep_names, (creep_name) => {
Game.creeps[creep_name].working_target_id = 0;
});
memory.working_creep_names = [];
return;
}
}
}
// 判断room controller 是否有creep,没有则添加
if (
!_.find(
Memory.WorkingTarget,
(target) => target.id === Game.spawns.Spawn1.room.controller.id
)
) {
Memory.WorkingTarget[
`RoomController_${Game.spawns.Spawn1.room.controller.id}`
] = {
id: Game.spawns.Spawn1.room.controller.id,
working_creep_names: [],
cate: "ROOM_CONTROLLER",
};
2020-10-23 20:55:20 +08:00
}
2020-10-26 16:45:02 +08:00
const room_controller_mem = _.filter(Memory.WorkingTarget, {
cate: "ROOM_CONTROLLER",
});
// 寻找creep为0的room controller
const room_controller_need_creep_array = _.filter(
room_controller_mem,
(m) =>
m.working_creep_names.length === 0 && m.cate === "ROOM_CONTROLLER"
2020-10-26 16:15:52 +08:00
);
2020-10-26 16:45:02 +08:00
if (room_controller_need_creep_array.length > 0) {
const builder_creep = _.filter(
Game.creeps,
(creep) =>
!creep.working_target_id && creep.memory.role === "builder"
);
if (builder_creep.length > 0) {
const opt = {
memory: room_controller_mem,
creep_name_to_assign_array: [builder_creep[0].name],
};
assign_creeps(opt);
}
2020-10-23 20:55:20 +08:00
}
}
2020-10-20 17:09:06 +08:00
2020-10-18 22:00:22 +08:00
function createHarvestCreep() {
2020-10-26 16:45:02 +08:00
// create new creep
const new_creep_name = `AUTO_CREATE_Harvester_${util.uuid()}`;
const Re_code = Game.spawns.Spawn1.createCreep(
[MOVE, CARRY, WORK],
new_creep_name
);
if (Re_code === new_creep_name) {
Game.creeps[new_creep_name].memory.role = "harvester";
console.log(`Create new creep ${new_creep_name}`);
} else {
// console.log(`failed to create harvester with code ${Re_code}`);
}
2020-10-18 22:00:22 +08:00
}
function createTransferCreep() {
2020-10-26 16:45:02 +08:00
// create new creep
const new_creep_name = `AUTO_CREATE_Transfer_${util.uuid()}`;
const Re_code = Game.spawns.Spawn1.createCreep(
[MOVE, CARRY, CARRY],
new_creep_name
);
if (new_creep_name === Re_code) {
Game.creeps[new_creep_name].memory.role = "transfer";
console.log(`Create new creep ${new_creep_name}`);
} else {
// console.log(`failed to create transfer with code ${Re_code}`);
}
2020-10-18 22:00:22 +08:00
}
2020-10-23 20:55:20 +08:00
2020-10-26 22:03:25 +08:00
module.exports.loop = function () {
2020-10-26 16:45:02 +08:00
extra();
init.init();
mount.mount();
cleanCreeps();
cleanInvalidMemoryCreep();
cleanTargetMemory();
2020-10-26 22:03:25 +08:00
assign_harvester_to_energy_source();
2020-10-26 16:45:02 +08:00
assign_transfer_to_harvester();
assign_builder_to_controller();
assign_transfer_to_builder();
const construction_site_array = Game.spawns.Spawn1.room.find(
FIND_MY_CONSTRUCTION_SITES
);
_.each(construction_site_array, function (found_construction_site) {
const constuction_key = `CONSTRUCTION_${found_construction_site.id}`;
if (
Memory.WorkingTarget[constuction_key] &&
Memory.WorkingTarget[constuction_key].working_creep_names.length ===
0
) {
assign_builder_to_construction(found_construction_site.id);
}
});
let isSpawning = false;
const energy_source_number = _.filter(
Game.spawns.Spawn1.room.find(FIND_SOURCES_ACTIVE)
).length;
const harvester_number = _(Game.creeps)
.filter({ memory: { role: "harvester" } })
.size();
if (!Game.spawns.Spawn1.spawning) {
if (harvester_number < energy_source_number) {
isSpawning = true;
createHarvestCreep();
}
if (
_(Game.creeps)
.filter({ memory: { role: "transfer" } })
.size() < energy_source_number &&
!isSpawning
) {
isSpawning = true;
createTransferCreep();
}
const builder_number = _.filter(Game.creeps, {
memory: { role: "builder" },
}).length;
// 创造一个builder升级room controller
if (
Game.spawns.Spawn1.room.controller &&
builder_number < 1 + construction_site_array.length &&
!isSpawning
) {
isSpawning = true;
createBuilderCreep();
}
// 判断是否需要再增加1个transfer
const transfer_number = _.filter(Game.creeps, {
memory: { role: "transfer" },
}).length;
if (
builder_number + harvester_number > transfer_number &&
!isSpawning
) {
isSpawning = true;
createTransferCreep();
}
2020-10-26 16:15:52 +08:00
}
2020-10-26 16:45:02 +08:00
assign_task();
2020-10-26 16:15:52 +08:00
};