Пример #1
0
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
Пример #2
0
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
Пример #3
0
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
Пример #4
0
    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
Пример #5
0
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
Пример #6
0
    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
Пример #7
0
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
Пример #8
0
    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)
Пример #9
0
    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)
Пример #10
0
    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