def find_midpoint(pos, origin, target): # type: (RoomPosition, RoomPosition, RoomPosition) -> Optional[RoomPosition] # This method calculates the angle at each junction made by drawing lines from the origin and destination to # that junction. pi*2/5 is just under 90 degrees, and is our cutoff point for deciding to path through an # intersection. biggest_midpoint_angle = math.pi * 2 / 5 best_midpoint = None for junction in _find_nearest_junctions(pos): # a^2 = b^2 + c^2 - 2bc * cos(A) # cos(A) = (b^2 + c^2 - a^2) / (2bc) oj_distance_squared = distance_squared_room_pos(origin, junction) jt_distance_squared = distance_squared_room_pos(junction, target) ot_distance_squared = distance_squared_room_pos(origin, target) junction_angle = math.acos( (oj_distance_squared + jt_distance_squared - ot_distance_squared) / (2 * math.sqrt(oj_distance_squared) * math.sqrt(jt_distance_squared)) ) if junction_angle > biggest_midpoint_angle: biggest_midpoint_angle = junction_angle best_midpoint = junction # if best_midpoint is not None: # self.log("WARNING: Found midpoint {} for path from {} to {}".format( # best_midpoint, origin, target # )) return best_midpoint
def find_new_target_extension(targets, creep): # type: (TargetMind, RoleBase) -> Optional[str] closest_distance = Infinity best_id = None stealing_from = None structures = cast( List[Union[StructureExtension, StructureSpawn]], _.filter( creep.home.find(FIND_MY_STRUCTURES), lambda s: ((s.structureType == STRUCTURE_EXTENSION or s.structureType == STRUCTURE_SPAWN) and s.energy < s.energyCapacity))) if len(structures): for structure in structures: structure_id = structure.id if volatile_cache.mem("extensions_filled").has(structure_id): continue current_carry = targets.workforce_of(target_spawn_deposit, structure_id) distance = movement.distance_squared_room_pos( structure.pos, creep.creep.pos) if distance < closest_distance: max_to_deposit = structure.energyCapacity / 50.0 if not current_carry or current_carry < max_to_deposit: closest_distance = distance best_id = structure_id stealing_from = None else: targeting = targets.reverse_targets[target_spawn_deposit][ structure_id] if len(targeting): for name in targeting: if not Game.creeps[ name] or movement.distance_squared_room_pos( Game.creeps[name].pos, structure.pos) > distance * 2.25: # If we're at least 1.5x closer than them, let's steal their place. # Note that 1.5^2 is 2.25, which is what we should be using since we're comparing # squared distances. d1 > d2 * 1.5 is equivalent to d1^2 > d2^2 * 1.5^2 which is # equivalent to d1^2 > d2^2 * 2.25 closest_distance = distance best_id = structure_id stealing_from = name break else: closest_distance = distance best_id = structure_id stealing_from = None if stealing_from is not None: targets.unregister_name(stealing_from, target_spawn_deposit) elif creep.home.full_storage_use: flag_list = flags.find_flags(creep.home, SPAWN_FILL_WAIT) if len(flag_list): best_id = _(flag_list).map(lambda f: "flag-{}".format(f.name)) \ .min(lambda fid: targets.reverse_targets[target_spawn_deposit][fid] or 0) if best_id is Infinity: best_id = None return best_id
def find_new_target_owned_typed_flag(targets, creep, args): # type: (TargetMind, RoleBase, Union[Tuple[int, Union[RoomPosition, RoomObject, None]], None, int]) -> Optional[str] pos = creep.pos if _.isNumber(args): flag_type = cast(int, args) elif args != undefined: flag_type, center_pos = cast( Tuple[int, Union[RoomPosition, RoomObject, None]], args) pos = cast(RoomObject, center_pos).pos or cast(RoomPosition, center_pos) else: raise ValueError( "_find_closest_home_flag called for creep {} without second parameter!" .format(creep)) closest_flag = None closest_distance = Infinity for flag in flags.find_flags(creep.home, flag_type): flag_id = "flag-{}".format(flag.name) current = targets.targets[target_home_flag][flag_id] if not current or current < 1: distance = movement.distance_squared_room_pos(pos, flag.pos) if distance < closest_distance: closest_distance = distance closest_flag = flag_id return closest_flag
def get_colony(self): if not self.memory.colonizing: closest_distance = Infinity closest_room_name = None for room in self.home.subsidiaries: if not len(room.spawns) and _.sum(room.role_counts) < 3: distance = movement.distance_squared_room_pos( self.pos, movement.center_pos(room.name)) if distance < closest_distance: closest_room_name = room.name if not closest_room_name: for room in self.home.subsidiaries: if not len(room.spawns): distance = movement.distance_squared_room_pos( self.pos, movement.center_pos(room.name)) if distance < closest_distance: closest_room_name = room.name # Colonize! self.memory.colonizing = closest_room_name return self.memory.colonizing
def find_new_energy_miner_target_mine(targets, creep): # type: (TargetMind, RoleBase) -> Optional[str] best_id = None closest_flag = Infinity for flag in creep.home.mining.available_mines: flag_id = "flag-{}".format(flag.name) miners = targets.targets[target_energy_miner_mine][flag_id] if not miners or miners < 1: distance = movement.distance_squared_room_pos( flag.pos, creep.creep.pos) if distance < closest_flag: closest_flag = distance best_id = flag_id return best_id
def get_colony(self): if not self.memory.colonizing: closest_distance = Infinity closest_room_name = None for room in self.hive.my_rooms: if room.room.storage and room.room.storage.storeCapacity <= 0 \ and _.sum(room.room.storage.store) > room.room.storage.store[RESOURCE_ENERGY]: distance = movement.distance_squared_room_pos( self.pos, movement.center_pos(room.name)) if distance < closest_distance: closest_room_name = room.name if not closest_room_name: return None # Colonize! self.memory.colonizing = closest_room_name return self.memory.colonizing
def find_new_target_reserve_now_room(targets, creep): # type: (TargetMind, RoleBase) -> Optional[str] closest_flag = None closest_distance = Infinity for flag in flags.find_flags_global(RESERVE_NOW): room_name = flag.pos.roomName room = Game.rooms[room_name] if not room or (room.controller and not room.controller.my and not room.controller.owner): # claimable! flag_id = "flag-{}".format(flag.name) current_targets = targets.targets[target_reserve_now][flag_id] if not current_targets or current_targets < 1: distance = movement.distance_squared_room_pos( creep.pos, __new__(RoomPosition(25, 25, room_name))) if distance < closest_distance: closest_distance = distance closest_flag = flag_id return closest_flag
def run(self): if self.creep.ticksToLive < recycle_time: self.memory.role = role_recycling self.memory.last_role = role_cleanup return False storage = self.creep.room.storage if self.memory.filling and self.carry_sum( ) >= self.creep.carryCapacity: self.memory.filling = False if not self.memory.filling and self.carry_sum() <= 0: self.memory.filling = True if self.memory.filling: # TODO: Make some cached memory map of all hostile creeps, and use it to avoid. resources = cast(List[Resource], self.room.find(FIND_DROPPED_RESOURCES)) if len(resources): closest = None closest_distance = Infinity for resource in resources: if len( self.room.find_in_range(FIND_HOSTILE_CREEPS, 3, resource.pos)) == 0: if len( self.room.find_in_range( FIND_SOURCES, 1, resource.pos)) == 0: if self.memory.last_energy_target: compressed_pos = resource.pos.x | ( resource.pos.y << 6) if compressed_pos == self.memory.last_energy_target: closest = resource break # we've confirmed now that this is a valid target! congrats. distance = movement.distance_squared_room_pos( self.pos, resource.pos) if distance < closest_distance: closest = resource closest_distance = distance pile = closest else: pile = None if not pile: del self.memory.last_energy_target self.go_to_depot() # wait return self.memory.last_energy_target = pile.pos.x | (pile.pos.y << 6) if not self.pos.isNearTo(pile): self.move_to(pile) return False result = self.creep.pickup(pile) if result == ERR_FULL: self.memory.filling = False return True elif result != OK: self.log("Unknown result from cleanup-creep.pickup({}): {}", pile, result) else: if not storage: # self.log("Cleanup can't find storage in {}!", self.creep.room.name) # self.go_to_depot() # return False return SpawnFill.run(self) if self.pos.roomName != storage.pos.roomName: self.move_to(storage) return False if self.carry_sum() > self.creep.carry[RESOURCE_ENERGY]: target = storage else: target = self.targets.get_new_target( self, target_closest_energy_site) if not target: target = storage # if target.energy >= target.energyCapacity: # target = storage if target.structureType == STRUCTURE_LINK: assert isinstance(target, StructureLink) self.home.links.register_target_deposit( target, self, self.creep.carry[RESOURCE_ENERGY], self.pos.getRangeTo(target)) if not self.pos.isNearTo(target): if self.pos.isNearTo(storage): # being blocked by a link manager to get to the link target = storage else: self.move_to(target) return False resource_type = _.find(Object.keys(self.creep.carry), lambda r: self.creep.carry[r] > 0) result = self.creep.transfer(target, resource_type) if result == ERR_NOT_ENOUGH_RESOURCES: self.memory.filling = True return True elif result == ERR_FULL: if target == storage: self.log("Storage in room {} full!", storage.room.name) elif result != OK: self.log( "Unknown result from cleanup-creep.transfer({}, {}): {}", target, resource_type, result)
def run(self): target = cast( Flag, self.targets.get_new_target(self, target_single_flag, REAP_POWER_BANK)) if not target: if len(flags.find_flags( self.home, RAID_OVER)) or self.creep.ticksToLive < 100: self.recycle_me() else: self.log("PowerAttack has no target!") self.go_to_depot() return if self.memory.filling and self.carry_sum( ) >= self.creep.carryCapacity: self.memory.filling = False if not self.memory.filling and self.carry_sum() <= 0: self.memory.filling = True storage = self.home.room.storage if self.memory.filling: if self.pos.roomName != target.pos.roomName: self.follow_military_path(self.home.spawn.pos, target.pos) return # TODO: Make some cached memory map of all hostile creeps, and use it to avoid. resources = cast(List[Resource], self.room.find(FIND_DROPPED_RESOURCES)) if len(resources): closest = None closest_distance = Infinity for resource in resources: if len( self.room.find_in_range(FIND_HOSTILE_CREEPS, 3, resource.pos)) == 0: if self.memory.last_energy_target: compressed_pos = resource.pos.x | ( resource.pos.y << 6) if compressed_pos == self.memory.last_energy_target: closest = resource break if (resource.amount > 50 or len( self.room.find_in_range( FIND_SOURCES, 1, resource.pos)) == 0): # we've confirmed now that this is a valid target! congrats. distance = movement.distance_squared_room_pos( self.pos, resource.pos) if distance < closest_distance: closest = resource closest_distance = distance pile = closest else: pile = None if not pile: del self.memory.last_energy_target if not _.find(self.room.find(FIND_STRUCTURES), {"structureType": STRUCTURE_POWER_BANK}): if self.carry_sum() >= 0: self.memory.filling = False else: target.remove() else: if self.pos.inRangeTo(target, 7): self.move_around(target) else: self.move_to(target) return self.memory.last_energy_target = pile.pos.x | (pile.pos.y << 6) if not self.pos.isNearTo(pile): self.move_to(pile) return False result = self.creep.pickup(pile) if result == OK: pass elif result == ERR_FULL: self.memory.filling = False return True else: self.log("Unknown result from cleanup-creep.pickup({}): {}", pile, result) else: if not storage: self.go_to_depot() return if self.pos.roomName != storage.pos.roomName: self.follow_military_path(target.pos, storage.pos) return False target = storage if not self.pos.isNearTo(target): self.move_to(target) return False resource_type = _.find(Object.keys(self.creep.carry), lambda r: self.creep.carry[r] > 0) result = self.creep.transfer(target, resource_type) if result == OK: pass elif result == ERR_NOT_ENOUGH_RESOURCES: self.memory.filling = True return True elif result == ERR_FULL: if target == storage: self.log("Storage in room {} full!", storage.room.name) else: self.log( "Unknown result from cleanup-creep.transfer({}, {}): {}", target, resource_type, result)
def run(self): if self.creep.ticksToLive < recycle_time: self.memory.role = role_recycling self.memory.last_role = role_sacrificial_cleanup return False if self.memory.filling and self.carry_sum( ) >= self.creep.carryCapacity: self.memory.filling = False elif not self.memory.filling and self.carry_sum() <= 0: self.memory.filling = True if self.memory.filling: target = None if self.memory.target: target = cast( Optional[Resource], self.room.look_at( LOOK_RESOURCES, positions.deserialize_xy_to_pos( self.memory.target, self.room.name))[0]) if not target: resources = self.room.find(FIND_DROPPED_RESOURCES) closest_distance = Infinity for resource in resources: if len( self.room.find_in_range(FIND_HOSTILE_CREEPS, 3, resource.pos)) == 0: if len( self.room.find_in_range( FIND_SOURCES, 1, resource.pos)) == 0: # we've confirmed now that this is a valid target! congrats. distance = movement.distance_squared_room_pos( self.pos, resource.pos) if distance < closest_distance: target = resource closest_distance = distance self.memory.target = positions.serialize_pos_xy(target.pos) if not target: self.log("sacrificial cleanup found no energy, recycling.") self.memory.role = role_recycling self.memory.last_role = role_sacrificial_cleanup return if self.pos.isNearTo(target): result = self.creep.pickup(target) if result == ERR_FULL: self.memory.filling = False return True elif result != OK: self.log( "Unknown result from cleanup-creep.pickup({}): {}", target, result) else: self.move_to(target) return False else: target = self.creep.room.storage if not target: return self.refill_creeps() if self.pos.roomName != target.pos.roomName: self.move_to(target) return False if self.pos.isNearTo(target): resource = _.findKey(self.creep.carry) result = self.creep.transfer(target, resource) if result == ERR_NOT_ENOUGH_RESOURCES: self.memory.filling = True return True elif result == ERR_FULL: self.log("Storage in room {} full!", target.room.name) elif result != OK: self.log( "Unknown result from cleanup-creep.transfer({}, {}): {}", target, resource, result) else: self.move_to(target) return False